wcc/ww: size/align/offset return untyped_int, not i32 (catB-9)

wwstage's size/align/offset builtins returned i32 while their node
stamp was already untyped_int -- and cstage returns ty_untyped_int
(check.c:1570/1602). The diverging return false-rejected the canonical
Hare idiom `let x: size = size(T)` in wwstage (`let: not assignable
(i32 -> size)`) where cstage accepts; sha256.ww:189 was the live
casualty, quarantined as M_WWREJECT (#59.13) in the byte-id gate.

Align wwstage up: return untyped_int at the three sites (check.ww
size/align/offset). The len / slice .len / .cap returns stay i32 --
those match cstage (check.c:1534) and are correct. cstage is unchanged.

Regenerates the w6c and wwdump combined.ww. Full 990-997 byte-id holds
(a size()-mixing comparison emits CMPQ byte-identically on both stages,
so the untyped-int widening does not perturb the asm). Table-driven 844
test: the `let x: size = size(T)` family now compiles on both stages.
This commit is contained in:
2026-06-14 18:46:10 +09:00
parent 9767ff8fff
commit 7d4feac959
5 changed files with 272 additions and 24 deletions

View File

@@ -3081,11 +3081,10 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
};
// Post-fold the node IS an N_INTLIT-shaped
// untyped_int constant. Mirrors cstage
// cmd/wcc/check.c:926/958 which stamps
// ty_untyped_int after the fold. The return
// tnode mktname("i32") is the assignability
// target for callers, not the constant's
// own type.
// cmd/wcc/check.c:1570/1602 which stamps
// ty_untyped_int after the fold AND returns it
// to the caller (the Hare-correct type), so a
// `let x: size = size(T)` binding is assignable.
let utn: *node = mktname(c, "untyped_int");
if (issize) {
// #108(b): rule-10 twin of the cstage
@@ -3096,7 +3095,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
let v: i64 = astsize(c, e.list);
foldtointlit(c, e, v);
e.type_ = tinfofornode(c, utn): *void;
return mktname(c, "i32");
return mktname(c, "untyped_int");
};
if (isalign) {
if (astunsized(c, e.list)) {
@@ -3105,7 +3104,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
let v: i64 = astalign(c, e.list);
foldtointlit(c, e, v);
e.type_ = tinfofornode(c, utn): *void;
return mktname(c, "i32");
return mktname(c, "untyped_int");
};
// offset(e.f): the arg is a value expression
// (N_DOT), parsed via parsearglist — not a
@@ -3122,7 +3121,7 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
};
foldtointlit(c, e, off);
e.type_ = tinfofornode(c, utn): *void;
return mktname(c, "i32");
return mktname(c, "untyped_int");
};
};
};