Skip to content

Commit 87fa68c

Browse files
authored
[patterns] Small fixes and clarifications (#2819)
* [patterns] Fix sign of a remark on non-refutable patterns * [patterns] Try to clarify remark on non-"refutable" patterns that fail I found I had to reread this paragraph a couple of times to understand the point it was making. (Possibly the logic error just fixed in it can be taken as evidence that other readers found it a bit hard to read, too.) So here's an attempt at making it clearer. * [patterns] Deduplicate assignable-to-bool requirement on guard expressions * [patterns] Slightly unpack logic for list length-checking I found the preface "If `p` is empty or has any non-rest elements", and its relationship with the sub-cases it encloses, required some re-reading to put together. It's meant as a way of saying "If `p` is not `[...]`", as referred to in the rationale line that follows it; but to see that, one has to work through a bit of Boolean logic to invert the condition. So here's a rewording which I hope is clearer, by un-inverting the condition. The usage "then do nothing for checking the length" is perhaps a bit unconventional in spec-ese. But it's parallel to the "then do nothing for checking this element" found in the head and tail cases below. * [patterns] Slightly unpack logic for map length-checking Much like for lists in the previous commit. * [patterns] Fix spec-variable references in field subpattern caching There's no `e` defined here, but there is an `f`. Based on the object case just below, I think the name `f` ("field") was the intended one. Also cut a conflicting definition of `f`.
1 parent 6a13f89 commit 87fa68c

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

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

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,11 +1493,10 @@ restrictions on which other kinds of patterns are allowed. The rules are:
14931493
true the pattern does nothing useful since its only behavior is a type
14941494
test.*
14951495

1496-
*The remaining patterns are allowed syntactically to appear in a refutable
1497-
context. Patterns that do type tests like variables and lists produce a
1498-
compile-time error when used in an irrefutable context if the static type of
1499-
the matched value isn't assignable to their required type. This error is
1500-
specified under type checking.*
1496+
*In addition to this rule, patterns that do type tests (like variable and
1497+
list patterns) produce a compile-time error when used in an irrefutable
1498+
context if the static type of the matched value isn't assignable to their
1499+
required type. That error is specified under type checking.*
15011500

15021501
* In a declaration context, an identifier pattern declares a new variable with
15031502
that name. *A pattern declaration statement begins with `var` or `final`, so
@@ -2132,13 +2131,10 @@ If `p` with required type `T` is in an irrefutable context:
21322131
a _cast_ from `dynamic` to `String` and instead let the `String s` pattern
21332132
_test_ the value's type, which then fails to match.*
21342133
2135-
It is a compile-time error if the type of an expression in a guard clause is not
2136-
assignable to `bool`.
2137-
21382134
### Pattern uses (static semantics)
21392135
2140-
It is a compile-time error if the expression in a guard clause in a switch case
2141-
or if-case construct is not assignable to `bool`.
2136+
It is a compile-time error if the type of an expression in a guard clause is not
2137+
assignable to `bool`.
21422138
21432139
The static type of a switch expression is the least upper bound of the static
21442140
types of all of the case expressions.
@@ -2910,29 +2906,33 @@ To match a pattern `p` against a value `v`:
29102906
3. Let `t` be the number of non-rest elements following the rest element if
29112907
there is one, or `0` otherwise.
29122908
2913-
4. Check the length. If `p` is empty or has any non-rest elements:
2909+
4. Check the length:
2910+
2911+
1. If `p` has a rest element and `h + t == 0`, then do nothing for
2912+
checking the length.
29142913
2915-
*We only call `length` on the list if needed. If the pattern is `[...]`,
2916-
then any length is allowed, so we don't even check it..*
2914+
*We only call `length` on the list if needed. If the pattern is
2915+
`[...]`, then any length is allowed, so we don't even ask the list
2916+
for it.*
29172917
2918-
1. Let `l` be the length of the list determined by calling `length` on
2919-
`v`.
2918+
2. Else let `l` be the length of the list determined by calling
2919+
`length` on `v`.
29202920
2921-
2. If `p` has a rest element and `h + t > 0`:
2921+
3. If `p` has a rest element *(and `h + t > 0`)*:
29222922
29232923
1. If `l < h + t` then the match fails.
29242924
29252925
*When there are non-rest elements and a rest element, the list must
29262926
be at least long enough to match the non-rest elements.*
29272927
2928-
3. Else if `h + t > 0` *(and `p` has no rest element)*:
2928+
4. Else if `h + t > 0` *(and `p` has no rest element)*:
29292929
29302930
1. If `l != h + t` then the match fails.
29312931
29322932
*If there are only non-rest elements, then the list must have
29332933
exactly the same number of elements.*
29342934
2935-
4. Else `p` is empty:
2935+
5. Else `p` is empty:
29362936
29372937
1. If `l > 0` then the match fails.
29382938
@@ -3004,29 +3004,33 @@ To match a pattern `p` against a value `v`:
30043004
30053005
2. Let `n` be the number of non-rest elements.
30063006
3007-
3. Check the length. If `p` is empty or has any non-rest elements:
3007+
3. Check the length:
30083008
3009-
*We only call `length` on the map if needed. If the pattern is `{...}`,
3010-
then any length is allowed, so we don't even check it.*
3009+
1. If `p` has a rest element and `n == 0`, then do nothing for checking
3010+
the length.
30113011
3012-
1. Let `l` be the length of the map determined by calling `length` on
3013-
`v`.
3012+
*We only call `length` on the map if needed. If the pattern is
3013+
`{...}`, then any length is allowed, so we don't even ask the map
3014+
for it.*
30143015
3015-
2. If `p` has a rest element and `n > 0`:
3016+
2. Else let `l` be the length of the map determined by calling `length`
3017+
on `v`.
3018+
3019+
3. If `p` has a rest element *(and `n > 0`)*:
30163020
30173021
1. If `l < n` then the match fails.
30183022
30193023
*When there are non-rest elements and a rest element, the map must
30203024
be at least long enough to match the non-rest elements.*
30213025
3022-
3. Else if `n > 0` *(and `p` has no rest element)*:
3026+
4. Else if `n > 0` *(and `p` has no rest element)*:
30233027
30243028
1. If `l != n` then the match fails.
30253029
30263030
*If there are only non-rest elements, then the map must have exactly
30273031
the same number of elements.*
30283032
3029-
4. Else `p` is empty:
3033+
5. Else `p` is empty:
30303034
30313035
1. If `l > 0` then the match fails.
30323036
@@ -3413,14 +3417,14 @@ To bind invocation keys in a pattern `p` using parent invocation `i`:
34133417
34143418
* **Record**:
34153419
3416-
1. For each field `f` in `p`:
3420+
1. For each field in `p`:
34173421
34183422
1. Let `f` be `i : (field, [])` where `field` is the corresponding
34193423
getter name for the field.
34203424
3421-
2. Bind `e` to the field accessor for this field.
3425+
2. Bind `f` to the field accessor for this field.
34223426
3423-
3. Bind invocations in the field subpattern using parent `e`.
3427+
3. Bind invocations in the field subpattern using parent `f`.
34243428
34253429
* **Object**:
34263430

0 commit comments

Comments
 (0)