w6c+w6c_ww: tuple-let receive keyed on type classify, not producer shape (C-t1, #33)
wwstage cglet's tuple receive was producer-SHAPE-keyed: the mixed str/scalar arm required s0_is_str != s1_is_str (syntactic) and the rt16 arm required an N_CALL rhs (rettupleof), so a scalar-scalar tuple LITERAL `let t: (u32,u32) = (3,4)` matched neither and fell to the generic single-word store — word 1 silently dropped (#209/#211-class syntactic-vs-type keying). cstage's twin arm was sz==16/32 magic-size keyed, so 24B 3-scalar tuples dropped words 2+ on BOTH sources. Both stages now key the same way: declared-type TY_TUPLE + in-cap register classify (cg_sret_retsize / sretretsize == 0, the shared SSoT), alias-peeled; the two wwstage shape arms collapse into one type-keyed arm walking the declared element list (the #240 lesson — never the producer's). Over-cap falls through to the sret receive exactly as before; unannotated `let t = f()` rides inferletcalltype. 941 grows the t1 rows: lit packed/16B/3-scalar + call 3-scalar fail at the C-t0 parent (10/39 checks — wwstage lit halves AND both-stage 24B halves), mixed-lit + unannotated-call anchor the untouched paths. Filed while probing: cstage silently accepts an over-cap tuple-LITERAL let where wwstage loud-stops (pre-existing at master, task #64).
This commit is contained in:
@@ -163,6 +163,75 @@ static const struct row rows[] = {
|
||||
" if (b != 4) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
|
||||
/* ---- C-t1 (#33): the let RECEIVE re-keyed onto the declared
|
||||
* type's register classify. Pre-C-t1 wwstage keyed on producer
|
||||
* SHAPE (mixed-str syntactic / rettupleof N_CALL) so a
|
||||
* scalar-scalar LITERAL matched neither and dropped word 1;
|
||||
* cstage keyed on sz==16/32 so 24B 3-scalar shapes dropped words
|
||||
* on BOTH sources. ---- */
|
||||
{ "t1_lit_packed",
|
||||
"package main;\n"
|
||||
"fn second() u32 = {\n"
|
||||
" let t: (u32, u32) = (3, 4);\n"
|
||||
" if (t.0 != 3) { return 99; };\n"
|
||||
" return t.1;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" if (second() != 4) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
{ "t1_lit_16",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t: (i64, i64) = (3, 4);\n"
|
||||
" if (t.0 != 3) { return 1; };\n"
|
||||
" if (t.1 != 4) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
{ "t1_lit_mixed",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t: (i64, str) = (12, \"wxyz\");\n"
|
||||
" if (t.0 != 12) { return 1; };\n"
|
||||
" if (len(t.1) != 4) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
{ "t1_lit_3scalar",
|
||||
"package main;\n"
|
||||
"fn second() i64 = {\n"
|
||||
" let t: (i64, i64, i64) = (3, 4, 5);\n"
|
||||
" if (t.0 != 3) { return -1; };\n"
|
||||
" if (t.1 != 4) { return -2; };\n"
|
||||
" return t.2;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" if (second() != 5) { return 1; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
{ "t1_call_3scalar",
|
||||
"package main;\n"
|
||||
"fn f() (i64, i64, i64) = {\n"
|
||||
" return (7, 8, 9);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t: (i64, i64, i64) = f();\n"
|
||||
" if (t.0 != 7) { return 1; };\n"
|
||||
" if (t.1 != 8) { return 2; };\n"
|
||||
" if (t.2 != 9) { return 3; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
{ "t1_call_noannot_neutral",
|
||||
"package main;\n"
|
||||
"fn f() (i64, i64) = {\n"
|
||||
" return (3, 4);\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let t = f();\n"
|
||||
" if (t.0 != 3) { return 1; };\n"
|
||||
" if (t.1 != 4) { return 2; };\n"
|
||||
" return 0;\n"
|
||||
"};\n", 0 },
|
||||
};
|
||||
|
||||
/* build+run via a driver (ww / ww_ww); returns 0 pass, nonzero fail. */
|
||||
|
||||
Reference in New Issue
Block a user