Summary
Heap-boxing primitives accept ephemeral type arguments, letting a borrowed view escape onto the heap with no diagnostic. The type-erased copy (via &raw const value + with_memcpy) hides the escape from effect analysis (the by-value param is classified read-only), so neither Box.new[T] nor std.ffi.box_ctx[T] rejects an ephemeral T.
Repro
type StrView = ephemeral { s: &str }
fn main:
let owned = "hello"
let v = StrView { s: owned }
let b = Box.new(v) // compiles; borrow now lives on the heap past its scope
Impact
Boxing a borrow-holding ephemeral produces a dangling reference once the borrow's scope ends. Noted in #436 (test plan called for err_ffi_box_ephemeral); the gap is shared with Box.new, so enforcing it only for box_ctx would be inconsistent. A principled fix should reject ephemeral T at both heap-boxing entry points.
Summary
Heap-boxing primitives accept ephemeral type arguments, letting a borrowed view escape onto the heap with no diagnostic. The type-erased copy (via
&raw const value+with_memcpy) hides the escape from effect analysis (the by-value param is classified read-only), so neitherBox.new[T]norstd.ffi.box_ctx[T]rejects an ephemeralT.Repro
Impact
Boxing a borrow-holding ephemeral produces a dangling reference once the borrow's scope ends. Noted in #436 (test plan called for
err_ffi_box_ephemeral); the gap is shared withBox.new, so enforcing it only forbox_ctxwould be inconsistent. A principled fix should reject ephemeralTat both heap-boxing entry points.