Skip to content

Commit 4ca7482

Browse files
[flow analysis expressions] Fix instance check and assignment to match implementation. (#4307)
This change fixes three spec inaccuracies: 1. The spec claimed that when flow analysis encounters an expression `N` of the form `V = E` (a local variable assignment), it would set `true(N)` and `false(N)` based on `true(E)` and `false(E)`. Note that we *could* have implemented flow analysis this way; if we had, then a test like `if (v1 = v2 is T)` would have promoted `v2` to `T`. But we didn't implement that functionality. 2. The spec failed to document the special behavior of expressions of the form `E is Never`. Flow analysis knows that expressions of this form cannot evaluate to `true`. 3. The spec failed to document the special behavior of expressions of the form `E is! T`. `E is! T` is understood by flow analysis to behave the same as `!(E is T)`.
1 parent 4d1dff9 commit 4ca7482

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

resources/type-system/flow-analysis.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,6 @@ then they are all assigned the same value as `after(N)`.
546546
where `x` is a local variable, then:
547547
- Let `before(E1) = before(N)`.
548548
- Let `after(N) = assign(x, E1, after(E1))`.
549-
- Let `true(N) = assign(x, E1, true(E1))`.
550-
- Let `false(N) = assign(x, E1, false(E1))`.
551549

552550
- **operator==** If `N` is an expression of the form `E1 == E2`, where the
553551
static type of `E1` is `T1` and the static type of `E2` is `T2`, then:
@@ -585,8 +583,25 @@ then they are all assigned the same value as `after(N)`.
585583
- **instance check** If `N` is an expression of the form `E1 is S` where the
586584
static type of `E1` is `T` then:
587585
- Let `before(E1) = before(N)`
588-
- Let `true(N) = promote(E1, S, after(E1))`
589-
- Let `false(N) = promote(E1, factor(T, S), after(E1))`
586+
- If `T` is a bottom type, then:
587+
- Let `true(N) = unreachable(after(E1))`.
588+
- Let `false(N) = after(E1)`.
589+
- Otherwise:
590+
- Let `true(N) = promote(E1, S, after(E1))`
591+
- Let `false(N) = promote(E1, factor(T, S), after(E1))`
592+
593+
- **negated instance check** If `N` is an expression of the form `E1 is! S`
594+
where the static type of `E1` is `T` then:
595+
- Let `before(E1) = before(N)`
596+
- If `T` is a bottom type, then:
597+
- Let `true(N) = after(E1)`.
598+
- Let `false(N) = unreachable(after(E1))`.
599+
- Otherwise:
600+
- Let `true(N) = promote(E1, factor(T, S), after(E1))`
601+
- Let `false(N) = promote(E1, S, after(E1))`
602+
603+
_Note that flow analysis treats `E1 is! S` the same as the equivalent
604+
expression `!(E1 is S)`._
590605

591606
- **type cast** If `N` is an expression of the form `E1 as S` where the
592607
static type of `E1` is `T` then:

0 commit comments

Comments
 (0)