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.
121 lines
3.4 KiB
Plaintext
121 lines
3.4 KiB
Plaintext
// tuple_nary_destructure_test — project #83: the general N-ary tuple-
|
|
// destructure per-element register-return. The send (N_RETURN) and receive
|
|
// (N_MLET / N_MASSIGN) sites previously gated the 3-word {ptr,len,cap} store
|
|
// on a str-only XOR (e0_is_str ^ e1_is_str), which admitted EXACTLY ONE str
|
|
// element and was slice-BLIND: a tuple with a []u8 element fell to the
|
|
// scalar-pair fallback and silently DROPPED len+cap (only .ptr landed). The
|
|
// fix REPLACES the XOR with a positional per-element cursor (harec
|
|
// create_unpack_bindings, ref/harec/src/check.c:1354-1416): each element rides
|
|
// consecutive eightbytes over [AX,DX,CX,R8]; a slice/str rides its 3-word
|
|
// header, a scalar rides 1. SEND and RECEIVE walk the SAME cursor.
|
|
//
|
|
// Migrated from test/wcc/945_tuple_nary_destructure_run.c. Every wide row has
|
|
// cap!=len so a dropped len OR cap is caught; N_MASSIGN rows pre-poison the
|
|
// destination slot (distinct len/cap via a proven 3-word let-init copy) so a
|
|
// dropped len/cap reads the poison, never the test value. Each []u8 element
|
|
// borrows a str literal's .ptr (stable .rodata). Row F (slice_slice_recv) is
|
|
// the over-cap 6-eightbyte tuple that #10 Fold A sret's at the SEND and Fold B
|
|
// copies out at the RECEIVE — a working round-trip. cstage run is test-lang;
|
|
// cs==ww byte-id is test-lang-byteid (T2) — both dimensions survive.
|
|
|
|
package tuple_nary_destructure_test;
|
|
|
|
fn mk_mlet_islice() (i64, []u8) = {
|
|
let b: str = "hi";
|
|
let p: []u8; p.ptr = b.ptr; p.len = 2; p.cap = 5;
|
|
return (4i64, p);
|
|
};
|
|
|
|
fn mk_massign_islice() (i64, []u8) = {
|
|
let b: str = "hi";
|
|
let p: []u8; p.ptr = b.ptr; p.len = 2; p.cap = 5;
|
|
return (4i64, p);
|
|
};
|
|
|
|
fn mk_mlet_istr() (i64, str) = {
|
|
let p: str = "hi"; p.cap = 7i32;
|
|
return (4i64, p);
|
|
};
|
|
|
|
fn mk_massign_istr() (i64, str) = {
|
|
let p: str = "hi"; p.cap = 7i32;
|
|
return (4i64, p);
|
|
};
|
|
|
|
fn mk_str_control() str = {
|
|
let p: str = "hello"; p.cap = 9i32;
|
|
return p;
|
|
};
|
|
|
|
fn mk_massign_blank_wide() ([]u8, i64) = {
|
|
let b: str = "hi";
|
|
let p: []u8; p.ptr = b.ptr; p.len = 2; p.cap = 5;
|
|
return (p, 7i64);
|
|
};
|
|
|
|
fn mk_slice_slice_recv() ([]u8, []u8) = {
|
|
let a: []u8; a.len = 1; a.cap = 5;
|
|
let b: []u8; b.len = 2; b.cap = 6;
|
|
return (a, b);
|
|
};
|
|
|
|
@test fn mlet_islice() void = {
|
|
let (a, s) = mk_mlet_islice();
|
|
assert(a == 4);
|
|
assert(s.len: i32 == 2);
|
|
assert(s.cap: i32 == 5);
|
|
assert(s[0] == 104u8);
|
|
};
|
|
|
|
@test fn massign_islice() void = {
|
|
let qb: str = "zzzz";
|
|
let q: []u8; q.ptr = qb.ptr; q.len = 9; q.cap = 9;
|
|
let a: i64 = 0i64;
|
|
let s: []u8 = q;
|
|
a, s = mk_massign_islice();
|
|
assert(a == 4);
|
|
assert(s.len: i32 == 2);
|
|
assert(s.cap: i32 == 5);
|
|
assert(s[0] == 104u8);
|
|
};
|
|
|
|
@test fn mlet_istr() void = {
|
|
let (a, s) = mk_mlet_istr();
|
|
assert(a == 4);
|
|
assert(s.len: i32 == 2);
|
|
assert(s.cap: i32 == 7);
|
|
assert(s[0] == 104u8);
|
|
};
|
|
|
|
@test fn massign_istr() void = {
|
|
let q: str = "qqqq"; q.cap = 6i32;
|
|
let a: i64 = 0i64;
|
|
let s: str = q;
|
|
a, s = mk_massign_istr();
|
|
assert(a == 4);
|
|
assert(s.len: i32 == 2);
|
|
assert(s.cap: i32 == 7);
|
|
assert(s[0] == 104u8);
|
|
};
|
|
|
|
@test fn str_control() void = {
|
|
let s: str = mk_str_control();
|
|
assert(s.len: i32 == 5);
|
|
assert(s.cap: i32 == 9);
|
|
assert(s[0] == 104u8);
|
|
};
|
|
|
|
@test fn massign_blank_wide() void = {
|
|
let a: i64 = 0i64;
|
|
_, a = mk_massign_blank_wide();
|
|
assert(a == 7);
|
|
};
|
|
|
|
@test fn slice_slice_recv() void = {
|
|
let (x, y) = mk_slice_slice_recv();
|
|
assert(x.len: i32 == 1);
|
|
assert(x.cap: i32 == 5);
|
|
assert(y.len: i32 == 2);
|
|
assert(y.cap: i32 == 6);
|
|
};
|