-
Allow variable declarations under
or
andnot
patterns and acrosscase
labels in aswitch
section.if (e is C c or Wrapper { Prop: C c }) return c; Expr Simplify(Expr e) { switch (e) { case Mult(Const(1), var x): case Mult(var x, Const(1)): case Add(Const(0), var x): case Add(var x, Const(0)): return Simplify(x); // .. } }
Instead of:
if (e is C c1) return c1; if (e is Wrapper { Prop: C c2 }) return c2; Expr Simplify(Expr e) { switch (e) { case Mult(Const(1), var x): return Simplify(x); case Mult(var x, Const(1)): return Simplify(x); case Add(Const(0), var x): return Simplify(x); case Add(var x, Const(0)): return Simplify(x); // .. } }
-
Also relax single-declaration rules across the entire declaring scope as long as each variable is assigned once.
if (e is C c || e is Wrapper { Prop: C c }) ; if (e is C c) ; else if (e is Wrapper { Prop: C c }) ; if (b ? e is C c : e is Warpper { Prop: C c }) ;
- Pattern variables are allowed to be redeclared in the same scope if not already definitely assigned. These names can possibly reference either of variables based on the result of the pattern-matching at runtime.
- Pattern variables with multiple declarations must be of the same type, excluding tuple names and nullability for reference types.
For an is_pattern_expression of the form e is pattern
, the definite assignment state of v after is_pattern_expression is determined by:
- The state of v after is_pattern_expression is definitely assigned, if pattern is irrefutable.
- Otherwise, the state of v after is_pattern_expression is the same as the state of v after pattern.
For a switch_section of the form case pattern_1 when condition_1: ... case pattern_N when condition_N:
, the definite assignment state of v is determined by:
- The state of v before condition_i is definitely assigned, if the state of v after pattern_i is "definitely assigned when true".
- The state of v before switch_section_body is definitely assigned, if the state of v after each pattern_i is "definitely assigned when true".
- Otherwise, the state of v is not definitely assigned.
The following rule applies to any primary_pattern p that declares a variable, namely list_pattern, declaration_pattern, recursive_pattern, and var_pattern, as well as any nested subpatterns.
- The state of v after p is "definitely assigned when true".
For a disjunctive_pattern p of the form left or right
, the definite assignment state of v is determined by:
- The state of v before right is definitely assigned if and only if the state of v after left is "definitely assigned when false".
- The state of v after p is "definitely assigned when true" if the state of v after both left and right is "definitely assigned when true".
- The state of v after p is "definitely assigned when false" if the state of v after either left or right is "definitely assigned when false".
For a conjunctive_pattern p of the form left and right
, the definite assignment state of v is determined by:
- The state of v before right is definitely assigned if and only if the state of v after left is "definitely assigned when true".
- The state of v after p is "definitely assigned when true" if the state of v after either left or right is "definitely assigned when true".
- The state of v after p is "definitely assigned when false" if the state of v after both left and right is "definitely assigned when false".
For a negated_pattern p of the form not pattern
, the definite assignment state of v after p is determined by:
- If the state of v after pattern is "definitely assigned when true", then the state of v after p is "definitely assigned when false".
- If the state of v after pattern is "definitely assigned when false", then the state of v after p is "definitely assigned when true".
These rules cover the existing top-level is not
pattern variables. However, in any other scenario the variables could be left unassigned.
- Should the redeclaration rules work in nested scopes?
if (e is C c) return; if (e is C c) return; // allowed { if (e is C c) return; } // allowed?