ERR/E1.8: path-sensitive value-slot liveness check
A `v, err := failable()` destructure now binds the value slot(s) "live
only where `err` is proven absent". Reading `v` where the compiler cannot
prove `err == null` is a compile error.
New diagnostic-only Pass 1e (`checkErrorFlow` in ir/lower.zig): a
structured, path-sensitive walk over each main-file function body. A
proven-null set is threaded across branches and joined by intersection
at each `if`'s merge. Proof shapes recognized:
- `if !err { … v … }` (proven inside the guard)
- `if err { return/raise } … v` (proven on the fall-through)
- `if err { … } else { … v … }` (proven in the else branch)
- `!err and <reads v>` (short-circuit refinement)
Error-set tag compares (`if err == error.X`) prove nothing about
absence — they narrow the tag only. Nested lambdas are analyzed as their
own boundaries. Library modules are trusted (skipped).
Migrated the canon value-failable examples (1011/1012/1018/1044) to read
their value slots under `if !err` guards — output unchanged. New
regressions: 1046 (every proof shape compiles + runs, exit 210) and 1047
(unproven reads rejected, exit 1).
Gates: zig build, zig build test, run_examples.sh -> 338 passed, 0 failed.
This commit is contained in:
@@ -52,15 +52,13 @@ main :: () -> s32 {
|
||||
// Destructure binds EVERY slot including the error tag (e1 / e2 / e3) —
|
||||
// the error is treated, never dropped.
|
||||
v1, b1, e1 := parse(5); // success → (10, 6, no-error)
|
||||
if e1 == error.Bad { r = r + 1000; } // false
|
||||
r = r + v1 + b1; // +16
|
||||
if !e1 { r = r + v1 + b1; } // success → +16 (slots live only when proven ok)
|
||||
|
||||
v2, b2, e2 := parse(-1); // Bad → {undef, undef, Bad}
|
||||
if e2 == error.Bad { r = r + 4; } // +4
|
||||
|
||||
a, c, ea := inc(5); // parse(5)=(10,6) → (11, 7, no-error)
|
||||
if ea == error.Bad { r = r + 2000; } // false
|
||||
r = r + a + c; // +18
|
||||
if !ea { r = r + a + c; } // success → +18
|
||||
|
||||
a2, c2, e3 := inc(-1); // try parse(-1)=Bad → propagate {undef, undef, Bad}
|
||||
if e3 == error.Bad { r = r + 5; } // +5
|
||||
|
||||
Reference in New Issue
Block a user