Skip to content

Commit f92b033

Browse files
committed
Change the disambiguation rule for function literals inside guards.
We now unconditionally prohibit function literals inside guards, regardless of whether their bodies take the form `=> expression` or a block. This matches what was implemented in the parser. See discussion in dart-lang/sdk#51482.
1 parent 0e320bd commit f92b033

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

accepted/future-releases/0546-patterns/feature-specification.md

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,34 +1345,40 @@ var x = switch (obj) {
13451345

13461346
A similar ambiguity exists with function expressions in initializer lists, if
13471347
the constructor happens to be a factory constructor with `=>` for its body. We
1348-
resolve the ambiguity similarly here: When `=>` is encountered after `when` in
1349-
a guard, if the code between forms a valid expression, then it is interpreted as
1350-
such and the `=>` is treated as the separator between the guard and case body.
1351-
*In the above example, we take the first interpretation.*
1352-
1353-
This rules applies in all contexts where a guard can appear: switch statements,
1354-
switch expressions, if-case statements, and if-case elements. *We could restrict
1355-
this rule to guards only in switch expressions where the ambiguity arises, but
1356-
that leads to a syntactic restriction that is context-sensitive and harder to
1357-
learn. Since the rule is unusual enough as it is, we apply it as consistently as
1358-
possible. Note that the related restriction on `=>` in constructor initializers
1359-
applies even though generative constructors can't use `=>` for their body.*
1360-
1361-
The rule is applied unconditionally even if the code after `=>` is not a valid
1362-
body expression, as in:
1348+
resolve the ambiguity similarly here: Inside the `expression` part of a
1349+
`guardedPattern`, a function literal is not allowed, unless it is enclosed in
1350+
grouping operators (parentheses, square brackets, or curly braces). *Therefore,
1351+
if `=>` is encountered after `when` in a guard, the `=>` is treated as the
1352+
separator between the guard and case body. In the above example, we take the
1353+
first interpretation.*
1354+
1355+
This rule applies in all contexts where a guard can appear: switch statements,
1356+
switch expressions, if-case statements, and if-case elements. It also applies
1357+
to all function expressions, whether their body is `=>` followed by an
1358+
expression, a block delimited by curly braces. *We could restrict this rule to
1359+
guards only in switch expressions where the ambiguity arises, and to function
1360+
literals using `=>`. But that leads to a syntactic restriction that is
1361+
context-sensitive and harder to learn. Since the rule is unusual enough as it
1362+
is, we apply it as consistently as possible. Note that the related restriction
1363+
on constructor initializers applies regardless of whether the function literal
1364+
uses `=>` or a block, even though generative constructors can't use `=>` for
1365+
their body.*
1366+
1367+
*The rule is applied unconditionally even if the code after `=>` is not a valid
1368+
body expression, as in:*
13631369

13641370
```dart
13651371
var x = switch (obj) {
13661372
_ when (a) => b => c
13671373
};
13681374
```
13691375

1370-
Here, we treat the guard expression as `(a)`, which leads the body to be `b =>
1371-
c` which isn't a valid expression and produces a compile-time error.
1376+
*Here, we treat the guard expression as `(a)`, which leads the body to be `b =>
1377+
c` which isn't a valid expression and produces a compile-time error.*
13721378

1373-
If you want a guard expression that ends in a function expression (which is
1379+
*If you want a guard expression that ends in a function expression (which is
13741380
quite unlikely), you can avoid the `=>` being captured as the case separator by
1375-
parenthesizing the function:
1381+
parenthesizing the function:*
13761382

13771383
```dart
13781384
var x = switch (obj) {

0 commit comments

Comments
 (0)