Harden the ownership analysis for universal activation (value-types + HOF application) #56
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Blocks #55 (delete the
ParamMode::Implicitownership default, specdocs/specs/0062-eliminate-implicit-mode.md).The discovery
Deleting
Implicitmakes every fn fully-moded, which turns the strict linearity check (consume-while-borrowed/use-after-consume,crates/ailang-check/src/linearity.rs) on universally for the first time. Today its activation gate (linearity.rs:339) skips any fn with a bare/Implicitparam — i.e. all but ~45 of 258 fn-bearing modules. The strict ownership analysis, the core safety feature, currently almost never runs.Evidence (measured 2026-06-01)
Temporarily materialising bare params as derived modes (
consume_count==0 → Borrow, elseOwn) and batch-checkingexamples/: 38 of ~182 functional fixtures (~21%) newly break, all withuse-after-consume. The real consume_count-derived rule breaks the SAME count as naive all-own, so the mode choice does not fix them. All are false positives, in two classes:n,i,depth,lo,x,d,sample—Int/Floatread multiple times. Value types have no refcount and are never consumed; multi-read is always legal. e.g.sum.ail:(fn sum (params n) (body (if (eq n 0) 0 (+ n (sum (- n 1)))))).finmap_int,fold_left,apply_thrice. Applying a function is a borrow, not a consume.None is real heap-data multi-consume needing
clone.Root cause
Spec 0062 handled the codegen side of value-types (trivial-own = no
dec) but not the check side: the linearity analysis still tracks a value-type or function param as consumable. TheImplicitgate has hidden these blind spots because the check almost never ran.Scope
Harden the linearity analysis for universal activation:
Int/Bool/Float/Unit(and decideStr) are never consumed; multi-use is always legal.use-after-consume.This is independently valuable — it makes the core ownership analysis sharp across the whole codebase for the first time, not just under the #55 cutover.
Open design questions for the spec
Stra value type (immutable, but heap-allocated) for consume-tracking purposes?ownparam = consume; but the recursion-passing pattern needs precise rules.depends on: nothing (precondition for #55)
context: discovered while de-risking #55; #55 cannot ship until this lands.