// A []T (slice-typed) VALUE stored through a // WHOLE-deref lhs `*p = sliceval` must move the full 24B {ptr,len,cap} header // (ref/hare/rt/ensure.ha:4-8), not just {ptr}, migrated from // test/wcc/944_deref_slice_store_run.c (project #79). The `*p = v` deref-store // arm was kind-gated on str ONLY; a slice fell to the 1-word default and // silently DROPPED len+cap. str IS []u8 since Phase 2 (#1), so the str 3-word // stash+store machinery applies to slices verbatim; the fix widens the gate // from `str` to `str || slice`. SYMMETRIC across both stages (cs==ww, // byte-id-BLIND), so only a store->read ROUNDTRIP catches it. // // cap != len in every row so a dropped len OR cap is caught. package deref_slice_store_test; type box = struct { s: []u8 }; @test fn d_slice_direct() void = { // A — `*pp = p`, read back via the DIRECT local `dst`. dst is POISONED // first with a different slice q (len=4,cap=5) via a PROVEN 3-word store // (`dst = q`, NOT the site under test); a 1-word `*pp=p` leaves q's cap=5, // the fix lands 8. let hb: [8]u8; hb[0] = 104u8; let p: []u8; p.ptr = &hb[0]; p.len = 2; p.cap = 8; let qb: [8]u8; let q: []u8; q.ptr = &qb[0]; q.len = 4; q.cap = 5; let dst: []u8 = q; let pp: *[]u8 = &dst; *pp = p; assert(dst.cap: i32 == 8); assert(dst.len: i32 == 2); assert(dst[0] == 104u8); }; @test fn d_slice_thru() void = { // B — same store, read back THROUGH the pointer via the 3-word field-deref // read `(*pp).cap`/`.len` (already 3-word), confirming the stored header // survives a pointer-side read. let hb: [8]u8; hb[0] = 104u8; let p: []u8; p.ptr = &hb[0]; p.len = 2; p.cap = 8; let qb: [8]u8; let q: []u8; q.ptr = &qb[0]; q.len = 4; q.cap = 5; let dst: []u8 = q; let pp: *[]u8 = &dst; *pp = p; assert((*pp).cap: i32 == 8); assert((*pp).len: i32 == 2); }; @test fn d_str_control() void = { // C — control str-deref: the str arm the fix widens around must still land // len=5 (regression guard). Poison d="xy" then `*pp="hello"`. let d: str = "xy"; let pp: *str = &d; *pp = "hello"; assert(d.len: i32 == 5); }; @test fn d_field_control() void = { // D — control (*p).field: explicit-deref field store, a separate // already-3-word branch. `(*pb).s = p` into a struct{s:[]u8}. let hb: [8]u8; hb[0] = 104u8; let p: []u8; p.ptr = &hb[0]; p.len = 2; p.cap = 8; let b: box; let pb: *box = &b; (*pb).s = p; assert(b.s.cap: i32 == 8); assert(b.s.len: i32 == 2); assert(b.s[0] == 104u8); };