Commit d437dfe
committed
feat(check): catch block narrows target to error
Inside an assignment's catch block, reads of the assignment target
now see type `error` rather than the post-success type the frame
held coming out of walkAssign.
The runtime guarantee is clear: a catch block executes precisely
because the RHS errored - so within the catch body, the target IS
carrying an error value. Previously the catch body walked under the
frame walkAssign set up for the success path (the assignment target
narrowed to the RHS value type), which silently said "the user
referenced x inside the catch, and x is int" - incorrect, since the
RHS errored on this path.
The override is the error arm of the RHS type when extractable:
parse_int returns int|error, so the override is `error` (the second
arm). Falls back to a bare TypingErrorT when no error arm is
visible (we couldn't introspect the RHS type, but the runtime
already guarantees we're in the error branch - error is sound).
After the catch body, tc.frame is restored. The catch's body
narrowing doesn't leak into subsequent statements - exactly what
the immutable frame's save/restore pattern gives us.
extractErrorFrom lives next to stripErrorFrom in narrow.go (they're
duals - one returns the error component, the other returns
everything except). Shared code: future error-path narrowings
(e.g. ExprStmt + catch in shell statements) can reuse the same
helper.1 parent ebe5242 commit d437dfe
2 files changed
Lines changed: 83 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
729 | 729 | | |
730 | 730 | | |
731 | 731 | | |
732 | | - | |
733 | | - | |
734 | | - | |
735 | | - | |
736 | | - | |
737 | | - | |
738 | | - | |
739 | | - | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
740 | 744 | | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
741 | 767 | | |
| 768 | + | |
742 | 769 | | |
743 | 770 | | |
744 | 771 | | |
| |||
0 commit comments