Files
ww/test/lang/tuple_elem_slice_len_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

65 lines
1.9 KiB
Plaintext

// `len(t.N)` where t is a tuple and t.N is a
// slice/str-typed element, migrated from test/wcc/903_tuple_elem_slice_len_run.c
// (#235). The len() builtin special-cased only a PLAIN N_IDENT slice operand
// and an array operand; every other shape fell back to a bare `cgexpr(operand)`,
// which for a slice leaves AX=.ptr. A tuple-element read (`t.N`) loads only
// AX=.ptr, so `len(t.N)` returned the slice's .ptr word AS the length — a SILENT
// miscompile, gate-blind because the bootstrap never does len() on a
// slice-typed tuple element. The fix (both stages, byte-id) loads the element's
// .len word directly at BP + tuple_off + element_off + 8. Every element has a
// DISTINCT length so a dropped/wrong field is caught. Tuples are slice/str-ONLY
// here — a leading scalar element exercises a separate mixed-tuple sret
// divergence (filed apart, out of scope).
package tuple_elem_slice_len_test;
fn mk2() ([]u8, []u8) = {
let a: []u8; a.len = 3; a.cap = 7;
let b: []u8; b.len = 5; b.cap = 9;
return (a, b);
};
fn mk3() ([]u8, []u8, []u8) = {
let a: []u8; a.len = 3; a.cap = 7;
let b: []u8; b.len = 5; b.cap = 9;
let c: []u8; c.len = 11; c.cap = 13;
return (a, b, c);
};
fn mksb() (str, []u8) = {
let s: str = "abcd";
let b: []u8; b.len = 6; b.cap = 8;
return (s, b);
};
fn mkbs() ([]u8, str) = {
let b: []u8; b.len = 7; b.cap = 9;
let s: str = "hi";
return (b, s);
};
@test fn two_slice() void = {
let t: ([]u8, []u8) = mk2();
assert(len(t.0): i32 == 3);
assert(len(t.1): i32 == 5);
};
@test fn three_slice() void = {
let t: ([]u8, []u8, []u8) = mk3();
assert(len(t.0): i32 == 3);
assert(len(t.1): i32 == 5);
assert(len(t.2): i32 == 11);
};
@test fn str_slice() void = {
let t: (str, []u8) = mksb();
assert(len(t.0): i32 == 4);
assert(len(t.1): i32 == 6);
};
@test fn slice_str() void = {
let t: ([]u8, str) = mkbs();
assert(len(t.0): i32 == 7);
assert(len(t.1): i32 == 2);
};