Files
ww/test/lang/subslice_cap_test.ww
Hojun-Cho 83f5956df2 test: banner purge + WHY-only comment sweep (rule 8)
Every section banner dies (103 -> 0) across test/lang, the observer
suites, the C carriers, and the five comment-heavy corpus fixtures;
banner provenance (#N cites, carrier numbers, repair-cluster labels)
folded into headers or adjacent WHY comments. Narration deleted; row
provenance, ref cites, divergence pins, and layout contracts kept
(fwd-ref decl-order guards and bootstrap-gate corpus rationale
restored where the sweep over-cut). Comment-only proven: all 3742
wwbuild workdir .s byte-identical before/after; test-commit and
test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
2026-08-08 21:40:23 +09:00

77 lines
2.6 KiB
Plaintext

// 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);
};