Skip to content

Conversation

@tbkka
Copy link

@tbkka tbkka commented Nov 15, 2025

yielding borrow and yielding mutate are the final approved names for the accessors previously known as read and modify (which are themselves improvements over the earlier non-standard _read and _modify accessors).

Since some people are already using these under the read and modify names, we want to support the old and new names as synonyms for a transition period until everyone has had a chance to migrate.

`yielding borrow` and `yielding mutate` are the final approved
names for the accessors previously known as `read` and `modify`
(which are themselves improvements over the earlier non-standard
`_read` and `_modify` accessors).

Since some people are already using these under the `read` and
`modify` names, we want to support the old and new names as synonyms
for a transition period until everyone has had a chance to migrate.
@tbkka
Copy link
Author

tbkka commented Nov 15, 2025

This isn't working out so well. There seem to be two basic problems:

  • Treating yielding borrow as a synonym for read
  • Having yielding borrow be a "keyword" that's really two words

@tbkka
Copy link
Author

tbkka commented Nov 17, 2025

It's not clear from SE-0474 whether yielding mutating borrow should be accepted, or only mutating yielding borrow. @DougGregor @rjmccall -- Any insights here?

If the former is accepted, then it might make sense to model yielding as a modifier here; otherwise, I'll need to do something more complicated.

@tbkka
Copy link
Author

tbkka commented Nov 17, 2025

Can anyone suggest how this should work? @bnbarham @rintaro @hamishknight ?? I'm completely stumped. What I have here seems entirely wrong, but I have no idea what approach should be used here. In particular:

  • Mapping yielding borrow to read breaks round-tripping, so it seems like I somehow need to model yielding borrow as a distinct construct from read
  • It seems like yielding borrow must be modeled as two Nodes? Otherwise, trivia between those tokens can't be modeled?
  • yielding can't be a "modifier" without other changes, since mutating yielding borrow is legal, and that would have two modifiers, which isn't supported in the current accessor modeling. So either accessors need to support a set of modifiers? Or something different?


let (unexpectedBeforeIntroducer, introducer) = self.expect(kind.spec)

// Map `yielding borrow` => `read`, etc.
Copy link
Author

@tbkka tbkka Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks round-tripping, so I can't do this mapping here.

@tbkka
Copy link
Author

tbkka commented Nov 17, 2025

Maybe I could expand AccessorIntroducer with a new yielding field like this?

  struct AccessorIntroducer {
    var attributes: RawAttributeListSyntax
    var modifier: RawDeclModifierSyntax?
    var yielding: RawAccessorYieldingSyntax?
    var kind: AccessorDeclSyntax.AccessorSpecifierOptions
    var unexpectedBeforeToken: RawUnexpectedNodesSyntax?
    var token: RawTokenSyntax
  }

and then I'd have to reverse-engineer the code generator to construct RawAccessorYieldingSyntax and update everywhere an AccessorIntroducer was used to properly handle the new field? Does that make any sense?

@tbkka
Copy link
Author

tbkka commented Nov 17, 2025

It would be so helpful if the generated code included comments indicating where the data came from for each particular generated type and/or file.

@tbkka tbkka marked this pull request as draft November 18, 2025 00:29
@bnbarham
Copy link
Contributor

bnbarham commented Nov 18, 2025

It's not clear from SE-0474 whether yielding mutating borrow should be accepted, or only mutating yielding borrow. @DougGregor @rjmccall -- Any insights here?

I haven't been following the proposal closely, but from a quick read, it has eg.

Like a set accessor, a yielding mutate accessor in a struct or enum property is mutating by default (unless explicitly declared a nonmutating yielding mutate)

Confusing set of terms IMO (nonmutating mutate?), but set accessors allow specifying mutating (despite being redundant), so seems reasonable to allow here.

yielding can't be a "modifier" without other changes, since mutating yielding borrow is legal, and that would have two modifiers, which isn't supported in the current accessor modeling. So either accessors need to support a set of modifiers? Or something different?

Given the proposal mentions the possibility of a non-yielding borrow/mutate, seems that yielding is most like a modifier. So yes, I'd go with:

So either accessors need to support a set of modifiers?

The next question is whether there should be an order to these, ie. is yielding nonmutating mutate allowed?

var look = self.lookahead()
let _ = look.consumeAttributeList()
let hasModifier = look.consume(ifAnyIn: AccessorModifier.self) != nil
let hasYielding = look.consume(if: TokenSpec(.yielding)) != nil
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes to Declarations.swift seem to make sense to me. This should verify the basic syntax.

struct AccessorIntroducer {
var attributes: RawAttributeListSyntax
var modifier: RawDeclModifierSyntax?
var yielding: RawAccessorYieldingModifierSyntax?
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to either add a new field here or change modifier to an array. No idea which is more appropriate.

@tbkka
Copy link
Author

tbkka commented Nov 18, 2025

What does this mean?

Build of product 'generate-swift-syntax' complete! (0.08s)
SyntaxSupport/Child.swift:370: Fatal error: unexpected node has no siblings?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants