w6c: key tagged natural-push call args on type equality, not slot size
pushargsrev's five aistagged gates (N_IDENT #55, N_CALL #21, N_INDEX #12, N_DOT #22a, deref #35) treated a tagged arg as already-tagged when its SLOT SIZE matched the param's. A same-slot subset union ((bool|void) into (i64|bool|void), both 16B) then natural-pushed the narrower box's words carrying SOURCE tags — no re-layout, no cg_widen_tag_remap twin — so the callee matched the wrong arm (silent: probes exited 10/90 where cstage exits 30/27). cstage keys widen detection on type equality (cgen.c:10000 same = (pu == au) || type_eq) and routes every non-same tagged source through the zeroed scratch + tag remap; the slot-DIFFER wwstage path already mirrored that byte-identically, so the fix computes cstage's same check once (wsame) and replaces each slot-size test with it. This also erases the last known cs!=ww shape divergence (the 16B-local staging vs direct-push frame delta on prefix subsets). 8 subsetwiden_* fixtures own the class: call-result/ident/str-payload /mid-arg remap (the wrong-arm shapes), prefix (the shape-divergence repro), and bigslot/return-pos/struct-24-to-32 sibling guards. Corpus pin 1740/343/22/209/1166/3480.
This commit is contained in:
11
test/wcc/data/subsetwiden_bigslot/case.ww
Normal file
11
test/wcc/data/subsetwiden_bigslot/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn mk(v: bool) (i64 | bool) = { return v; };
|
||||
fn pick(r: (i64 | bool | str)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let b: bool => return 30;
|
||||
case let s: str => return 40;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(mk(true)); };
|
||||
11
test/wcc/data/subsetwiden_callarg_prefix/case.ww
Normal file
11
test/wcc/data/subsetwiden_callarg_prefix/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn mk(v: bool) (i64 | bool) = { return v; };
|
||||
fn pick(r: (i64 | bool | void)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let b: bool => return 30;
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(mk(true)); };
|
||||
11
test/wcc/data/subsetwiden_callarg_remap/case.ww
Normal file
11
test/wcc/data/subsetwiden_callarg_remap/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn mk(v: bool) (bool | void) = { return v; };
|
||||
fn pick(r: (i64 | bool | void)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let b: bool => return 30;
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(mk(true)); };
|
||||
13
test/wcc/data/subsetwiden_identarg_remap/case.ww
Normal file
13
test/wcc/data/subsetwiden_identarg_remap/case.ww
Normal file
@@ -0,0 +1,13 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn pick(r: (i64 | bool | void)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let b: bool => return 30;
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = {
|
||||
let v: (bool | void) = true;
|
||||
return pick(v);
|
||||
};
|
||||
11
test/wcc/data/subsetwiden_midarg_remap/case.ww
Normal file
11
test/wcc/data/subsetwiden_midarg_remap/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:run-exit 27
|
||||
package main;
|
||||
fn mk(v: bool) (bool | void) = { return v; };
|
||||
fn pick3(a: i32, r: (i64 | bool | void), b: i32) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 90;
|
||||
case let b2: bool => return a*10 + b;
|
||||
case void => return 91;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick3(2, mk(true), 7); };
|
||||
12
test/wcc/data/subsetwiden_return_pos/case.ww
Normal file
12
test/wcc/data/subsetwiden_return_pos/case.ww
Normal file
@@ -0,0 +1,12 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn mk(v: bool) (bool | void) = { return v; };
|
||||
fn wide(v: bool) (i64 | bool | void) = { return mk(v); };
|
||||
fn pick(r: (i64 | bool | void)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let b: bool => return 30;
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(wide(true)); };
|
||||
11
test/wcc/data/subsetwiden_strpayload_remap/case.ww
Normal file
11
test/wcc/data/subsetwiden_strpayload_remap/case.ww
Normal file
@@ -0,0 +1,11 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
fn mk(s: str) (str | void) = { return s; };
|
||||
fn pick(r: (i64 | str | void)) i32 = {
|
||||
match (r) {
|
||||
case let n: i64 => return 10;
|
||||
case let s: str => { if (len(s) != 5) { return 4; }; return 30; };
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(mk("hello")); };
|
||||
15
test/wcc/data/subsetwiden_struct2432_remap/case.ww
Normal file
15
test/wcc/data/subsetwiden_struct2432_remap/case.ww
Normal file
@@ -0,0 +1,15 @@
|
||||
//ww:run-exit 30
|
||||
package main;
|
||||
type pair = struct { a: i64, b: i64 };
|
||||
fn mk(x: i64) (pair | void) = {
|
||||
let p: pair; p.a = x; p.b = x + 1;
|
||||
return p;
|
||||
};
|
||||
fn pick(r: (str | pair | void)) i32 = {
|
||||
match (r) {
|
||||
case let s: str => return 10;
|
||||
case let p: pair => { if (p.a != 5) { return 4; }; if (p.b != 6) { return 5; }; return 30; };
|
||||
case void => return 20;
|
||||
};
|
||||
};
|
||||
export fn main() i32 = { return pick(mk(5)); };
|
||||
Reference in New Issue
Block a user