w6c+selfhost: same-module preference for bare-leaf lookup

This commit is contained in:
2026-05-15 11:24:33 +09:00
parent 35b32c1304
commit e6045f3ada
13 changed files with 382 additions and 12 deletions

View File

@@ -60,7 +60,7 @@ resolve_typename(Checker *c, Node *n)
const char *nm = n->str;
Type *bi = lookup_builtin(nm);
if (bi) return bi;
Sym *s = scope_lookup(c->cur, nm);
Sym *s = scope_lookup_prefer(c->cur, c->cur_mod, nm);
if (s == NULL && nm) {
/* module-qualified: io.stream → strip the last dot prefix
* and look up the leaf, filtering on the importing module's
@@ -679,7 +679,7 @@ cexpr(Checker *c, Node *n)
if (n->str && n->str[0] == '\0')
return n->type = err(c, n->pos,
"`_` is only valid as a binding or discard lvalue");
Sym *s = scope_lookup(c->cur, n->str);
Sym *s = scope_lookup_prefer(c->cur, c->cur_mod, n->str);
if (s == NULL)
return n->type = err(c, n->pos, "undefined: %s", n->str);
/* SK_USE has no concrete value type; the only legal use is
@@ -942,7 +942,7 @@ cexpr(Checker *c, Node *n)
* (e.g. lib/os/os.ww) keeps working unchanged. */
if (n->lhs && n->lhs->kind == N_IDENT && n->lhs->str &&
strcmp(n->lhs->str, "abort") == 0 &&
scope_lookup(c->cur, "abort") == NULL) {
scope_lookup_prefer(c->cur, c->cur_mod, "abort") == NULL) {
if (n->list) {
Type *mt = cexpr(c, n->list);
if (mt != ty_err && !type_assignable(ty_str, mt))
@@ -957,7 +957,7 @@ cexpr(Checker *c, Node *n)
if (n->lhs && n->lhs->kind == N_IDENT && n->lhs->str &&
strcmp(n->lhs->str, "assert") == 0 &&
n->list != NULL &&
scope_lookup(c->cur, "assert") == NULL) {
scope_lookup_prefer(c->cur, c->cur_mod, "assert") == NULL) {
Type *ct = cexpr(c, n->list);
if (ct != ty_err && ct != ty_bool && ct != ty_untyped_bool)
err(c, n->pos, "assert: cond must be bool");
@@ -1051,7 +1051,8 @@ cexpr(Checker *c, Node *n)
}
/* Reject assignment to a const-bound name. */
if (n->lhs && n->lhs->kind == N_IDENT && n->lhs->str) {
Sym *s = scope_lookup(c->cur, n->lhs->str);
Sym *s = scope_lookup_prefer(c->cur, c->cur_mod,
n->lhs->str);
if (s && s->is_const)
err(c, n->pos, "cannot assign to const `%s`",
n->lhs->str);
@@ -1069,7 +1070,8 @@ cexpr(Checker *c, Node *n)
* resolve_type for the synthetic-type-expr case. */
Type *t = NULL;
if (n->lhs && n->lhs->kind == N_IDENT) {
Sym *s = scope_lookup(c->cur, n->lhs->str);
Sym *s = scope_lookup_prefer(c->cur, c->cur_mod,
n->lhs->str);
if (s == NULL || s->kind != SK_TYPE)
t = err(c, n->pos, "unknown struct type '%s'",
n->lhs->str);
@@ -1682,6 +1684,7 @@ check_file(Checker *c, Node *file)
}
for (Node *d = file->list; d; d = d->next) {
if (d->kind != N_TYPEDECL) continue;
c->cur_mod = decl_mod(file, d);
Type *under = resolve_type(c, d->lhs);
d->type->under = under;
if (under) {
@@ -1690,7 +1693,9 @@ check_file(Checker *c, Node *file)
d->type->iserror = under->iserror;
}
}
c->cur_mod = NULL;
for (Node *d = file->list; d; d = d->next) {
c->cur_mod = decl_mod(file, d);
switch (d->kind) {
case N_USE:
/* already installed in pass 1; no-op here so the
@@ -1741,9 +1746,11 @@ check_file(Checker *c, Node *file)
default: break;
}
}
c->cur_mod = NULL;
/* pass 2: check def initialisers and fn bodies */
for (Node *d = file->list; d; d = d->next) {
c->cur_mod = decl_mod(file, d);
switch (d->kind) {
case N_DEF: {
if (d->rhs) {
@@ -1786,4 +1793,5 @@ check_file(Checker *c, Node *file)
default: break;
}
}
c->cur_mod = NULL;
}