test(codegen): ignored RED pin for match-arm consume-split leak (#63 leg 3)
The third and final identified leg of #63: an owned heap param consumed on one match arm but live on a sibling fall-through arm is never dropped, because both codegen drop sites (the fn-return Own-param dec in lib.rs and the pre-tail-call dec in match_lower.rs) gate on the per-fn AGGREGATE consume_count. When the param is consumed on one arm (aggregate >= 1) but live on another, the gate skips the drop on the live arm too. This is the residual that keeps examples/series_sma.ail at live=2 after legs 1 and 2. Series-free minimal repro (a `Box` consumed on the `On` arm, live on the `Off` fall-through arm; main takes the `Off` path): `live=1` today. Committed #[ignore]: unlike legs 1 and 2, this is NOT a contained fix. The per-arm/per-path consume information is destroyed by the worst-case `max` merge in uniqueness.rs (`merge_states`) before MIR — MArm carries only {pat, body}, MirDef.consume is the per-fn aggregate — so codegen has no per-arm liveness to gate a fall-through drop on. Closing it needs a memory-model change (retain per-arm consume, surface it to codegen, emit the drop only on the live arm, never at the post-match join or the consuming arm — a live double-free hazard) and a fresh brainstorm cycle. The pin is committed ignored so the precise symptom and minimal repro are durable; un-ignore when the fix ships. The assertion is a correct symptom pin (live == 0); only the fix mechanism is undecided. refs #63
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
(module match_arm_consume_split_no_leak_pin
|
||||
(data Box (ctor B (con Int)))
|
||||
(data Flag (ctor On) (ctor Off))
|
||||
(fn sink
|
||||
(type (fn-type (params (own (con Box))) (ret (own (con Unit))) (effects IO)))
|
||||
(params b)
|
||||
(body (match b (case (pat-ctor B n) (do io/print_str "x")))))
|
||||
(fn run
|
||||
(type (fn-type (params (own (con Box)) (own (con Flag))) (ret (own (con Unit))) (effects IO)))
|
||||
(params b f)
|
||||
(body
|
||||
(match f
|
||||
(case (pat-ctor Off) (do io/print_str ""))
|
||||
(case (pat-ctor On) (app sink b)))))
|
||||
(fn main
|
||||
(type (fn-type (params) (ret (own (con Unit))) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(let b (term-ctor Box B 7)
|
||||
(seq
|
||||
(app run b (term-ctor Flag Off))
|
||||
(do io/print_str "done\n"))))))
|
||||
Reference in New Issue
Block a user