-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correct grammar of in-out expressions #194
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: Sarah Canto <61300898+sarahnicoleboo@users.noreply.github.com>
The current grammar dates back to commit b0bc885 for Swift 1. The original RST langref grammar doesn't have specific discussion of in-out expressions; the older HTML langref says:
Neither of the langref formal grammars include a production for in-out-expression. |
This grammar avoids productions like &x+y -- even though x+y is a valid expression, you can't use it this way in an in-out expression. However, it does still overproduce -- for example, a.b() is a valid postfix expression but &a.b() isn't a valid in-out expression. Co-authored-by: Joe Groff <jgroff@apple.com>
Interesting! I am not a Swift grammar expert, but to my naive, innocent eyes this does look like a better match with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change looks correct to me.
Moving up one level in the grammar introduces additional overgeneration, but otherwise code like f(&(x)) doesn't match.
@ahoppen Thanks for taking a look. Reading it again this morning, I see that 'postfix-expression' doesn't include parenthesized-expression, but you can use parentheses in an in-out expression. One option is to define 'in-out-expression' as follows:
This overproduces even more — allowing literals, closures, and conditional expressions inside the in-out expression where the aren't actually allowed. Elsewhere in the reference, we often handle places where the grammar overproduces by explaining the limitations in prose. Do we have a list of what we specifically do support after the Trying code out in the REPL, we allow parentheses for grouping, dot for member lookup, square brackets for array subscripts. An alternate approach that might be feasible here, if the list of allowed in-out things is small, is to build them up in the in-out-expression grammar specifically by repeating/re-using bits of other grammar rules:
It doesn't look like we support tuple expressions — but the error I get suggests maybe we do and I need to spell something more explicitly:
|
There isn't a clear point in the expression grammar where everything produced by that rule is allowed in an in-out expression, but nothing else, so we will always either over- or under-produce if we write in-out-expression in terms of existing productions. Combined rules from the parts of the grammar that are definitely supported to make these production rules, although this list might be incomplete: - The grammar for . is borrowed from explicit-member-expression - The grammar for [] is borrowed from subscript-expression - The grammar for () is adapted from parenthesized-expression
The Swift parser itself allows any expression after Any enforcement that you can’t pass a literal after the ampersand is semantic. For example the diagnostic of passing an integer literal is the same as when passing a func foo(_ x: inout Int) {}
foo(&1) // error: Cannot pass immutable value as inout argument: literals are not mutable
let myInt = 1
foo(&myInt) // error: Cannot pass immutable value as inout argument: 'myInt' is a 'let' constant I’m not entirely sure what’s used to represent CC @rintaro In case you have opinions / thoughts as well. |
This is not enough. At least it's missing
And somewhat surprisingly, the following code also works struct S {
static var shared: Self = S()
}
func foo(_ x: inout S) {}
foo(&.shared) As @ahoppen mentioned, the parser parses any
NOTE: not |
On second thought,
This is similar to keypath expression. Parser parses any postfix components, but in the current grammar, |
Thanks, @rintaro. TSPL doesn't generally distinguish between parsing, lexing, semantic analysis, etc. — so its formal grammar doesn't specifically try to include content that parses but is semantically invalid. If there's something that isn't valid Swift code, we try to exclude it from the grammar, regardless of which stage of compilation rejects it. Defining 'in-out-expression' in terms of 'prefix-expression' as in your comment doesn't entirely work, because grouping parentheses appear in the grammar in the production for 'primary-expression', but they're valid after the
If the third option produces a reasonable grammar, that's my initial preference. That said, it might not be practical — adding implicit member expressions and self expressions might make the list of productions here unwieldy. For the second option, I'd add a paragraph before the "for more information" line like the following:
|
The previous grammar didn't include `self` or `.self` or implicit member expressions, as Rintaro Ishizaki <rishizaki@apple.com> noted on the PR. Duplicating those productions here, with modifications to prevent them from pulling in all of primary-expression or postfix-expression, would make this grammar a bit too long and unwieldy.
Hi everyone. I've read through this thread along with the partial fix that was merged. I think that @rintaro proposed the fix that I believe is the most correct with With that being said, I also see the concern of consistency when looking at how keypath-expression is handled. I'm not sure it's my place to be chiming in on that decision since it's really a design decision. Thanks for the consideration. |
The grammar for postfix-expression produces this case, and includes primary-expression. This grammar also allows for production of parentheses because primary-expression produces parenthesized-expression. Co-authored-by: Sarah Canto <61300898+sarahnicoleboo@users.noreply.github.com>
Kept this branch's changes to the grammar.
Fixes: #193