2488d9d345471501b5cb2f65d49d3f7ab619d278
After the leg-1 fix (68f500c), a tail call wrapped in a trailing
`(let ...)` (or `seq`) still leaks: the arm body is an MTerm::Let, not
a direct App{tail:true}, so `arm_body_is_tail_call` (match_lower.rs
~717) is false and both the scrutinee-husk shallow-dec and the leg-1
owned-param dec are skipped — while lower_term still descends through
the Let body and emits the inner call as musttail. The scrutinee husk
and the non-forwarded owned param each leak one slab per recursion
step.
Series-free minimal repro (a plain `Box` whose replacement is
let-bound before the tail call), asserting live == 0 under
AILANG_RC_STATS=1. RED today: `allocs=6 frees=2 live=4`. This is the
leg that keeps examples/series_sma.ail at live=8 (its canonical
`(let s_new (push …) (seq … (tail-app …)))` body).
The debugger confirmed the fix is contained, not a design fork:
`arm_body_is_tail_call` feeds only the two drop-emission gates, never
the musttail-emission decision (which lives independently in
lower_term off App{tail:true}), so peeling the detection through a
trailing Let/Seq chain ending in a tail call is safe. The let
scope-close drop is gated on `!block_terminated` and so is correctly
skipped, avoiding a double-free of the let binding.
refs #63
feat(lang): eliminate the Implicit ownership default — totality + the drop-soundness it demasks (#55)
Description
No description provided
Languages
Rust
91.6%
Python
4.6%
C
1.8%
LLVM
1.6%
Shell
0.4%