You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
The #555 **codegen** handler-arm-drop class was fixed by #566 (issue now
closed). This addresses the live **interpreter** residual its closing
comment left open — the tree-walking interpreter's shallow `resume`.
`ExprHandle` models the resume continuation as the identity, correct
only for single-shot **tail**-resume. Multi-shot resume (calling
`resume` >1×) has no reified continuation, so each call just returned
its argument and e.g. `resume(1) + resume(2)` silently evaluated to `3`
instead of running the continuation twice — a silent miscompute.
## Fix
`lib/interp.ml`: count resume invocations per dispatch and fail loud
(`RuntimeError`) on the second call. A multi-shot handler can never
again silently produce a wrong value. Single-shot tail-resume (the
supported shape) is unaffected.
**Documented residual (not closed here):** non-tail single-shot resume
(`let x = op(); x + 100` resuming to 5 rather than 105) stays a
shallow-resume incompleteness — the body has already unwound the bind
chain when the arm runs, so the discarded continuation is undetectable
without a CPS transform. It's pinned as an executable known-shallow fact
that flips deliberately when delimited continuations land.
## Tests
New `E2E Resume Soundness (#555)` group — the **first** interpreter
tests that actually `apply` `main` and exercise `resume`:
- `handle_resume_tail.affine` → `VInt 5` (single-shot tail-resume works)
- `handle_resume_multishot.affine` → loud "multi-shot resume" error
(negative)
- `handle_resume_nontail.affine` → `VInt 5`, KNOWN shallow (flips to 105
when CPS lands)
Full suite **454/454 green**.
Refs #555
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments