selfhost/cmd/wcc: variadic param N_TSLICE wrap at installparams (cascade Commit 3, #25/#41)

installparams normalises `T...` p.lhs to []T so N_IDENT lookups
(s.decl.lhs) and cgen's variadic-slot synthesis see the effective
slice — mirrors cstage check.c:455 `tp->type = type_slice(c->a, pt)`
and harec check_func_type. cgendecl/cgenexpr drop the on-the-fly
slicewrap and consume p.lhs directly; cgenexpr cgcall peels the
N_TSLICE wrap when reading the element predicates / esz (Ken's
gate: cstage cgen.c:4352 `vsu->kind == TY_SLICE`), and passes
`velem` — not the wrap — into cgwidentaggedstore (cstage cgen.c
:4382). Closes the 22 N_DOT + 9 N_INDEX fires from #36 with the
cascade absorbed by e662156 (#39 arm-6 recursion). Class B "case:
not a variant of scrutinee" did NOT fire post-#39, so Commit 2
(#40 tagged_select_subtype) was not needed.
This commit is contained in:
2026-05-22 03:09:22 +09:00
parent e662156574
commit 45910ff966
5 changed files with 141 additions and 45 deletions

View File

@@ -39,11 +39,13 @@ fn cgfnparams(c: *cgen, params: *node) void = {
if (p.kind == nkind.N_PARAM) {
let nm: str = p.str;
// Hare-style variadic `T...`: callee receives a []T
// slice (3 register words / 24B). Mirror the slice-
// param spill below but use a synthesised TSLICE
// tnode so body references see the slot as a slice.
// slice (3 register words / 24B). p.lhs is already
// the []T wrap installed by check.ww installparams
// (mirrors cstage check.c:455 tp->type promotion), so
// we consume it directly — re-wrapping via slicewrap
// would yield [][]T.
if (p.op == tkind.TK_ELLIPSIS) {
let tn: *node = slicewrap(c, p.lhs);
let tn: *node = p.lhs;
if (idx + 3 <= 6) {
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
emitline("\tMOVQ\t");