w6c+selfhost: cross-module same-leaf type disambiguation via Sym.mod

This commit is contained in:
2026-05-15 10:26:20 +09:00
parent e349536f62
commit 66d6408cbe
15 changed files with 614 additions and 60 deletions

View File

@@ -53,18 +53,66 @@ scope_lookup(Scope *s, const char *name)
return NULL;
}
/*
* scope_lookup_in_module — module-filtered chain walk.
*
* Same FNV bucket + hashnext chain + parent walk as scope_lookup,
* plus a (b->mod != NULL && strcmp(b->mod, mod) == 0) filter. When
* `mod` is NULL we fall back to unfiltered scope_lookup semantics,
* so callers that don't care about disambiguation get the default.
*
* Used by resolve_typename and the cexpr N_DOT branch to pick the
* right same-leaf-name type when two imports each export it
* (`bufio.stream` vs `io.stream`).
*/
Sym *
scope_lookup_in_module(Scope *s, const char *mod, const char *name)
{
if (mod == NULL) return scope_lookup(s, name);
for (; s; s = s->parent) {
u64 h = hashstr(name) % s->nbuckets;
for (Sym *b = s->buckets[h]; b; b = b->hashnext) {
if (strcmp(b->name, name) != 0) continue;
if (b->mod && strcmp(b->mod, mod) == 0) return b;
}
}
return NULL;
}
Sym *
scope_define(Scope *s, const char *name, Skind k, Type *t, Node *decl)
{
if (scope_lookup_local(s, name) != NULL)
return NULL;
return scope_define_in_module(s, name, NULL, k, t, decl);
}
/*
* scope_define_in_module — bucket insert with per-mod dedup.
*
* Same insertion as scope_define, but the duplicate-rejection key is
* (name, mod) rather than name alone. This lets two imports each
* register their own `stream` SK_TYPE in the flat scope, and lets the
* primary register `stream` (mod=NULL) alongside imported `stream`s.
*
* Within a single (name, mod) pair the first registration wins; later
* attempts return NULL and the caller emits a duplicate-type error.
*/
Sym *
scope_define_in_module(Scope *s, const char *name, const char *mod,
Skind k, Type *t, Node *decl)
{
u64 h = hashstr(name) % s->nbuckets;
for (Sym *b = s->buckets[h]; b; b = b->hashnext) {
if (strcmp(b->name, name) != 0) continue;
if (b->mod == NULL && mod == NULL) return NULL;
if (b->mod && mod && strcmp(b->mod, mod) == 0) return NULL;
}
Sym *sy = amalloc(s->a, sizeof *sy);
sy->name = name;
sy->mod = mod;
sy->kind = k;
sy->type = t;
sy->decl = decl;
sy->scope = s;
u64 h = hashstr(name) % s->nbuckets;
sy->hashnext = s->buckets[h];
s->buckets[h] = sy;
if (s->first == NULL) s->first = sy;