cgen: key the str/slice arg recognizers off the checker stamp

The wwstage nodeisstr/nodeisslice recognizers were name-keyed for
every non-local shape: an indirect fn-pointer callee ((*f)() — the
errnotest #59.5 divergence, streq receiving a shifted register file)
and module-global let/const idents (path.sepstr — union-widen pushes
zero-filled len/cap) both fell to false while cstage keys off the
checker stamp unconditionally. Both recognizers now fall back to the
stamped n.type_; push and pop sites share them, so the drain stays
balanced by construction. Graduates the #59.5 errnotest pin.
This commit is contained in:
2026-08-08 00:58:04 +09:00
parent 90af21e132
commit c421c2b20a
6 changed files with 103 additions and 7 deletions

View File

@@ -0,0 +1,23 @@
//ww:run
// A module-global const []u8 widened into a tagged-union call arg —
// the slice twin of globalconst_str_widen (path's const dot/dotdot
// shape).
package main;
const gb: []u8 = ['x', 'y', 'z'];
fn f(x: ([]u8 | i32)) i32 = {
match (x) {
case let s: []u8 => {
if (len(s) != 3) { return 1; };
if (s[2] != 122u8) { return 2; };
return 0;
};
case let v: i32 => { return 3; };
};
return 4;
};
fn main() i32 = {
return f(gb);
};

View File

@@ -0,0 +1,24 @@
//ww:run
// A module-global const str widened into a tagged-union call arg.
// The pre-fix wwstage nodeisstr N_IDENT arm knew only frame slots and
// defs, so the widen push took the scalar arm and zero-filled len/cap
// (path.sepstr's strings.hasprefix shape).
package main;
const gs: str = "hello";
fn f(x: (str | i32)) i32 = {
match (x) {
case let s: str => {
if (s.len != 5) { return 1; };
if (s[4] != 111u8) { return 2; };
return 0;
};
case let v: i32 => { return 3; };
};
return 4;
};
fn main() i32 = {
return f(gs);
};

View File

@@ -0,0 +1,22 @@
//ww:run
// #59.5: a str returned by an INDIRECT fn-pointer call, passed
// directly as a call arg. The pre-fix wwstage nodeisstr/nodeisslice
// N_CALL arms were callee-name-keyed and fell to false for the
// N_UN(STAR) callee, so only the ptr word was pushed and the callee
// read a shifted register file (len=b.ptr).
package main;
fn hello() str = {
return "hello";
};
fn taker(s: str) i32 = {
if (s.len != 5) { return 1; };
if (s[0] != 104u8) { return 2; };
return 0;
};
fn main() i32 = {
let f = (&hello): *fn() str;
return taker((*f)());
};