; Iter 18d.3 — move-aware pattern bindings: let-close emits an
; inlined per-field dec sequence that skips moved slots and dec's
; non-moved (wildcarded) pointer-typed slots.
;
; Fixture shape:
;   - Pair carries two `IntList` fields (both pointer-typed).
;   - main builds a Pair, pattern-matches it binding only the FIRST
;     field, wildcarding the SECOND.
;   - The matched binding `a` is consumed by `sum_list`. The
;     wildcarded slot is logically retained by `p` (no binder owns
;     it), so at p's let-close it must be dec'd.
;
; Expected IR shape under --alloc=rc at p's let-close:
;   - NO `call void @drop_pat_extract_partial_drop_Pair(ptr <p>)`
;     (the uniform drop fn is replaced by inline partial drop)
;   - YES a `getelementptr ... ptr <p>, i64 16` + `load ptr` +
;     `call void @drop_pat_extract_partial_drop_IntList(ptr <slot1_v>)`
;     (slot 1 was NOT moved → emit per-field dec)
;   - YES `call void @ailang_rc_dec(ptr <p>)` (outer cell)
;   - NO load+dec for slot 0 (moved → skipped)
;
; Expected stdout: 6 (1 + 2 + 3 = 6, sum of the first list).

(module pat_extract_partial_drop

  (data IntList
    (doc "Recursive Int list — boxed.")
    (ctor Nil)
    (ctor Cons (con Int) (con IntList)))

  (data Pair
    (doc "Two IntLists side by side. Both fields are pointer-typed; the test exercises move-tracking against EACH slot independently.")
    (ctor Pair (con IntList) (con IntList)))

  (fn sum_list
    (doc "Consume xs, sum its elements.")
    (type
      (fn-type
        (params (own (con IntList)))
        (ret (own (con Int)))))
    (params xs)
    (body
      (match xs
        (case (pat-ctor Nil) 0)
        (case (pat-ctor Cons h t)
          (app + h (app sum_list t))))))

  (fn main
    (doc "Build Pair([1,2,3], [4,5,6]); pattern-bind first slot only; sum first list. The wildcarded second slot's IntList lives only inside the Pair box; closing the Pair's let scope must dec it (non-moved) while skipping the moved first slot.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let p
        (term-ctor Pair Pair
          (term-ctor IntList Cons 1
            (term-ctor IntList Cons 2
              (term-ctor IntList Cons 3
                (term-ctor IntList Nil))))
          (term-ctor IntList Cons 4
            (term-ctor IntList Cons 5
              (term-ctor IntList Cons 6
                (term-ctor IntList Nil)))))
        (match p
          (case (pat-ctor Pair a _)
            (app print (app sum_list a))))))))
