Consuming a heap sub-binder of a borrowed scrutinee is accepted -> double-free #58
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?
Symptom
The strict linearity check does NOT reject consuming a heap pattern sub-binder extracted from a
borrow-mode match scrutinee. The sub-binder aliases caller-owned heap, so consuming it (passing it to anownparam) double-frees.Surfaced by fieldtest spec
docs/specs/0065-fieldtest-eliminate-implicit-mode.md(cut55_2c) post-#55 cutover. NOT introduced by #55 — the cutover's universal activation of the strict check exposed a pre-existing hole the corpus never exercised.Repro
ail check-> ok, exit 0 (WRONG: should fireconsume-while-borrowedont).ail build+ run -> exit 139 (SIGSEGV, double-free of the freed tail on the secondleak).AILANG_RC_STATS=1masks the crash (exit 0) — same divergence as the #55 drop legs.Root hypothesis
A
borrow-mode match scrutinee's pattern sub-binders that are heap-typed must INHERIT borrowed status, so consuming them firesconsume-while-borrowed. The linearity pass (crates/ailang-check/src/linearity.rs) currently catches the whole-param consume (cut55_2d, correctly rejected) but not the moved-out heap sub-binder. Sibling to the #57 (spec 0064) class-2 let-alias-of-borrow hardening; this is the pattern-sub-binder analog. RED-first.Note
Value-typed sub-binders (an Int
h) are fine to consume (copied, no heap alias) — only HEAP sub-binders of a borrowed scrutinee are the hole.