-
Notifications
You must be signed in to change notification settings - Fork 201
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
Parsing ambiguity in switch expressions: =>
might be part of guard expression
#2672
Comments
I remember when that first dark corner of the language was first discovered while @eernstg, is it hiding in there somewhere? I agree with your proposed resolution. I'll try to come up with a nice way to word it. |
@munificent wrote, about the treatment of
Not in the language specification. I noticed this glaring ambiguity in the grammar when I created the spec parser, and Dart.g does actually handle This discrepancy between the language specification grammar and the spec grammar does not cause any known parsing failures. In particular, a At the same time, we don't have to worry about whether @jensjoha did do some work on an update to the parser following this approach, but it was never sufficiently near the top of the agenda to make it into the specification, or to get landed in the implementation. I'd love to get it done, of course. If we assume this modified grammar then we could change the |
Another issue in initializer lists is not class C {
Object x;
C() : x = (y) {
...............
};
} This looks like a The only difference between the two is the trailing (Even worse as That's reason enough, to me, to not allow function literals as the expression of an initializer list element. It's too unreadable in a position where any expression can be immediately followed by a block. I'd be happy requiring functions literals occurring un-delimited in |
In https://dart-review.googlesource.com/c/sdk/+/273020 I'm using the parser's @lrhn's comment above:
doesn't mention switch expressions specifically. Should I extend the restriction to all |
It's true that it's only really expression-switch I'd be fine with just restricting it there. I'd probably be fine with restricting it in every |
…sing. We need to prohibit function expressions during guard clauses in switch expressions, otherwise the `=>` might be misinterpreted. Fixes #50591. Bug: #50591, dart-lang/language#2672 Change-Id: Ie5703ac7049557798b19778281429e8a591cf09f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/273020 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
I went with the latter. It felt simpler to me to just employ the rule consistently across all guards. I'm not sure if I can fully motivate that choice, but one meta-rule I use sometimes is "How long would the error message to explain this have to be?" and "guards can't end in function expressions" is marginally shorter than "guards in switch expressions can't end in function expressions". |
The following code is ambiguous:
It could either mean:
Or:
(Either of which would successfully type check because
y
has typedynamic
.)More generally, in the parser we have the rule that when an expression is expected, if
(...) =>
is found, the parser assumes it's looking at a function expression and greedily consumes the=>
. Which means that we currently can't parse this, even though technically it's unambiguous:Because the parser interprets it as:
(Which is missing the
=> expression
part of theswitchExpressionCase
.)There's one exception: if
(...) =>
appears in a constructor initializer, and it's not inside any grouping constructs, then the parser assumes it's looking at a parenthesized expression or a record, so it doesn't consume the=>
. This means that the=>
winds up getting interpreted as the beginning of the constructor body (which is kind of weird because non-factory constructor bodies aren't allowed to use=>
syntax, but who am I to judge?)I propose that we address this ambiguity in a similar fashion: if
(...) =>
appears in a guard expression inside a switch expression, and it's not inside any grouping constructs, then let's specify that the construct should be interpreted as a parenthesized expression or a record, thus allowing the=>
to be interpreted as terminating theguardedPattern
. Which means thatwill be interpreted as:
And
will be interpreted as
However, this will be rejected:
Because the parser will interpret it as:
(Which is illegal because
z => z
isn't a valid expression.)The text was updated successfully, but these errors were encountered: