wwstage: prefer curmod for bare-leaf value-ident in exprtype (#55, fixes #226)

exprtype's N_IDENT branch resolved a bare value-ident through the
flat-scope scopelookup, which bucket-walks and returns whichever
same-leaf symbol heads the bucket (the last-registered one). Under a
foreign curmod that binds a same-named symbol from the wrong module
and drags in its declaration's type: resolving `read` to io.read while
checking os pulled io.read's (size|eof|error) return node, whose bare
`error` then bound strconv.error instead of io.error. The mistyped
union variant made the tagged-tag remap's flatvariantidxt return -1
(correctly: the union held the wrong type), collapsing the tag to 0 —
the #226 fmt cs/ww asm divergence.

Resolve through scopelookupprefer(c.cur, c.curmod, e.str), preferring
the current module, mirroring cstage cmd/wcc/check.c:66
scope_lookup_prefer. Sibling bare-leaf sites already migrated: #56
(N_CALL callee), #53 (bare TNAME).

#226 is thereby an instance of #55, not a nominal-identity gap:
io.error is already a sound sym-cached singleton. The remaining
bare-leaf sites (N_DOT-callee leaf, varianterr, scruttype) and the
cgen-side cgident analogue are tracked separately. fmt's 777/780/781
stay STAGE_CS pending a separate spread-union residual.

test/wcc/794: cross-module bare-leaf value-ident, reject->accept
polarity (w6c_ww must accept the cstage-emitted combined); no byte-id
assertion as the minimal value-ident also trips the open cgen-side
cgident bug.
This commit is contained in:
2026-06-01 02:07:59 +09:00
parent db9edb7c39
commit f8aebc045d
5 changed files with 213 additions and 3 deletions

View File

@@ -12355,7 +12355,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return tn;
};
if (k == nkind.N_IDENT) {
let s: *sym = scopelookup(c.cur, e.str);
// #55: bare-leaf value-ident must prefer curmod. Flat-scope
// scopelookup bucket-walks and can bind a same-leaf symbol from
// the wrong module under a foreign curmod, dragging its decl's
// return-type node (e.g. `read` -> io.read under curmod=os, whose
// bare `error` then binds strconv.error not io.error). Mirrors
// cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at
// L2439, #53 at L688. Tracked in the cluster note at L685-687.
let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str);
if (s == nil) { return nil; };
if (s.decl == nil) { return nil; };
let t: *node = s.decl.lhs;

View File

@@ -2243,7 +2243,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return tn;
};
if (k == nkind.N_IDENT) {
let s: *sym = scopelookup(c.cur, e.str);
// #55: bare-leaf value-ident must prefer curmod. Flat-scope
// scopelookup bucket-walks and can bind a same-leaf symbol from
// the wrong module under a foreign curmod, dragging its decl's
// return-type node (e.g. `read` -> io.read under curmod=os, whose
// bare `error` then binds strconv.error not io.error). Mirrors
// cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at
// L2439, #53 at L688. Tracked in the cluster note at L685-687.
let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str);
if (s == nil) { return nil; };
if (s.decl == nil) { return nil; };
let t: *node = s.decl.lhs;

View File

@@ -12355,7 +12355,14 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
return tn;
};
if (k == nkind.N_IDENT) {
let s: *sym = scopelookup(c.cur, e.str);
// #55: bare-leaf value-ident must prefer curmod. Flat-scope
// scopelookup bucket-walks and can bind a same-leaf symbol from
// the wrong module under a foreign curmod, dragging its decl's
// return-type node (e.g. `read` -> io.read under curmod=os, whose
// bare `error` then binds strconv.error not io.error). Mirrors
// cstage cmd/wcc/check.c:66 scope_lookup_prefer; sibling #56 at
// L2439, #53 at L688. Tracked in the cluster note at L685-687.
let s: *sym = scopelookupprefer(c.cur, c.curmod, e.str);
if (s == nil) { return nil; };
if (s.decl == nil) { return nil; };
let t: *node = s.decl.lhs;