Files
ww/test/lang/nonlit_tuple_widen_test.ww
Hojun-Cho 07b3c74ab0 test: migrate Fam8 tuple value tests to @test + reject carriers (#5-C2)
fold-2 chunk C2 (drew's Fam8-13 plan): 14 tuple value-row C drivers migrate to
15 test/lang/*_test.ww @test row-tables (the +1 is 954_tuprecv, slimmed not
deleted -- its value rows split out while the asserttyped-stamp dimension stays
as a carrier-split C pin, mutation-proven non-vacuous). Reject rows move to 32
test/wcc/data/*/case.ww //ww:error carriers (runww asserts the substring in
BOTH stages). The test-lang byte-id (LANGBYTEID) gate gives cs==ww automatically
and is strictly more sensitive than re-running the wwstage leg; floor 59->74.
Tuple surfaced zero cs!=ww as the plan predicted -- no value-only carve. The 945
trio folds in here; 940_global_sret / 940_str_forrange / 926_tagscr untouched
(routed to drew per-file). Test count 402->388 = the 14 retired drivers.
2026-06-24 01:44:13 +09:00

89 lines
2.5 KiB
Plaintext

// nonlit_tuple_widen_test — project #116: a NON-LITERAL tuple source widened
// into a tagged box (cg_widen_tagged_store / cgwidentaggedstore). Pre-#116 only a
// bare/cast tuple LITERAL carried a full payload into the union box; every
// ADDRESSABLE non-literal tuple source — a tuple IDENT var, a slice/array INDEX
// `tbl[i]`, a DEREF `*p` — hit the `else fatal` ("tuple-typed source shape
// unwired"), LOUD and IDENTICAL on both stages, blocking fold-6's
// `append(charsets[...], charclass_map[cc_idx])`. The fix resolves the source
// ADDRESS through cgplaceaddr and BLOCK-COPIES the tuple's table size into the
// box payload, stamping the variant tag. Byte-id is BLIND here (both stages were
// loud — #263), so the RUNTIME read-back is the correctness net: `len(x.0)`
// proves the str header rode over, `(*x.1)(arg)` indirect-calls the fn-ptr
// element. Migrated from test/wcc/944_nonlit_tuple_widen_run.c. The never-taken
// rune match arm -> assert(false) (the C original's `return 90`).
package nonlit_tuple_widen_test;
type ci = (str, *fn(c: rune) bool);
type u = (rune | ci);
fn fa(c: rune) bool = { return c == 'a'; };
fn fb(c: rune) bool = { return c == 'b'; };
@test fn literal() void = {
let nm: str = "ww";
let cf: *fn(c: rune) bool = &fa;
let s: []u = [];
append(s, ((nm, cf): ci));
match (s[0]) {
case let r: rune => { assert(false); };
case let x: ci => {
assert(!((len(x.0): i32) != 2));
assert(!(!(*x.1)('a')));
};
};
};
@test fn ident() void = {
let nm: str = "zz";
let cf: *fn(c: rune) bool = &fb;
let t: ci = (nm, cf);
let s: []u = [];
append(s, t);
match (s[0]) {
case let r: rune => { assert(false); };
case let x: ci => {
assert(!((len(x.0): i32) != 2));
assert(!(!(*x.1)('b')));
assert(!((*x.1)('a')));
};
};
};
@test fn index() void = {
let n0: str = "aa"; let c0: *fn(c: rune) bool = &fa;
let n1: str = "zzz"; let c1: *fn(c: rune) bool = &fb;
let t0: ci = (n0, c0);
let t1: ci = (n1, c1);
let tbl: [2]ci = [];
tbl[0] = t0;
tbl[1] = t1;
let s: []u = [];
append(s, tbl[1]);
match (s[0]) {
case let r: rune => { assert(false); };
case let x: ci => {
assert(!((len(x.0): i32) != 3));
assert(!(!(*x.1)('b')));
assert(!((*x.1)('a')));
};
};
};
@test fn deref() void = {
let nm: str = "qqq";
let cf: *fn(c: rune) bool = &fa;
let t: ci = (nm, cf);
let p: *ci = &t;
let s: []u = [];
append(s, *p);
match (s[0]) {
case let r: rune => { assert(false); };
case let x: ci => {
assert(!((len(x.0): i32) != 3));
assert(!(!(*x.1)('a')));
assert(!((*x.1)('b')));
};
};
};