flan/test/programs/pool-stale-region.flan
Joseph Ferano 0837959140 Six refusals and a trap, each one a way of losing the property
The refusals: the arities, a pool of an owning element, ordering handles,
free of a handle, and clone of a pool. Each names what it would cost — a
cloned pool duplicates the generation counters with the slots, so one handle
would resolve in both copies and name two different things.

pool-stale-region.flan is the other failure, and the point of it is that it
is not the first. A stale handle is an answer and resolve says None; a pool
whose region was released has no slot array left to ask, so it traps. Same
rule that keeps a Vec's generation word and its epoch word apart.
2026-09-13 07:59:04 +07:00

26 lines
1.1 KiB
Plaintext

;;;; The epoch trap on the pool's side. spec-memory.md, "Dev builds detect a
;;;; released region".
;;;;
;;;; This is deliberately the *other* failure from a stale handle, and the two
;;;; must not be conflated — the same rule that keeps a Vec's generation word
;;;; and its epoch word apart. A stale handle is an answer: the entity died,
;;;; resolve says None, the program carries on. A released region is not an
;;;; answer at all: the storage the pool sits in is gone, the slot array with
;;;; it, and there is nothing left to ask. So one returns None and the other
;;;; traps naming the site.
(defn main [] i32
(let [a (arena-new 4096)]
(let [p (pool-new i32 a)]
(let [h (insert p 7)]
(match (resolve p h)
(Some x) (println (deref x))
None (println -1))
;; The region goes. p is still in scope, still looks fine, and h is
;; still a perfectly well-formed handle — which is exactly the case a
;; static rule cannot see.
(free-all a)
(match (resolve p h)
(Some x) (println (deref x))
None (println -1)))))
0)