wwstage: recognize an unwrap success in the slice/str call-arg recognizers (#6 Mech A)

nodeisslice/nodeisstr lacked an N_TRYUNW/N_TRYPROP arm, so a str/slice produced by an unwrap (f()!, r!, r?) and passed as a call arg fell to the 1-word scalar push, dropping .len/.cap; cstage's type-keyed node_isslice/node_isstr already pushed 3 words. Add the type-keyed arm reading the checker-stamped success-variant n.type_, mirroring #9's N_UN/TK_STAR arm. Fixes the str case (wwstage align-up to cstage); the slice success shuffle that both stages still get wrong is fixed in the Mech B follow-up.
This commit is contained in:
2026-06-27 21:10:03 +09:00
parent 5071996efe
commit 3fe4a2cd3b
2 changed files with 60 additions and 0 deletions

View File

@@ -1383,6 +1383,16 @@ fn nodeisslice(c: *cgen, n: *syntax.node) bool = {
if (k == syntax.nkind.N_UN && n.op == syntax.tkind.TK_STAR) {
return syntax.typeisslice(n.type_: *syntax.tinfo);
};
// #6 (Mech A): an unwrap source (`f()!` N_TRYUNW, `r!`/`r?` N_TRYPROP)
// whose success variant is a slice. Without this arm the unwrap fell
// through to the scalar single-PUSHQ default, marshalling .ptr and
// dropping .len/.cap (cgcall's pop sizer under-drains). n.type_ is
// checker-stamped to the success variant (check.ww N_TRYPROP/N_TRYUNW),
// mirroring cstage node_isslice = type_isslice(n->type). Twin of the
// N_UN(TK_STAR) #9 arm above.
if (k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TRYPROP) {
return syntax.typeisslice(n.type_: *syntax.tinfo);
};
return false;
};
@@ -1486,6 +1496,13 @@ fn nodeisstr(c: *cgen, n: *syntax.node) bool = {
if (k == syntax.nkind.N_UN && n.op == syntax.tkind.TK_STAR) {
return syntax.typeisstr(n.type_: *syntax.tinfo);
};
// #6 (Mech A): str twin of the N_TRYUNW/N_TRYPROP slice arm in
// nodeisslice — an unwrap source whose success variant is a str.
// n.type_ is checker-stamped to the success variant; mirrors cstage
// node_isstr = type_isstr(n->type).
if (k == syntax.nkind.N_TRYUNW || k == syntax.nkind.N_TRYPROP) {
return syntax.typeisstr(n.type_: *syntax.tinfo);
};
return false;
};