Files
AILang/crates
Brummel 68f500c4b0 fix(codegen): drop owned params on tail-call-terminated match arms (#63 leg 1)
An owned heap ADT param that a tail-recursive match arm neither
forwards into the tail call nor consumes had no drop site: the
fn-return Own-param dec in lib.rs is gated behind `!block_terminated`
and so fires only on the fall-through `ret` path, while the per-arm
drop in match_lower.rs handled only pattern binders. A
`musttail call`-terminated arm therefore leaked one slab per
recursion step (#63, leg 1).

match_lower.rs now emits a pre-tail-call Own-param dec, gated exactly
like the fn-return path: Rc strategy, `arm_body_is_tail_call`,
ParamMode::Own, ptr-typed, and uniqueness `consume_count == 0`. For an
Own param consume_count==0 also implies "not forwarded into the tail
call" — a forwarded Own arg is walked Position::Consume and carries
consume_count>=1 — so the gate cannot drop a param the callee took
ownership of. The drop routes through the same per-type /
partial-drop machinery (honouring moved_slots) as the fn-return path.

The match scrutinee param is explicitly skipped: its ownership is
already discharged by the pre-tail-call scrutinee-husk shallow-dec
plus the moved-out field binders, so dropping it here would dec the
same outer cell twice (a double-handling the first cut of this fix
introduced and the quality review caught — the pin read live=0 but
the IR showed two decs on the scrutinee cell).

Verified: the committed RED pin is green (live=0, allocs==frees);
full `cargo test --workspace` 0 failures; the fix introduces no
under-free (loop_recur_heap_binder / loop_recur_str_binder /
loop_str_recur_literal / rc_pin_recurse_implicit /
lit_pat_ctor_tail_drop all stay live=0, no underflow to depth 5).
No INTERCEPTS/(intrinsic) or pre_desugar_validation change; no IR
snapshot refresh needed.

Leg 1 only. Leg 2 — a `let`/`seq`-wrapped tail call makes the arm
body an MTerm::Let so `arm_body_is_tail_call` is false, skipping both
the husk-dec and this new param-dec — still leaks (examples/series_sma.ail
stays live=8). It gets its own RED pin and fix next.

refs #63
2026-06-02 13:41:57 +02:00
..