From b291574ffdba8ec8e118ed581f3763ddc156808e Mon Sep 17 00:00:00 2001 From: James Clark Date: Wed, 25 Nov 2020 11:05:13 +0700 Subject: [PATCH] Narrow types in match statements Fixes #152 --- lang/spec.html | 69 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/lang/spec.html b/lang/spec.html index 7a826968..04f5eadc 100644 --- a/lang/spec.html +++ b/lang/spec.html @@ -7437,20 +7437,20 @@

Local variable declaration statements

-

Implicit variable type narrowing

+

Conditional variable type narrowing

Usually the type of a reference to a variable is determined by the variable's declaration, either explicitly specified by a type descriptor or inferred from -the static type of the initializer. -

-

-In addition, this section defines cases where a variable is used in certain -kinds of boolean expression in a conditional context, and it can be proved at -compile time that the value stored in local variable or parameter will, within a -particular region of code, always belong to a type that is narrower that the -static type of the variable. In these cases, references to the variable within -particular regions of code will have a static type that is narrower that the -variable type. +the static type of the initializer. However, the language also recognizes two +kinds of case where the way a local variable or parameter is used means that is +known at compile-time that within a particular region of code the value of the +variable will belong to a type that is narrower than the declared type. In these +cases, references to the variable within particular regions of code will have a +static type that is narrower that the variable type. One kind of case, which is +described in this section, is when a variable is used in a boolean expression in +a conditional context. The other kind of case is when a variable is used in a +match statement; this is described in the Match +statement section.

Given an expression E with static type boolean, and a variable x with static @@ -7942,7 +7942,7 @@

Do statement

-

Match statement

+

Match statement

match-stmt := match action-or-expr { match-clause+ }
@@ -8074,12 +8074,47 @@ 

Match statement

match a field-match-pattern.

-For a match of an error-match-pattern with an +For every match pattern, there is a set of shapes that the pattern matches. The +type corresponding to the match pattern is the type containing these shapes. The +value matches the pattern if and only if it looks like the type. A mutable value +thus can match the pattern without belonging to the corresponding type. However, +an immutable value that matches the pattern will always belong to the type. +In particular, for the match of an error-match-pattern with an error-type-reference against an error value to succeed, the -referenced error type must contain the shape of the error value; since errors -are immutable, this requirement is equivalent to requiring that the error value -belong to the referenced error type. -

+error value must belong to the referenced error type. +

+

+A variable is the matched variable of a match-statement if +the action-or-expression following match is a +variable-reference that references this variable. The type of a +matched variable is subject to narrowing within regions of the +match-statement as follows. The matched variable has a narrowed +type at the start of each match-clause, which is determined by previous +match-clauses; the type for the first match-clause is +the normal static type of the variable. Narrowing is applied to each +match-clause as follows: +

+
    +
  • let T be the narrowed type of the matched variable at the start +of the match-clause;
  • +
  • let P be the union of the corresponding types of each +match-pattern in the match-pattern-list of the +match-clause;
  • +
  • let N be the intersection of T and +P;
  • +
  • let R be the set difference of T and +P;
  • +
  • if N is a subtype of readonly, then the narrowed +type for the match-guard, if any, and statement-block +of the match-clause is N; otherwise it is +T;
  • +
  • if there is a match-guard, then the type narrowing described in Conditional variable type +narrowing is done in addition to the type narrowing described here;
  • +
  • if R is a subtype of readonly and there is no +match-guard, then the narrowed type for the next +match-clause is R; otherwise, it is T.
  • +