The wcc test drivers ran `ww build <bare-/tmp src>` with no -o, so the
compiler's <stem>.sepwork scratch landed beside the source and was never
cleaned: unbounded /tmp growth (2195 stale dirs observed) that fills tmpfs
and fabricates phantom test failures + silent harness aborts, and for
in-repo fixture builds leaked .sepwork into the tracked tree.
Each leaking build now writes its source + output inside a per-invocation
tmpdir, passes -o <tmpdir>/<stem> so the .sepwork lands inside it, and
rm -rf's the tmpdir on every exit path -- including fopen-fail and the
expected-fail reject builds (scratch is mkdir'd before the build can fail).
`ww run` and explicit-`-o`/byte-id helpers are left as-is; the 990/993
byte-id comparison logic is byte-for-byte unchanged.
Two items filed separately (this commit holds the no-Makefile / no-main.c
rail):
- #13: a stale <src>.s byte-id readback (749) silently no-ops since
separate-compile emits .s to <ostem>.sepwork/__root.s; documented inline.
- #14: build-system Makefile recipes build selfhost/cmd/*/main.ww with no
-o and leak main.sepwork in-tree (bounded, gitignored; own commit).
One concern -- sepwork leak hygiene -- across 228 drivers; uniform
transform applied per-file and two-round reviewed. make test: all 402
passed, zero net-new /tmp scratch, zero test-driven in-repo .sepwork.
A one-step `let xs: []T = [e0,e1,..]` had two faults. #31 (silent, cs!=ww):
the #258 array→slice borrow wrapped the un-addressable N_ARRLIT directly as
the N_SLICE base and cgen never spilled it to a stack slot, so .ptr dangled
(`let xs:[]i32=[10,20,30]; xs[1]` returned the un-stored header 1; []u8/[]str
segfaulted). #25 (over-strict): a slice target fell through to the exact-
element type_eq borrow gate, rejecting bare-int-width ([]u8=[1,2,3]) and str
elements the array-init path coerces.
Fix (re-stamp + per-borrow scratch; both stages byte-identical asm):
- Checker re-stamps the slice arrlit as [count]T, reusing the array-init
per-element coercion + range-check (#25): in-range accepts, out-of-range
loud-rejects. cstage arrlit_init_fits gains a TY_SLICE arm; wwstage
checkletassign mirrors it and stashes the synthesized [count]T tnode on
arrlit.lhs (free for N_ARRLIT) so cgen can size the backing NODE-wise
(elemsizeofc) and count from the tnode's .rhs intlit — the arrlit's own
value tinfo carries the literal's untyped element (unsized), so node-first
sizing is required (a cstage/wwstage representation divergence; cstage's
Type IS sized and reads base->type).
- cgen materialises the N_ARRLIT borrow base into a FRESH per-borrow
@slicescr stack slot (distinct slot per borrow: a borrow's backing must
outlive the lowering, so it can't share a cached @aggargscr/@tagscr-style
slot — two live borrows would alias one backing; localalloc/local_alloc
is always-fresh), filled by REUSING the array-init element fill extracted
from the N_LET path (cstage cg_arrlit_fill_bp, wwstage cgarrlitfillbp —
same store sequence the byte-id-green `let a:[N]T=[..]` uses, the
frame-order + store-op guarantee), then LEAQ'd as the base.
Supported ONLY at a `let` init. In call-arg / return / assign position
there is no addressable backing, so both stages LOUD-REJECT ("bind it to a
`let` first") — aligning cstage DOWN to wwstage (which already refused the
untyped arrlit element) per rule-10; this closes#31's silent call-arg
segfault as a compile error. Full non-let support is deferred (#33).
Escape (rule-8 WHY): a `let xs:[]T=[..]; return xs;` returns a slice into a
freed frame slot = dangling, IDENTICAL to the pre-existing named-array
borrow and Hare-consistent (no escape analysis / GC / heap promotion).
Test 953_arrlit_slice_run: 8 accept rows (cstage runtime readback +
cs==ww byte-id, frame-size canary incl.) covering the #31 i32 pin, bare-int→u8
coercion, str readback, the multi-live soundness pin (xs[0]+ys[0]=5, not 8 —
proves fresh-per-borrow), and a mutate-through-borrow proof; 4 reject rows
(out-of-range element + the three non-let contexts, loud in both stages).
Tuple-element slices stay blocked by the pre-existing #30 array-init FATAL.