@@ -188,7 +188,8 @@ Before introducing each pattern in detail, here is a summary with some examples:
188
188
| [ Null-check] [ nullCheckPattern ] | ` subpattern? ` |
189
189
| [ Null-assert] [ nullAssertPattern ] | ` subpattern! ` |
190
190
| [ Constant] [ constantPattern ] | ` 123 ` , ` null ` , ` 'string' ` <br >` math.pi ` , ` SomeClass.constant ` <br >` const Thing(1, 2) ` , ` const (1 + 2) ` |
191
- | [ Variable] [ variablePattern ] | ` foo ` , ` var bar ` , ` String str ` , ` _ ` , ` int _ ` |
191
+ | [ Variable] [ variablePattern ] | ` var bar ` , ` String str ` , ` final int _ ` |
192
+ | [ Identifier] [ identifierPattern ] | ` foo ` , ` _ ` |
192
193
| [ Parenthesized] [ parenthesizedPattern ] | ` (subpattern) ` |
193
194
| [ List] [ listPattern ] | ` [subpattern1, subpattern2] ` |
194
195
| [ Map] [ mapPattern ] | ` {"key": subpattern1, someConst: subpattern2} ` |
@@ -203,6 +204,7 @@ Before introducing each pattern in detail, here is a summary with some examples:
203
204
[ nullAssertPattern ] : #null-assert-pattern
204
205
[ constantPattern ] : #constant-pattern
205
206
[ variablePattern ] : #variable-pattern
207
+ [ identifierPattern ] : #identifier-pattern
206
208
[ parenthesizedPattern ] : #parenthesized-pattern
207
209
[ listPattern ] : #list-pattern
208
210
[ mapPattern ] : #map-pattern
@@ -226,6 +228,7 @@ unaryPattern ::= castPattern
226
228
227
229
primaryPattern ::= constantPattern
228
230
| variablePattern
231
+ | identifierPattern
229
232
| parenthesizedPattern
230
233
| listPattern
231
234
| mapPattern
@@ -436,7 +439,6 @@ constantPattern ::= booleanLiteral
436
439
| '-'? numericLiteral
437
440
| stringLiteral
438
441
| symbolLiteral
439
- | identifier
440
442
| qualifiedName
441
443
| constObjectExpression
442
444
| 'const' typeArguments? '[' elements? ']'
@@ -455,14 +457,10 @@ supporting terse forms of the most common constant expressions like so:
455
457
literal ` 2 ` with a unary ` - ` applied to it (which is how the language
456
458
views it).
457
459
458
- * Named constants are also allowed because they aren't ambiguous. That
459
- includes simple identifiers like ` someConstant ` , prefixed constants like
460
- ` some_library.aConstant ` , static constants on classes like
461
- ` SomeClass.aConstant ` , and prefixed static constants like
462
- ` some_library.SomeClass.aConstant ` . * Simple identifiers would be ambiguous
463
- with variable patterns that aren't marked with ` var ` , ` final ` , or a type,
464
- but unmarked variable patterns are only allowed in irrefutable contexts
465
- where constant patterns are prohibited.*
460
+ * Qualified named constants are also allowed because they aren't ambiguous.
461
+ That includes prefixed constants like ` some_library.aConstant ` , static
462
+ constants on classes like ` SomeClass.aConstant ` , and prefixed static
463
+ constants like ` some_library.SomeClass.aConstant ` .
466
464
467
465
* List literals are ambiguous with list patterns, so we only allow list
468
466
literals explicitly marked ` const ` . Likewise with set and map literals
@@ -487,7 +485,7 @@ expression.
487
485
### Variable pattern
488
486
489
487
```
490
- variablePattern ::= ( 'var' | 'final' | 'final'? type )? identifier
488
+ variablePattern ::= ( 'var' | 'final' | 'final'? type ) identifier
491
489
```
492
490
493
491
A variable pattern binds the matched value to a new variable. These usually
@@ -502,8 +500,8 @@ Here, `a` and `b` are variable patterns and end up bound to `1` and `2`,
502
500
respectively.
503
501
504
502
The pattern may have a type annotation in order to only match values of the
505
- specified type. If the type annotation is omitted, the variable's type is
506
- inferred and the pattern matches all values.
503
+ specified type. Otherwise, it is declared using ` var ` or ` final ` and the
504
+ variable's type is inferred such that it matches all values.
507
505
508
506
``` dart
509
507
switch (record) {
@@ -517,17 +515,9 @@ They are specified later in the "Pattern context" section.*
517
515
518
516
#### Wildcards
519
517
520
- If the variable's name is ` _ ` , it doesn't bind any variable. This "wildcard"
521
- name is useful as a placeholder in places where you need a subpattern in order
522
- to destructure later positional values:
523
-
524
- ``` dart
525
- var list = [1, 2, 3];
526
- var [_, two, _] = list;
527
- ```
528
-
529
- The ` _ ` identifier can also be used with a type annotation when you want to test
530
- a value's type but not bind the value to a name:
518
+ If the variable's name is ` _ ` , it doesn't bind any variable. A "wildcard" name
519
+ with a type annotation is useful when you want to test a value's type but not
520
+ bind the value to a name:
531
521
532
522
``` dart
533
523
switch (record) {
@@ -536,6 +526,32 @@ switch (record) {
536
526
}
537
527
```
538
528
529
+ ### Identifier pattern
530
+
531
+ ```
532
+ identifierPattern ::= identifier
533
+ ```
534
+
535
+ A bare identifier in a pattern is semantically ambiguous. A user might expect it
536
+ to match if the value is equal to a constant with that name (as it currently
537
+ does in switches). Or the user could expect it to bind or assign to a variable
538
+ with that name.
539
+
540
+ The answer is it's both. Depending on the context where it appears, a bare
541
+ identifier pattern may behave like a constant pattern or like a variable
542
+ pattern. The section on pattern context below lays out the precise rules.
543
+
544
+ #### Wildcards
545
+
546
+ As with variable patterns, an identifier pattern named ` _ ` is a wildcard that
547
+ doesn't bind or assign to any variable. It's useful as a placeholder in places
548
+ where you need a subpattern in order to destructure later positional values:
549
+
550
+ ``` dart
551
+ var list = [1, 2, 3];
552
+ var [_, two, _] = list;
553
+ ```
554
+
539
555
### Parenthesized pattern
540
556
541
557
```
@@ -782,8 +798,8 @@ In both record patterns and object patterns, a field subpattern's name may be
782
798
elided when it can be inferred from the field's value subpattern. The inferred
783
799
field name for a pattern `p`, if one exists, is defined as:
784
800
785
- * If `p` is a variable pattern which binds a variable `v`, and `v` is not `_`,
786
- then the inferred name is `v`.
801
+ * If `p` is a variable or identifier pattern with identifier `v`, and `v` is
802
+ not `_`, then the inferred name is `v`.
787
803
788
804
* If `p` is `q?` then the inferred name of `p` (if any) is the inferred name
789
805
of `q`.
@@ -912,15 +928,15 @@ patternAssignment ::= outerPattern '=' expression
912
928
assignments, but does not allow patterns to the left of a compound assignment
913
929
operator.*
914
930
915
- In a pattern assignment, all variable patterns are interpreted as referring to
931
+ In a pattern assignment, all identifier patterns are interpreted as referring to
916
932
existing variables. You can't declare any new variables. * Disallowing new
917
933
variables allows pattern assignment expressions to appear anywhere expressions
918
934
are allowed while avoiding confusion about the scope of new variables.*
919
935
920
936
It is a compile-time error if:
921
937
922
- * An identifier in a variable pattern does not resolve to an assignable local
923
- variable or formal parameter. A variable is assignable if it is any of:
938
+ * An identifier pattern does not resolve to an assignable local variable or
939
+ formal parameter. A variable is assignable if it is any of:
924
940
925
941
* Non-final
926
942
* Final and definitely unassigned
@@ -952,12 +968,12 @@ It is a compile-time error if:
952
968
to local variables, which are also the only kind of variables that can be
953
969
declared by patterns.*
954
970
955
- * The matched value type for a variable pattern is not assignable to the
971
+ * The matched value type for an identifier pattern is not assignable to the
956
972
corresponding variable's type.
957
973
958
974
* The same variable is assigned more than once. *In other words, a pattern
959
- assignment can't have multiple variable subpatterns with the same name. This
960
- prohibits code like:*
975
+ assignment can't have multiple identifier subpatterns with the same name.
976
+ This prohibits code like:*
961
977
962
978
```dart
963
979
var a = 1;
@@ -1452,8 +1468,8 @@ categorize into three contexts:
1452
1468
We refer to declaration and assignment contexts as * irrefutable contexts* .
1453
1469
1454
1470
While most patterns look and act the same regardless of where they appear in the
1455
- language, context places some restrictions on which kinds of patterns are
1456
- allowed and what their syntax is . The rules are:
1471
+ language, context determines what identifier patterns mean, and places some
1472
+ restrictions on which other kinds of patterns are allowed . The rules are:
1457
1473
1458
1474
* It is a compile-time error if any of the following * refutable patterns*
1459
1475
appear in an irrefutable context:
@@ -1481,6 +1497,14 @@ allowed and what their syntax is. The rules are:
1481
1497
the matched value isn't assignable to their required type. This error is
1482
1498
specified under type checking.*
1483
1499
1500
+ * In a declaration context, an identifier pattern declares a new variable with
1501
+ that name. * A pattern declaration statement begins with ` var ` or ` final ` , so
1502
+ within that, new variables can be introduced just using simple identifiers:*
1503
+
1504
+ ``` dart
1505
+ var (a, b) = (1, 2);
1506
+ ```
1507
+
1484
1508
* It is a compile-time error if a variable pattern in a declaration context is
1485
1509
marked with `var` or `final`. *A pattern declaration statement is already
1486
1510
preceded by `var` or `final`, so allowing those on the variable patterns
@@ -1492,18 +1516,12 @@ allowed and what their syntax is. The rules are:
1492
1516
final [var y] = [2];
1493
1517
```
1494
1518
1495
- *To declare variables in a declaration context, use a simple identifer:*
1496
-
1497
- ```dart
1498
- // OK:
1499
- var [x] = [1];
1500
- final [y] = [2];
1501
- ```
1519
+ *Variable patterns are allowed in declaration contexts but must have type
1520
+ annotations. This can be useful to upcast the declared variable.*
1502
1521
1503
- * It is a compile-time error if a variable pattern in an assignment context is
1504
- marked with `var`, `final`, or a type annotation (or both `final` and a type
1505
- annotation). *Patterns in assignments can only assign to existing variables,
1506
- not declare new ones.*
1522
+ * It is a compile-time error if a variable pattern appears in an assignment
1523
+ context. *Patterns in assignments can only assign to existing variables
1524
+ using identifier patterns, not declare new ones.*
1507
1525
1508
1526
```dart
1509
1527
var a = 1;
@@ -1516,16 +1534,13 @@ allowed and what their syntax is. The rules are:
1516
1534
(a, b) = (3, 4);
1517
1535
```
1518
1536
1519
- * A simple identifier in a matching context is treated as a named constant
1520
- pattern unless its name is `_`. *A bare identifier is ambiguous and could
1521
- be either a named constant or a variable pattern without any `var`, `final`,
1522
- or type annotation marker. We prefer the constant interpretation for
1523
- backwards compatibility and to make variable declarations more explicit in
1524
- cases. To declare variables in a matching context, use `var`, `final`, or a
1525
- type before the name.*
1526
-
1527
- *There is no ambiguity with bare identifiers in irrefutable contexts since
1528
- constant patterns are disallowed there.*
1537
+ * An identifier pattern in a matching context is treated as a named constant
1538
+ pattern unless its name is `_`. *A bare identifier is ambiguous and could be
1539
+ either a named constant or a variable pattern without any `var`, `final`, or
1540
+ type annotation marker. We prefer the constant interpretation for backwards
1541
+ compatibility and to make variable declarations more explicit in cases. To
1542
+ declare variables in a matching context, use a variable pattern with `var`,
1543
+ `final`, or a type before the name.*
1529
1544
1530
1545
```dart
1531
1546
const c = 1;
@@ -1537,9 +1552,13 @@ allowed and what their syntax is. The rules are:
1537
1552
1538
1553
*This program prints "no match" and not "match 2".*
1539
1554
1540
- * A simple identifier in any context named `_` is treated as a wildcard
1541
- variable pattern. *A bare `_` is always treated as a wildcard regardless of
1542
- context, even though other variables in matching contexts require a marker.*
1555
+ *There is no ambiguity with bare identifiers in irrefutable contexts since
1556
+ constant patterns are disallowed there.*
1557
+
1558
+ * An identifier pattern named `_` in any context is treated as a wildcard that
1559
+ matches any value and discards it. *A bare `_` is always treated as a
1560
+ wildcard regardless of context, even though other variables in matching
1561
+ contexts require a marker.*
1543
1562
1544
1563
```dart
1545
1564
// OK:
@@ -1553,10 +1572,10 @@ allowed and what their syntax is. The rules are:
1553
1572
forbid it, but doing so is discouraged.*
1554
1573
1555
1574
*In short, you can't use refutable patterns in places that don't do control
1556
- flow. Use simple identifiers (optionally with type annotations) to declare
1557
- variables in pattern declarations. Use simple identifiers to assign to variables
1558
- in pattern assignments. Use explicitly marked identifiers to declare variables
1559
- in `case` patterns. Use `_` anywhere for a wildcard.*
1575
+ flow. Use identifier patterns or type annotated variable patterns to declare
1576
+ variables in pattern declarations. Use identifier patterns to assign to
1577
+ variables in pattern assignments. Use variable patterns to declare variables in
1578
+ `case` patterns. Use `_` anywhere for a wildcard.*
1560
1579
1561
1580
## Static semantics
1562
1581
@@ -1766,6 +1785,10 @@ The context type schema for a pattern `p` is:
1766
1785
// ^- Infers List<int>.
1767
1786
```
1768
1787
1788
+ * **Identifier**: Context type schemas are only used in irrefutable contexts,
1789
+ so an identifier pattern is always a variable and is handled like a
1790
+ variable pattern, as above.
1791
+
1769
1792
* **Cast**: The context type schema is `_`.
1770
1793
1771
1794
* **Parenthesized**: The context type schema of the inner subpattern.
@@ -1926,13 +1949,10 @@ To type check a pattern `p` being matched against a value of type `M`:
1926
1949
1927
1950
* **Variable**:
1928
1951
1929
- 1. In an assignment context, the required type of `p` is the (unpromoted)
1930
- static type of the variable that `p` resolves to.
1931
-
1932
- 2. Else if the variable has a type annotation, the required type of `p` is
1933
- that type, as is the static type of the variable introduced by `p`.
1952
+ 1. If the variable has a type annotation, the required type of `p` is that
1953
+ type, as is the static type of the variable introduced by `p`.
1934
1954
1935
- 3 . Else the required type of `p` is `M`, as is the static type of the
1955
+ 2 . Else the required type of `p` is `M`, as is the static type of the
1936
1956
variable introduced by `p`. *This means that an untyped variable pattern
1937
1957
can have its type indirectly inferred from the type of a superpattern:*
1938
1958
@@ -1945,6 +1965,17 @@ To type check a pattern `p` being matched against a value of type `M`:
1945
1965
That inferred type is then destructured and used to infer `num` for `a`
1946
1966
and `Object` for `b`.*
1947
1967
1968
+ * **Identifier**:
1969
+
1970
+ 1. In an assignment context, the required type of `p` is the (unpromoted)
1971
+ static type of the variable that `p` resolves to.
1972
+
1973
+ 2. In a matching context, the name refers to a constant. Type check
1974
+ the constant identifier expression in context type `M`.
1975
+
1976
+ 3. In a declaration context, the required type of `p` is `M`, as is the
1977
+ static type of the variable introduced by `p`.
1978
+
1948
1979
* **Parenthesized**: Type-check the inner subpattern using `M` as the matched
1949
1980
value type.
1950
1981
@@ -2051,10 +2082,11 @@ To type check a pattern `p` being matched against a value of type `M`:
2051
2082
2052
2083
If `p` with required type `T` is in an irrefutable context:
2053
2084
2054
- * It is a compile-time error if `M` is not assignable to `T`. *Destructuring
2055
- and variable patterns can only be used in declarations and assignments if we
2056
- can statically tell that the destructuring and variable binding won't fail
2057
- to match.*
2085
+ * It is a compile-time error if `M` is not assignable to `T`. *Destructuring,
2086
+ variable, and identifier patterns can only be used in declarations and
2087
+ assignments if we can statically tell that the destructuring and variable
2088
+ binding won't fail to match (though it may still throw at runtime if the
2089
+ matched value type is `dynamic`).*
2058
2090
2059
2091
* Else if `M` is not a subtype of `T` then an implicit coercion or cast is
2060
2092
inserted before the pattern binds the value, tests the value's type,
@@ -2161,6 +2193,16 @@ pattern is:
2161
2193
matching context, the variable is final if the variable pattern is
2162
2194
marked `final` and is not otherwise.
2163
2195
2196
+ * **Identifier**:
2197
+
2198
+ 1. In a matching context, the empty set. *The identifier is a constant
2199
+ reference.*
2200
+
2201
+ 2. Else a set containing a single variable whose name is the identifier and
2202
+ whose type is the pattern's required type (which may have been
2203
+ inferred). The variable is final if and only if the surrounding
2204
+ `patternVariableDeclaration` has a `final` modifier.
2205
+
2164
2206
#### Scope
2165
2207
2166
2208
The variables defined by a pattern and its subpatterns (its pattern variable
@@ -2745,6 +2787,13 @@ To match a pattern `p` against a value `v`:
2745
2787
2746
2788
3. Otherwise, store `v` in `p`'s variable and the match succeeds.
2747
2789
2790
+ * **Identifier**:
2791
+
2792
+ 1. In a matching context, the same as a constant pattern whose constant
2793
+ expression is the identifier.
2794
+
2795
+ 2. Else, the same as a variable pattern with the same identifier.
2796
+
2748
2797
* **Parenthesized**: Match the subpattern against `v` and succeed if it
2749
2798
matches.
2750
2799
@@ -3168,6 +3217,13 @@ To bind invocation keys in a pattern `p` using parent invocation `i`:
3168
3217
3169
3218
1 . Nothing to do.
3170
3219
3220
+ * ** Identifier** :
3221
+
3222
+ 1 . In a matching context, the same as a constant pattern whose constant
3223
+ expression is the identifier.
3224
+
3225
+ 2 . Else, nothing to do.
3226
+
3171
3227
* ** List** :
3172
3228
3173
3229
1 . Bind ` i : ("length", []) ` to the ` length ` getter invocation.
@@ -3356,6 +3412,9 @@ Here is one way it could be broken down into separate pieces:
3356
3412
3357
3413
- Handle negative length lists and maps (#2701).
3358
3414
3415
+ - Disambiguate the grammar around bare identifiers (#2714). The overall syntax
3416
+ and semantics are unchanged, but the pattern grammar is now unambiguous.
3417
+
3359
3418
- Allow promoted types and type variables with bounds to be always-exhaustive
3360
3419
(#2765).
3361
3420
0 commit comments