; RED-pin fixture for leg (C) of the drop-soundness bug family the
; Implicit-cutover (#55) surfaced: a polymorphic ctor's drop fn
; rc_dec's a type-parameter field even when that field is
; monomorphised at a value type (Int).
;
; `Box a` is the minimal single-field box. `unbox` takes the box by
; `own` and matches it, extracting the inner value `x` and returning
; it. The match consumes the box husk, so codegen emits the
; scope-close drop `drop_drop_value_field_no_segfault_pin_Box(box)`.
; That drop fn is emitted ONCE from the polymorphic declaration; the
; field type is the type-var `a`, which `llvm_type` cannot lower, so
; drop.rs's `.unwrap_or_else(|_| "ptr")` treats it as a boxed pointer
; and emits `ailang_rc_dec` on it.
;
; At the `Box Int` monomorph the field holds the raw i64 `7` stored
; inline (offset 8), NOT a heap pointer. `ailang_rc_dec(7)`
; dereferences address 7 -> SIGSEGV. Expected post-fix: prints `7`,
; exits 0, AILANG_RC_STATS reports `allocs == frees && live == 0`
; (the one Box slab is freed exactly once; no spurious dec of the
; inline value field).

(module drop_value_field_no_segfault_pin

  (data Box (vars a)
    (doc "Single-field polymorphic box.")
    (ctor MkBox a))

  (fn unbox
    (doc "Consume the box by own, return its inner value. The match drops the box husk.")
    (type
      (forall (vars a)
        (fn-type
          (params (own (con Box a)))
          (ret (own a)))))
    (params b)
    (body
      (match b
        (case (pat-ctor MkBox x) x))))

  (fn main
    (doc "Build MkBox 7 at Int, unbox it (drops the Box husk), print the result.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body (app print (app unbox (term-ctor Box MkBox 7))))))
