wcc/ww: module-scope the cgen mangle-hint (#40)
use_hint/usehint were unit-global first-leaf-match: two directory- packages exporting the same fn leaf, each imported by a different module aliasing the same bareword, mis-routed every qualified call to whichever use was collected first. Identically wrong on both stages (byte-id-green #263-class). Key the hint on (owner-module, alias) and prefer cur_mod, mirroring the checker's use_path curmod-preference (55f54fb). 989_m1usehint_run: two same-leaf pick() across a.math/b.math, each module's call routes to its own import (111/222) + cs.s==ww.s.
This commit is contained in:
@@ -44986,6 +44986,7 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = {
|
||||
type modent = struct {
|
||||
mname: str, // the bare ident as it appears in source
|
||||
nmod: str, // the originating module (`// MODULE: foo`)
|
||||
omod: str, // owning module of a `use` decl (#40); unused for mods
|
||||
mnext: *modent,
|
||||
};
|
||||
|
||||
@@ -44998,7 +44999,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #22: record alias→path for the qualified-ref hint.
|
||||
if (d.kind == nkind.N_USE) {
|
||||
if (d.usepath.len > 0) {
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, mnext=c.uses})!;
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!;
|
||||
c.uses = um;
|
||||
};
|
||||
};
|
||||
@@ -45022,7 +45023,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #32: the ROOT main (imported==0) stays bare;
|
||||
// an IMPORTED `fn main` mangles on its path.
|
||||
if (!streq(d.str, "main") || d.imported != 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45031,7 +45032,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_DEF) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45039,7 +45040,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_TYPEDECL) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45047,7 +45048,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_LET) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45072,12 +45073,27 @@ fn modlookup(c: *cgen, name: str) str = {
|
||||
// import path (`encoding.utf8`) so the codegen hint keys the path-keyed
|
||||
// mods map. For single-level packages alias == path (no-op). Returns the
|
||||
// alias unchanged when no matching `use` exists.
|
||||
//
|
||||
// NOT file-global (#40): two modules in one unit may bind the same leaf
|
||||
// alias to different paths (module one's `import a.math` vs module two's
|
||||
// `import b.math`, both alias `math`). The `use` declared in the SAME
|
||||
// module as the reference (c.curmod) is authoritative; preferring it
|
||||
// routes each `math.pick()` to its own package. Falls back to any
|
||||
// matching alias when c.curmod has no own import. Mirrors the checker's
|
||||
// use_path curmod-preference (cstage check.c, M1 55f54fb).
|
||||
fn usehint(c: *cgen, alias: str) str = {
|
||||
let m: *modent = c.uses;
|
||||
let any: str;
|
||||
any.ptr = nil;
|
||||
any.len = 0;
|
||||
for (m != nil) {
|
||||
if (streq(m.mname, alias)) { return m.nmod; };
|
||||
if (streq(m.mname, alias)) {
|
||||
if (streq(m.omod, c.curmod)) { return m.nmod; };
|
||||
if (any.ptr == nil && any.len == 0) { any = m.nmod; };
|
||||
};
|
||||
m = m.mnext;
|
||||
};
|
||||
if (any.ptr != nil || any.len != 0) { return any; };
|
||||
return alias;
|
||||
};
|
||||
|
||||
|
||||
@@ -3787,6 +3787,7 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = {
|
||||
type modent = struct {
|
||||
mname: str, // the bare ident as it appears in source
|
||||
nmod: str, // the originating module (`// MODULE: foo`)
|
||||
omod: str, // owning module of a `use` decl (#40); unused for mods
|
||||
mnext: *modent,
|
||||
};
|
||||
|
||||
@@ -3799,7 +3800,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #22: record alias→path for the qualified-ref hint.
|
||||
if (d.kind == nkind.N_USE) {
|
||||
if (d.usepath.len > 0) {
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, mnext=c.uses})!;
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!;
|
||||
c.uses = um;
|
||||
};
|
||||
};
|
||||
@@ -3823,7 +3824,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #32: the ROOT main (imported==0) stays bare;
|
||||
// an IMPORTED `fn main` mangles on its path.
|
||||
if (!streq(d.str, "main") || d.imported != 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -3832,7 +3833,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_DEF) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -3840,7 +3841,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_TYPEDECL) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -3848,7 +3849,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_LET) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -3873,12 +3874,27 @@ fn modlookup(c: *cgen, name: str) str = {
|
||||
// import path (`encoding.utf8`) so the codegen hint keys the path-keyed
|
||||
// mods map. For single-level packages alias == path (no-op). Returns the
|
||||
// alias unchanged when no matching `use` exists.
|
||||
//
|
||||
// NOT file-global (#40): two modules in one unit may bind the same leaf
|
||||
// alias to different paths (module one's `import a.math` vs module two's
|
||||
// `import b.math`, both alias `math`). The `use` declared in the SAME
|
||||
// module as the reference (c.curmod) is authoritative; preferring it
|
||||
// routes each `math.pick()` to its own package. Falls back to any
|
||||
// matching alias when c.curmod has no own import. Mirrors the checker's
|
||||
// use_path curmod-preference (cstage check.c, M1 55f54fb).
|
||||
fn usehint(c: *cgen, alias: str) str = {
|
||||
let m: *modent = c.uses;
|
||||
let any: str;
|
||||
any.ptr = nil;
|
||||
any.len = 0;
|
||||
for (m != nil) {
|
||||
if (streq(m.mname, alias)) { return m.nmod; };
|
||||
if (streq(m.mname, alias)) {
|
||||
if (streq(m.omod, c.curmod)) { return m.nmod; };
|
||||
if (any.ptr == nil && any.len == 0) { any = m.nmod; };
|
||||
};
|
||||
m = m.mnext;
|
||||
};
|
||||
if (any.ptr != nil || any.len != 0) { return any; };
|
||||
return alias;
|
||||
};
|
||||
|
||||
|
||||
@@ -44986,6 +44986,7 @@ fn defisaddressable(c: *cgen, opnd: *node) bool = {
|
||||
type modent = struct {
|
||||
mname: str, // the bare ident as it appears in source
|
||||
nmod: str, // the originating module (`// MODULE: foo`)
|
||||
omod: str, // owning module of a `use` decl (#40); unused for mods
|
||||
mnext: *modent,
|
||||
};
|
||||
|
||||
@@ -44998,7 +44999,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #22: record alias→path for the qualified-ref hint.
|
||||
if (d.kind == nkind.N_USE) {
|
||||
if (d.usepath.len > 0) {
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, mnext=c.uses})!;
|
||||
let um: *modent = alloc(modent{mname=d.str, nmod=d.usepath, omod=d.nmod, mnext=c.uses})!;
|
||||
c.uses = um;
|
||||
};
|
||||
};
|
||||
@@ -45022,7 +45023,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
// M1 #32: the ROOT main (imported==0) stays bare;
|
||||
// an IMPORTED `fn main` mangles on its path.
|
||||
if (!streq(d.str, "main") || d.imported != 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45031,7 +45032,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_DEF) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45039,7 +45040,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_TYPEDECL) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45047,7 +45048,7 @@ fn collectmods(c: *cgen, file: *node) void = {
|
||||
if (d.kind == nkind.N_LET) {
|
||||
if (d.exported == 0) {
|
||||
if (d.nmod.len > 0) {
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, mnext=c.mods})!;
|
||||
let m: *modent = alloc(modent{mname=d.str, nmod=d.nmod, omod=d.nmod, mnext=c.mods})!;
|
||||
c.mods = m;
|
||||
};
|
||||
};
|
||||
@@ -45072,12 +45073,27 @@ fn modlookup(c: *cgen, name: str) str = {
|
||||
// import path (`encoding.utf8`) so the codegen hint keys the path-keyed
|
||||
// mods map. For single-level packages alias == path (no-op). Returns the
|
||||
// alias unchanged when no matching `use` exists.
|
||||
//
|
||||
// NOT file-global (#40): two modules in one unit may bind the same leaf
|
||||
// alias to different paths (module one's `import a.math` vs module two's
|
||||
// `import b.math`, both alias `math`). The `use` declared in the SAME
|
||||
// module as the reference (c.curmod) is authoritative; preferring it
|
||||
// routes each `math.pick()` to its own package. Falls back to any
|
||||
// matching alias when c.curmod has no own import. Mirrors the checker's
|
||||
// use_path curmod-preference (cstage check.c, M1 55f54fb).
|
||||
fn usehint(c: *cgen, alias: str) str = {
|
||||
let m: *modent = c.uses;
|
||||
let any: str;
|
||||
any.ptr = nil;
|
||||
any.len = 0;
|
||||
for (m != nil) {
|
||||
if (streq(m.mname, alias)) { return m.nmod; };
|
||||
if (streq(m.mname, alias)) {
|
||||
if (streq(m.omod, c.curmod)) { return m.nmod; };
|
||||
if (any.ptr == nil && any.len == 0) { any = m.nmod; };
|
||||
};
|
||||
m = m.mnext;
|
||||
};
|
||||
if (any.ptr != nil || any.len != 0) { return any; };
|
||||
return alias;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user