Skip to content

Commit b8eb49f

Browse files
committed
[patterns] Minor tweaks:
- Define the static type of switch expressions. - Clarify semantics of runtime type tests. - Allow relational operators whose return type is `dynamic`. Fix #2380. Fix #2385.
1 parent 8aa7930 commit b8eb49f

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

working/0546-patterns/patterns-feature-specification.md

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,9 +1335,9 @@ To type check a pattern `p` being matched against a value of type `M`:
13351335

13361336
* **Relational**: If the operator is a comparison (`<`, `<=`, `>`, or `>=`),
13371337
then it is a compile-time error if `M` does not define that operator, if the
1338-
type of the constant in the relational pattern is not a subtype of the
1339-
operator's parameter type, or if the operator's return type is not `bool`.
1340-
*The `==` and `!=` operators are valid for all pairs of types.*
1338+
type of the constant in the relational pattern is not assignable to the
1339+
operator's parameter type, or if the operator's return type is not `bool` or
1340+
`dynamic`. *The `==` and `!=` operators are valid for all pairs of types.*
13411341

13421342
* **Null-check** or **null-assert**:
13431343

@@ -1474,6 +1474,11 @@ To type check a pattern `p` being matched against a value of type `M`:
14741474
It is a compile-time error if the type of an expression in a guard clause is not
14751475
`bool` or `dynamic`.
14761476
1477+
### Switch expression type
1478+
1479+
The static type of a switch expression is the least upper bound of the static
1480+
types of all of the case expressions.
1481+
14771482
## Refutable and irrefutable patterns
14781483
14791484
Patterns appear inside a number of other constructs in the language. This
@@ -1665,9 +1670,10 @@ behavior.
16651670
to the next case (or default clause or exit the switch if there are no
16661671
other cases).
16671672

1668-
2. If there is a guard clause, evaluate it. If it does not evaluate to
1669-
a Boolean, throw a runtime exception. If it evaluates to `false`,
1670-
continue to the next case (or default or exit).
1673+
2. If there is a guard clause, evaluate it. If it does not evaluate to a
1674+
Boolean, throw a runtime exception. *This can happen if the guard
1675+
expression's type is `dynamic`.* If it evaluates to `false`, continue to
1676+
the next case (or default or exit).
16711677

16721678
3. Execute the nearest non-empty case body at or following this case.
16731679
*You're allowed to have multiple empty cases where all preceding
@@ -1775,25 +1781,28 @@ To match a pattern `p` against a value `v`:
17751781

17761782
* **Variable**:
17771783

1778-
1. If `v` is not a subtype of `p` then the match fails.
1784+
1. If the runtime type of `v` is not a subtype of the static type of `p`
1785+
then the match fails.
17791786

17801787
2. Otherwise, bind the variable's identifier to `v` and the match succeeds.
17811788

17821789
* **Cast**:
17831790

1784-
1. If `v` is not a subtype of `p` then throw a runtime exception. *Note
1785-
that we throw even if this appears in a refutable context. The intent
1786-
of this pattern is to assert that a value *must* have some type.*
1791+
1. If the runtime type of `v` is not a subtype of the static type of `p`
1792+
then throw a runtime exception. *Note that we throw even if this appears
1793+
in a refutable context. The intent of this pattern is to assert that a
1794+
value *must* have some type.*
17871795

17881796
2. Otherwise, bind the variable's identifier to `v` and the match succeeds.
17891797

17901798
* **Grouping**: Match the subpattern against `v` and succeed if it matches.
17911799

17921800
* **List**:
17931801

1794-
1. If `v` is not a subtype of `p` then the match fails. *The list pattern's
1795-
type will be `List<T>` for some `T` determined either by the pattern's
1796-
explicit type argument or inferred from the matched value type.*
1802+
1. If the runtime type of `v` is not a subtype of the static type of `p`
1803+
then the match fails. *The list pattern's type will be `List<T>` for
1804+
some `T` determined either by the pattern's explicit type argument or
1805+
inferred from the matched value type.*
17971806

17981807
2. If the length of the list determined by calling `length` is not equal to
17991808
the number of subpatterns, then the match fails. *This match failure
@@ -1811,10 +1820,10 @@ To match a pattern `p` against a value `v`:
18111820

18121821
* **Map**:
18131822

1814-
1. If `v` is not a subtype of `p` then the match fails. *The map pattern's
1815-
type will be `Map<K, V>` for some `K` and `V` determined either by the
1816-
pattern's explicit type arguments or inferred from the matched value
1817-
type.*
1823+
1. If the runtime type of `v` is not a subtype of the static type of `p`
1824+
then the match fails. *The map pattern's type will be `Map<K, V>` for
1825+
some `K` and `V` determined either by the pattern's explicit type
1826+
arguments or inferred from the matched value type.*
18181827

18191828
2. Otherwise, for each entry in `p`:
18201829

@@ -1832,7 +1841,8 @@ To match a pattern `p` against a value `v`:
18321841

18331842
* **Record**:
18341843

1835-
1. If `v` is not a record with the same type as `p`, then the match fails.
1844+
1. If the runtime type of `v` is not a record type with the same type as
1845+
the static type of `p`, then the match fails.
18361846

18371847
2. For each field `f` in `p`, in source order:
18381848

@@ -1845,7 +1855,8 @@ To match a pattern `p` against a value `v`:
18451855

18461856
* **Extractor**:
18471857

1848-
1. If `v` is not a subtype of `p` then the match fails.
1858+
1. If the runtime type of `v` is not a subtype of the static type of `p`
1859+
then the match fails.
18491860

18501861
3. Otherwise, for each field `f` in `p`:
18511862

@@ -1940,6 +1951,16 @@ Here is one way it could be broken down into separate pieces:
19401951

19411952
## Changelog
19421953

1954+
### 2.1
1955+
1956+
Minor tweaks:
1957+
1958+
- Define the static type of switch expressions (#2380).
1959+
1960+
- Clarify semantics of runtime type tests (#2385).
1961+
1962+
- Allow relational operators whose return type is `dynamic`.
1963+
19431964
### 2.0
19441965

19451966
Major redesign of the syntax and minor redesign of the semantics.

0 commit comments

Comments
 (0)