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
The #555 codegen handler-arm-drop class was fixed by #566; the live residual
was 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` more than once) 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.
Count resume invocations per dispatch and fail loud (RuntimeError) on the
second call, so a multi-shot handler can never silently produce a wrong value.
Single-shot tail-resume (the one shape the interpreter implements correctly)
is unaffected. Non-tail single-shot resume (`let x = op(); x + 100` resuming
to 5 rather than 105) remains a documented shallow-resume incompleteness: the
body has already unwound the bind chain when the arm runs, so the discarded
continuation is undetectable here without a CPS transform.
Regression tests (test/test_e2e.ml, "E2E Resume Soundness (#555)") — 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
delimited continuations land)
Full suite 454/454 green.
Refs #555
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments