diff --git a/test/wcc/928_str_abi_run.c b/test/wcc/928_str_abi_run.c index f28e7059..b68a1fb1 100644 --- a/test/wcc/928_str_abi_run.c +++ b/test/wcc/928_str_abi_run.c @@ -13,7 +13,10 @@ * AX/BX/CX value / AX:DX:CX:R8 tagged+tuple register layout: str * literal (cap=len), str arg, str return, str struct field, the * (i64,str) and (str,i64) tuple return shapes, deref-store `*p = s`, - * and []str index write+read. + * and []str index write+read. Phase 2 collapse folds (str IS []u8): + * str byte-index read `s[i]` (element stride via the type table, + * commit a5ca21d) and str widened into a tagged-union variant (the + * payload store folded onto the common slice arm, commit b416e71). * * Deliberately NOT covered here (known, separately-tracked gaps found * during Commit #1 review — both byte-identical across stages, so the @@ -142,6 +145,52 @@ static const struct row rows[] = { " return 0;\n" "};\n", 0 }, + /* str byte index read: `s[i]` strides by the u8 element size (1), + * routed through the type table post-collapse (a5ca21d). Guards + * the N_INDEX str-element stride against a slice-width (24B) + * miscompute now that str shares the slice path. */ + { "str_index_read", + "export fn main() i32 = {\n" + " let s: str = \"hello\";\n" + " if (s[0]: i32 != 104) { return 1; };\n" + " if (s[1]: i32 != 101) { return 2; };\n" + " if (s[4]: i32 != 111) { return 3; };\n" + " return 0;\n" + "};\n", + 0 }, + /* str widened into a tagged-union variant: the payload store + * folds onto the common slice arm (3-word ptr/len/cap @ + * slot+8/+16/+24 + tag, b416e71). Exercises literal, str-variable + * and a str returned from a fn into `(str | i64)`, plus the i64 + * arm so the variant-tag selection is checked both ways. */ + { "tagged_union_str_store", + "type sv = (str | i64);\n" + "fn wrap(s: str) sv = { return s; };\n" + "export fn main() i32 = {\n" + " let x: sv = \"hello\";\n" + " match (x) {\n" + " case let s: str => { if (s.len: i32 != 5) { return 1; }; };\n" + " case let n: i64 => { return 2; };\n" + " };\n" + " let a: str = \"world\";\n" + " let y: sv = a;\n" + " match (y) {\n" + " case let s: str => { if (s.len: i32 != 5) { return 3; }; };\n" + " case let n: i64 => { return 4; };\n" + " };\n" + " let z: sv = wrap(\"abcd\");\n" + " match (z) {\n" + " case let s: str => { if (s.len: i32 != 4) { return 5; }; };\n" + " case let n: i64 => { return 6; };\n" + " };\n" + " let w: sv = 42i64;\n" + " match (w) {\n" + " case let s: str => { return 7; };\n" + " case let n: i64 => { if (n: i32 != 42) { return 8; }; };\n" + " };\n" + " return 0;\n" + "};\n", + 0 }, }; static int