test: migrate dotfield/idxfield compound-assign to @test + runww rejects, retire C twins (fold-3)

949_dotfield_compound + 949_idxfield_compound are one bug class (#133-lineage compound-assign load-op-store on field lvalues; #34/#33, #263 carve-out) sharing the combine + hard-error path, so the two C carriers fuse into one commit: 26 value rows -> test/lang @test row-tables (primitive-only asserts), 8 reject rows -> runww //ww:error dual-stage carriers. byteid floor 50->52.
This commit is contained in:
2026-06-22 16:34:33 +09:00
parent af3c49a4c7
commit 057e805cf0
13 changed files with 354 additions and 778 deletions

View File

@@ -0,0 +1,14 @@
//ww:error "single-dot field compound on float field"
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_float"
// (#34/rule-7): a compound assign on a single-dot FLOAT field is unwired in
// both stages and MUST loud-fail, not silently demote to a plain store. The
// substring is the shared diagnostic body — byte-identical on both stages,
// pinned to "float field" so it cannot also match the str/slice/tagged rows
// (no file:line, no cstage "ww: " prefix — both differ cs vs ww).
package main;
type S = struct { f: f64, g: int };
export fn main() i32 = {
let s: S = S{f=1.0, g=0};
s.f *= 2.0;
return 0;
};

View File

@@ -0,0 +1,15 @@
//ww:error "single-dot field compound on slice field"
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_slice"
// (#34/rule-7): a compound assign on a single-dot SLICE field is unwired in
// both stages and MUST loud-fail. The substring is the shared diagnostic body
// — byte-identical on both stages, pinned to "slice field" so it cannot also
// match the float/str/tagged rows (no file:line, no cstage "ww: " prefix —
// both differ cs vs ww).
package main;
type S = struct { f: []u8, g: int };
export fn main() i32 = {
let b: [2]u8 = [1u8, 2u8];
let s: S = S{f=b[0:2], g=0};
s.f += b[0:1];
return 0;
};

View File

@@ -0,0 +1,14 @@
//ww:error "single-dot field compound on str field"
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_str"
// (#34/rule-7): a compound assign on a single-dot STR field is unwired in both
// stages and MUST loud-fail. The substring is the shared diagnostic body —
// byte-identical on both stages, pinned to "str field" so it cannot also match
// the float/slice/tagged rows (no file:line, no cstage "ww: " prefix — both
// differ cs vs ww).
package main;
type S = struct { f: str, g: int };
export fn main() i32 = {
let s: S = S{f="a", g=0};
s.f += "x";
return 0;
};

View File

@@ -0,0 +1,14 @@
//ww:error "single-dot field compound on tagged field"
// Lifted from test/wcc/949_dotfield_compound_run.c reject row "dotfld_he_tagged"
// (#34/rule-7): a compound assign on a single-dot TAGGED-union field is unwired
// in both stages and MUST loud-fail. The substring is the shared diagnostic
// body — byte-identical on both stages, pinned to "tagged field" so it cannot
// also match the float/str/slice rows (no file:line, no cstage "ww: " prefix —
// both differ cs vs ww).
package main;
type S = struct { f: (i32|str), g: int };
export fn main() i32 = {
let s: S = S{f=1, g=0};
s.f += 3;
return 0;
};

View File

@@ -0,0 +1,14 @@
//ww:error "arr[i].field compound on float field"
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_float"
// (#33/rule-7): a compound assign on an indexed-element FLOAT field is unwired
// in both stages and MUST loud-fail, not silently fall through. The substring
// is the shared diagnostic body — byte-identical on both stages, pinned to
// "float field" so it cannot also match the str/slice/tagged rows (no
// file:line, no cstage "ww: " prefix — both differ cs vs ww).
package main;
type S = struct { f: f64, g: i32 };
export fn main() i32 = {
let xs: [2]S = [S{f=1.0, g=0}, S{f=0.0, g=0}];
xs[0].f /= 2.0;
return 0;
};

View File

@@ -0,0 +1,15 @@
//ww:error "arr[i].field compound on slice field"
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_slice"
// (#33/rule-7): a compound assign on an indexed-element SLICE field is unwired
// in both stages and MUST loud-fail. The substring is the shared diagnostic
// body — byte-identical on both stages, pinned to "slice field" so it cannot
// also match the float/str/tagged rows (no file:line, no cstage "ww: " prefix
// — both differ cs vs ww).
package main;
type S = struct { f: []u8, g: i32 };
export fn main() i32 = {
let b: [2]u8 = [1u8, 2u8];
let xs: [2]S = [S{f=b[0:2], g=0}, S{f=b[0:2], g=0}];
xs[0].f += b[0:1];
return 0;
};

View File

@@ -0,0 +1,14 @@
//ww:error "arr[i].field compound on str field"
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_str"
// (#33/rule-7): a compound assign on an indexed-element STR field is unwired in
// both stages and MUST loud-fail. The substring is the shared diagnostic body
// — byte-identical on both stages, pinned to "str field" so it cannot also
// match the float/slice/tagged rows (no file:line, no cstage "ww: " prefix —
// both differ cs vs ww).
package main;
type S = struct { f: str, g: i32 };
export fn main() i32 = {
let xs: [2]S = [S{f="a", g=0}, S{f="b", g=0}];
xs[0].f += "x";
return 0;
};

View File

@@ -0,0 +1,14 @@
//ww:error "arr[i].field compound on tagged field"
// Lifted from test/wcc/949_idxfield_compound_run.c reject row "fld_he_tagged"
// (#33/rule-7): a compound assign on an indexed-element TAGGED-union field is
// unwired in both stages and MUST loud-fail. The substring is the shared
// diagnostic body — byte-identical on both stages, pinned to "tagged field" so
// it cannot also match the float/str/slice rows (no file:line, no cstage
// "ww: " prefix — both differ cs vs ww).
package main;
type S = struct { f: (i32|str), g: i32 };
export fn main() i32 = {
let xs: [2]S = [S{f=1, g=0}, S{f=2, g=0}];
xs[0].f += 3;
return 0;
};