; Iter 18d.4 regression fixture: under --alloc=rc, codegen's
; "pattern-binder dec at arm close" (Iter A) was firing on
; pattern-bound pointer fields whose enclosing fn is Implicit-
; mode. Result: a free of memory the caller still references.
;
; Symptom under --alloc=rc before the fix:
;   - Implicit-mode pin/loop: refcount underflow at runtime.
;   - Post-fix: clean exit, prints `0`.
;
; Pattern shape: a heap-allocated value `t` shared between a
; callee that pattern-destructures it (pin) and a recursive
; call that re-passes it (loop). Pattern arm binds the children
; (l, r) without consuming them — pre-fix, codegen emitted a
; drop on each, freeing memory still referenced via the outer
; let-binder `t`.

(module rc_pin_recurse_implicit

  (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 loop
    (type (fn-type (params (own (con Int)) (borrow (con Tree))) (ret (own (con Int)))))
    (params n t)
    (body
      (if (app eq n 0)
        0
        (let _v (app pin t)
          (app loop (app - n 1) t)))))

  (fn main
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let t (app build 2)
        (app print (app loop 3 t))))))
