1be6e49b4f
An owned heap ADT param threaded through a tail-recursive fn whose base-case arm neither forwards nor consumes it is never RC-dec'd, so it leaks one slab per recursion step. Series-free minimal repro (a plain `Box` ADT, no Series/RawBuf), so the pin guards the GENERAL memory-model invariant rather than the Series surface that first surfaced it (examples/series_sma.ail, live=8). The pin builds the fixture with --alloc=rc, runs it under AILANG_RC_STATS=1, and asserts live == 0 (allocs == frees). RED today: `allocs=6 frees=4 live=2`. The fixture passes the replacement ctor directly into the tail call (not let-bound) to isolate leg 1 — the owned-param drop omission — from the second, distinct leg the debugger found (a `let`-wrapped tail call also defeats the scrutinee-husk shallow-dec gate; that leg is what pushes box_ctrl to live=4 and series_sma to live=8, and gets its own pin once leg 1 is green). Cause (debugger, for the GREEN side): the fn-return Own-param dec in crates/ailang-codegen/src/lib.rs (~1444) is gated behind `!block_terminated`, so it fires only on the fall-through ret path; crates/ailang-codegen/src/match_lower.rs (~805) drops only pattern binders, never the fn's owned params. A tail-call-terminated match arm thus has no drop site for an owned param with consume_count==0 that is not forwarded into the tail call. refs #63
18 lines
691 B
Plaintext
18 lines
691 B
Plaintext
(module tail_recur_owned_param_no_leak_pin
|
|
(data Box (ctor B (con Int)))
|
|
(data IntList (ctor INil) (ctor ICons (con Int) (con IntList)))
|
|
(fn run
|
|
(type (fn-type (params (own (con Box)) (own (con IntList))) (ret (own (con Unit))) (effects IO)))
|
|
(params b input)
|
|
(body
|
|
(match input
|
|
(case (pat-ctor INil) (do io/print_str "done\n"))
|
|
(case (pat-ctor ICons v rest)
|
|
(tail-app run (term-ctor Box B v) rest)))))
|
|
(fn main
|
|
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
|
(params)
|
|
(body
|
|
(let b (term-ctor Box B 0)
|
|
(app run b (term-ctor IntList ICons 1 (term-ctor IntList ICons 2 (term-ctor IntList INil))))))))
|