; Iter 18g.2 RED-test fixture: a let-binder whose value is the ; result of an Own-returning fn call. 18c.3's ; `is_rc_heap_allocated` predicate returns `false` for any ; `Term::App` shape (its doc-comment explicitly defers this case ; to "later iters tied to (own) ret-mode contracts"); we now have ; those contracts (Iter 18a), and the let-scope close should drop ; the binder. ; ; Surfaced by 18f.2 / 18g.1: `bench_latency_explicit`'s ; `(let t (app build_tree 19) ...)` leaks the entire depth-19 ; Tree (~1M cells) because `t` is not trackable. This minimal ; repro uses a 2-cell depth-1 tree. ; ; Pre-fix: live = 3 (TNode + 2 TLeaf children — the depth-1 ; tree). ; Post-fix: live = 0. (module rc_let_owned_app_leak (data Tree (ctor TLeaf) (ctor TNode (con Int) (con Tree) (con Tree))) (fn build (type (fn-type (params (own (con Int))) (ret (own (con Tree))))) (params d) (body (if (app eq d 0) (term-ctor Tree TLeaf) (term-ctor Tree TNode 1 (app build (app - d 1)) (app build (app - d 1)))))) (fn pin (type (fn-type (params (borrow (con Tree))) (ret (own (con Int))))) (params t) (body (match t (case (pat-ctor TLeaf) 0) (case (pat-ctor TNode v l r) 1)))) (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (let t (app build 1) (app print (app pin t))))))