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
fix(BUG-004): lambda capture tracking — linear variables cannot be captured
Two coordinated fixes close BUG-004 (lambda capturing linear resources).
quantity.ml — ExprLambda scales captures by QOmega:
A lambda may be called zero or many times. Any outer variable it
references is therefore effectively used QOmega times. The fix snapshots
the usage env before walking the lambda body (shadowing lambda-local params),
computes the per-variable delta, restores the outer env, then re-applies
each delta scaled by QOmega via scale_usage. Consequence:
let v: QOne = ...; let f = |x| v + x;
→ delta(v) = UOne, scale_usage QOmega UOne = UMany
→ linear variable 'v' used multiple times → LinearVariableUsedMultiple
borrow.ml — ExprLambda creates Shared borrows for all free variables:
Adds collect_free: a structural walk of the lambda body that collects every
ExprVar name not bound by the lambda's own parameters. For each free
variable that resolves to a place, a Shared borrow is created before the
body is checked. This prevents the caller from moving a captured variable
after the lambda is created (use-after-move / move-while-borrowed):
let v = 42; let f = |x| consume(v); f(0);
→ shared borrow of v created at lambda site
→ consume(v) tries to move v → MoveWhileBorrowed error
Borrows expire at enclosing block exit via the lexical-lifetime clearing
added in the previous commit.
borrow.ml — borrow_kind_name replaces show_borrow_kind in error messages:
show_borrow_kind (OCaml-derived) produced "Borrow.Shared"; the new helper
produces "shared" / "exclusive" for readable diagnostics.
Verified:
- lambda capturing a moved-value → "cannot move `v` while it is
shared-borrowed at …"
- valid lambda with no captured owned values → passes
- 73/73 tests pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0 commit comments