// subslice_cap_test — a sub-slice `base[lo:hi]` must set its capacity word to // base_cap - lo (storage remaining to the underlying end; Go/Hare-identical), // NOT hi - lo (the new length), migrated from test/wcc/942_subslice_cap_run.c // (task #20). base_cap is the array length N for [N]T, or the carried .capacity // for a slice/str base. Cite (drew): harec ref/harec/src/eval.c:1017 (slice cap // -= start), eval.c:1024 (array cap = length - start), check.c:596 (cap>=len), // ref/hare/rt/ensure.ha:4-8 (capacity is a distinct field). // // Before the fix BOTH stages emitted cap = hi - lo (== len). Every row picks a // shape where base_cap - lo != hi - lo, so a stale `cap = len` stage is // observably wrong (cap reads hi-lo, or the append row reallocs instead of // filling the base's spare). cap != len in every row. package subslice_cap_test; @test fn subslice_array_hilt_n() void = { // A — array base, hi < N. cap = N(8) - lo(1) = 7 != len(2). let a: [8]u8; let i: i32 = 0; for (i < 8) { a[i] = (20 + i): u8; i += 1; }; let s: []u8 = a[1:3]; assert(s.cap: i32 == 7); assert(s.len: i32 == 2); assert(s[0] == 21u8); }; @test fn subslice_slice_spare_cap() void = { // B — slice base with spare cap. cap = base.cap(8) - lo(1) = 7 != len(3); // base.cap is read from the header +16, not re-derived. let a: [8]u8; let i: i32 = 0; for (i < 8) { a[i] = (40 + i): u8; i += 1; }; let p: []u8; p.ptr = &a[0]; p.len = 6; p.cap = 8; let s: []u8 = p[1:4]; assert(s.cap: i32 == 7); assert(s.len: i32 == 3); assert(s[0] == 41u8); }; @test fn subslice_str_base() void = { // C — str base (str[lo:hi] yields str, real .capacity, no downgrade). // cap = sb.cap(5) - lo(1) = 4 != len(2). let sb: str = "hello"; let s: str = sb[1:3]; assert(s.cap: i32 == 4); assert(s.len: i32 == 2); assert(s[0] == 101u8); }; @test fn subslice_append_no_realloc() void = { // D — append-no-realloc (strongest). s = buf[1:3] has cap 7 > len 2, so // append(s,99) fills buf's spare at lo+len = 3. A cap=len stage sees // len==cap (full) and reallocs, leaving buf[3] == 0. let buf: [8]u8; let i: i32 = 0; for (i < 8) { buf[i] = 0u8; i += 1; }; let s: []u8 = buf[1:3]; append(s, 99u8); assert(s.cap: i32 == 7); assert(s.len: i32 == 3); assert(s[2] == 99u8); assert(buf[3] == 99u8); }; @test fn subslice_hidefault_spare_cap() void = { // E — hi-default with spare cap. p{len=6,cap=8}; `p[2:]` defaults hi to // base.len=6, so len = 4, but cap = base.cap(8) - lo(2) = 6 != len. let a: [8]u8; let i: i32 = 0; for (i < 8) { a[i] = (60 + i): u8; i += 1; }; let p: []u8; p.ptr = &a[0]; p.len = 6; p.cap = 8; let s: []u8 = p[2:]; assert(s.cap: i32 == 6); assert(s.len: i32 == 4); assert(s[0] == 62u8); };