; Iter 18d.4 — Own-param dec at fn return. ; ; Companion fixture to `alloc_rc_borrow_only_recursive_list_drop`. ; Here the static "caller handed off ownership" signal is the ; explicit `(own (con IntList))` parameter mode on `head_or_zero`. ; Under --alloc=rc, codegen now emits a drop call against the ; param SSA (`%arg_xs`) before the fn's `ret`, closing the ; symmetric debt 18c.3/18c.4 carried. ; ; Fixture shape: ; - `head_or_zero` takes `(own (con IntList))` and returns Int. ; Body destructures via match, returns the head in the Cons ; arm (ignoring the tail) and 0 in the Nil arm. ; - `xs` (the param) has consume_count == 0 (only borrow at ; match scrutinee). Iter B fires: param drop at fn return. ; - `t` (Cons-arm pattern binder) has consume_count == 0 (the ; arm body just returns `h` — `t` is unused). Iter A fires: ; drop__IntList(t) at arm close, freeing the tail chain ; before the fn returns. ; - At fn return, moved_slots[xs] = {1} (Cons.t was moved into ; the arm-bound `t` and dec'd by iter A). Iter B falls back ; to shallow `ailang_rc_dec(%arg_xs)` — the dynamic-tag ; partial-drop case is debt; for the canonical Cons-or-Nil ; dispatch here, dec'ing the outer cell only is correct ; because the active ctor's only ptr field (Cons.tail) is ; already freed by iter A, and Nil has no ptr fields. ; ; Expected stdout under --alloc=rc / --alloc=gc: 11 (head of the ; 5-element list). (module rc_own_param_drop (data IntList (doc "Recursive Int list — boxed.") (ctor Nil) (ctor Cons (con Int) (con IntList))) (fn head_or_zero (doc "Take ownership of an IntList; return its head if Cons, else 0. The tail is loaded as a pattern binder but never consumed — iter A dec's it at arm close. The outer cell is dec'd at fn return via iter B's Own-param emission.") (type (fn-type (params (own (con IntList))) (ret (con Int)))) (params xs) (body (match xs (case (pat-ctor Nil) 0) (case (pat-ctor Cons h t) h)))) (fn main (doc "Build a 5-element IntList; pass to head_or_zero (transferring ownership); print the result.") (type (fn-type (params) (ret (con Unit)) (effects IO))) (params) (body (let xs (term-ctor IntList Cons 11 (term-ctor IntList Cons 22 (term-ctor IntList Cons 33 (term-ctor IntList Cons 44 (term-ctor IntList Cons 55 (term-ctor IntList Nil)))))) (do io/print_int (app head_or_zero xs))))))