selfhost/cmd/wcc/check: resolvealias prefer same-module (#53)
The bare-leaf TNAME lookup in resolvealias used flat scopelookup, which bucket-walks all matching names and returns whichever entry hashed in first. Two modules each declaring `type invalid = ...` collided in the same flat scope: utf8.invalid (`!void`) and strconv.invalid (`!i32`) resolved to whichever registered first. That drove a localloadop divergence at the 994/995 byte-id gates — MOVSXD vs MOVQ — depending on which alias the checker happened to pick for a given site. Switch to scopelookupprefer(c.cur, c.curmod, nm), mirroring cstage cmd/wcc/check.c:66 (scope_lookup_prefer at sym.c:103): when the current module matches the bucket entry's b.mod, prefer it; else fall back to first-found. The SK_USE→scopelookuptype fallback for the #61 A.5 bare-TNAME-vs-imported-module collision case is unchanged. Six remaining bare-leaf scopelookup sites in this file (exprtype N_IDENT, N_DOT-callee leaf, varianterr, scruttype, exprtypeoftry N_IDENT + N_CALL, walker N_IDENT) are punted to #55 — this commit fixes the path the reproducer surfaced and leaves the rest behind an explicit follow-up so the byte-id corpus stays the test for each conversion.
This commit is contained in:
@@ -7607,7 +7607,16 @@ fn resolvealias(c: *checker, n: *node) *node = {
|
||||
leaf.len = nm.len - dotidx - 1;
|
||||
s = scopelookupinmodule(c.cur, head, leaf);
|
||||
} else {
|
||||
s = scopelookup(c.cur, nm);
|
||||
// #53: same-module preference. Mirrors cstage
|
||||
// cmd/wcc/check.c:66 scope_lookup_prefer. Without this,
|
||||
// two modules each declaring `type invalid = ...` collide
|
||||
// on the head-first bucket walk: e.g. utf8.invalid `!void`
|
||||
// vs strconv.invalid `!i32` resolves to whichever
|
||||
// registered first, driving localloadop MOVSXD/MOVQ
|
||||
// divergence at 994/995. Other bare-leaf callers in this
|
||||
// file (L1597 exprtype N_IDENT, L1795/L2720 N_DOT-callee
|
||||
// leaf, L600 varianterr, L647 scruttype) tracked as #55.
|
||||
s = scopelookupprefer(c.cur, c.curmod, nm);
|
||||
// #61 A.5: bare TNAME that collides with an imported
|
||||
// module bareword. Two shapes hit this:
|
||||
// - `let l: lex;` where `lex` struct lives in
|
||||
|
||||
@@ -537,7 +537,16 @@ fn resolvealias(c: *checker, n: *node) *node = {
|
||||
leaf.len = nm.len - dotidx - 1;
|
||||
s = scopelookupinmodule(c.cur, head, leaf);
|
||||
} else {
|
||||
s = scopelookup(c.cur, nm);
|
||||
// #53: same-module preference. Mirrors cstage
|
||||
// cmd/wcc/check.c:66 scope_lookup_prefer. Without this,
|
||||
// two modules each declaring `type invalid = ...` collide
|
||||
// on the head-first bucket walk: e.g. utf8.invalid `!void`
|
||||
// vs strconv.invalid `!i32` resolves to whichever
|
||||
// registered first, driving localloadop MOVSXD/MOVQ
|
||||
// divergence at 994/995. Other bare-leaf callers in this
|
||||
// file (L1597 exprtype N_IDENT, L1795/L2720 N_DOT-callee
|
||||
// leaf, L600 varianterr, L647 scruttype) tracked as #55.
|
||||
s = scopelookupprefer(c.cur, c.curmod, nm);
|
||||
// #61 A.5: bare TNAME that collides with an imported
|
||||
// module bareword. Two shapes hit this:
|
||||
// - `let l: lex;` where `lex` struct lives in
|
||||
|
||||
@@ -7607,7 +7607,16 @@ fn resolvealias(c: *checker, n: *node) *node = {
|
||||
leaf.len = nm.len - dotidx - 1;
|
||||
s = scopelookupinmodule(c.cur, head, leaf);
|
||||
} else {
|
||||
s = scopelookup(c.cur, nm);
|
||||
// #53: same-module preference. Mirrors cstage
|
||||
// cmd/wcc/check.c:66 scope_lookup_prefer. Without this,
|
||||
// two modules each declaring `type invalid = ...` collide
|
||||
// on the head-first bucket walk: e.g. utf8.invalid `!void`
|
||||
// vs strconv.invalid `!i32` resolves to whichever
|
||||
// registered first, driving localloadop MOVSXD/MOVQ
|
||||
// divergence at 994/995. Other bare-leaf callers in this
|
||||
// file (L1597 exprtype N_IDENT, L1795/L2720 N_DOT-callee
|
||||
// leaf, L600 varianterr, L647 scruttype) tracked as #55.
|
||||
s = scopelookupprefer(c.cur, c.curmod, nm);
|
||||
// #61 A.5: bare TNAME that collides with an imported
|
||||
// module bareword. Two shapes hit this:
|
||||
// - `let l: lex;` where `lex` struct lives in
|
||||
|
||||
Reference in New Issue
Block a user