; Iter 18g.tidy.fu2 RED-test fixture 3/3: dynamic-tag partial-drop ; carve-out at let-close for an App-bound binder ; (drop.rs:580 fallback in `emit_inlined_partial_drop`). ; ; Shape: ; - Same `Pair`/`Cell`/`Wrap` types as fixtures 1 and 2. ; - `main` let-binds `p = (app build_pair)` — value is ; `Term::App` (Own-returning), `is_rc_heap_allocated` returns ; true → trackable. ; - Body matches `p` as `MkPair a _` — slot 0 bound, slot 1 wild. ; `moved_slots[p] = {0}`. ; - `a` is consumed by `use_cell` (Own param) → `consume_count[a] ; == 1`, arm-close drop skipped. `use_cell`'s body fully ; destructures `a` and returns Int. ; - At p's let-close: `consume_count[p] == 0`, `moves[p] = {0}` ; non-empty, `value` is `Term::App` (not `Term::Ctor`) → ; `emit_inlined_partial_drop` falls into the non-Ctor branch ; (drop.rs:580) → shallow `ailang_rc_dec(p)`. p's outer cell ; is freed; slot 1 (the second MkCell + its two MkWraps = ; 3 cells) leaks. ; ; Pre-fix: live = 3 (one MkCell + two MkWrap children in slot 1). ; Post-fix: live = 0. (module rc_app_let_partial_drop_leak (data Wrap (ctor MkWrap (con Int))) (data Cell (ctor MkCell (con Wrap) (con Wrap))) (data Pair (ctor MkPair (con Cell) (con Cell))) (fn build_pair (type (fn-type (params (con Int)) (ret (own (con Pair))))) (params n) (body (term-ctor Pair MkPair (term-ctor Cell MkCell (term-ctor Wrap MkWrap n) (term-ctor Wrap MkWrap 2)) (term-ctor Cell MkCell (term-ctor Wrap MkWrap 3) (term-ctor Wrap MkWrap 4))))) (fn use_cell (type (fn-type (params (own (con Cell))) (ret (con Int)))) (params c) (body (match c (case (pat-ctor MkCell w1 w2) 1)))) (fn main (type (fn-type (params) (ret (con Unit)) (effects IO))) (params) (body (let p (app build_pair 1) (do io/print_int (match p (case (pat-ctor MkPair a _) (app use_cell a))))))))