; RED fixture (refs #55, Implicit-cutover husk leak — leg B, Nil sub-case).
;
; Property under test: an owned scrutinee threaded through the
; lit-sub-pattern chain desugar must have its OUTER cell freed
; exactly once on EVERY return path — including the path that
; matches the Nil arm and touches neither inner re-match.
;
; `first_or_default` has a lit sub-pattern arm `(Cons (pat-lit 0) _)`,
; so the 16c desugar (crates/ailang-core/src/desugar.rs `desugar_match`)
; is forced off the `is_flat` fast-path: it let-binds the owned
; scrutinee `xs` into a fresh `$mp` var and lowers the arms to a chain
; of single-level matches over `$mp`. Two breakages follow once the
; param mode is `Own` (post-#55 cutover):
;   1. the `Let $mp = xs` consumes `xs` (consume_count := 1), which
;      trips the codegen fn-return gate `if consume_count != 0 {
;      continue }` (crates/ailang-codegen/src/lib.rs ~1522) and
;      SUPPRESSES the husk free that the equivalent single-match fn
;      (e.g. std_list List_map) emits as `partial_drop_<T>(arg_xs, 2)`;
;   2. the husk obligation moves to the internal `$mp` binder, which the
;      gate (it iterates `f.params` only) never inspects.
; Net effect: the outer cell of `xs` is never freed.
;
; This fixture isolates the Nil path specifically: `main` calls
; `first_or_default` with a bare `(IntList Nil)`. That path returns -1
; and flows entry -> Nil-arm -> fn-return join, touching neither inner
; Cons re-match. The Nil cell (one 8-byte alloc) leaks -> live=1.
; The companion fixture lit_pat_ctor_tail_drop.ail covers the Cons
; path; this one pins the distinct Nil path so a Cons-only fix cannot
; pass while still leaking Nil husks.

(module lit_pat_nil_scrutinee_drop

  (data IntList
    (ctor Nil)
    (ctor Cons (con Int) (con IntList)))

  (fn first_or_default
    (doc "Empty -> -1; first element 0 -> 0; otherwise the head.")
    (type (fn-type (params (borrow (con IntList))) (ret (own (con Int)))))
    (params xs)
    (body
      (match xs
        (case (pat-ctor Nil) -1)
        (case (pat-ctor Cons (pat-lit 0) _) 0)
        (case (pat-ctor Cons h _) h))))

  (fn main
    (doc "Drive the Nil scrutinee only. Expected output: -1.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (seq (app print (app first_or_default (term-ctor IntList Nil))) (do io/print_str "\n")))))
