fix: visibility-aware type-name resolution at registration time
Enum payloads, union fields, inline struct/enum/union field types, and named error-set references now resolve through the visibility-aware `inner` recursion hook (the same seam `resolveCompound` uses) instead of the flat `findByName`. A bare type name in any of these positions now selects the querying module's OWN author over a same-name namespaced import -- the own-wins rule already applied to top-level named references and struct fields. - buildEnumInfo / buildUnionInfo / resolveInlineEnum / resolveInlineStruct / resolveInlineUnion / resolveErrorType take the `inner: anytype` seam; registerEnumDecl / registerUnionDecl and the struct-const annotation pass `self` (visibility-aware); resolveAstType passes the stateless `si`. - resolveTypeWithBindings routes inline type decls and named error refs through `self` instead of delegating to flat resolveAstType. Regression tests: examples/0781 (top-level enum payload over a namespaced import), examples/0784 (inline struct field). Addresses issue 0132's broader latent class; the protocol-return case (0132 primary) is a separate registerProtocolDecl fix and stays open. The error-set reference path is in place but dormant pending error-set per-decl nominal identity (issue 0134).
This commit is contained in:
@@ -717,6 +717,14 @@ pub const Lowering = struct {
|
||||
return self.resolveTypeWithBindings(node);
|
||||
}
|
||||
|
||||
/// Bare TYPE-NAME twin of `resolveInner` for callers holding a name rather
|
||||
/// than an AST node (e.g. an error-set reference `!Named`) — routed through
|
||||
/// the visibility-aware `resolveNominalLeaf`, so a same-name-shadowed set
|
||||
/// resolves to the querying module's own author (issue 0132's class).
|
||||
pub fn resolveName(self: *Lowering, name: []const u8) TypeId {
|
||||
return self.resolveNominalLeaf(name, false, null);
|
||||
}
|
||||
|
||||
/// Fixed-array dimension hook for `TypeResolver.resolveCompound`. A literal
|
||||
/// `[16]T` and a named-const `N :: 16; [N]T` must resolve to the SAME length:
|
||||
/// the dimension folds to a compile-time integer (looked up in the comptime /
|
||||
@@ -936,6 +944,28 @@ pub const Lowering = struct {
|
||||
// literal (`(i32, i32)`); validate its elements are types and reject
|
||||
// non-type elements loudly.
|
||||
.tuple_literal => return self.resolveTupleLiteralTypeArg(node),
|
||||
// Inline type declarations used as a field type (`x: enum { ... }`,
|
||||
// `x: struct { ... }`, `x: union { ... }`): build their bodies with
|
||||
// THIS lowering as the `inner` recursion hook, so a payload / field
|
||||
// type NAME resolves in the enclosing module's visibility context —
|
||||
// the SAME own-wins-over-namespaced rule the top-level registration
|
||||
// uses (issue 0132's class). Delegating to the flat `else` below
|
||||
// dropped `self`, leaving inline-decl payloads on the global
|
||||
// `findByName` first-match.
|
||||
.enum_decl => return type_bridge.resolveInlineEnum(&node.data.enum_decl, &self.module.types, self),
|
||||
.struct_decl => return type_bridge.resolveInlineStruct(&node.data.struct_decl, &self.module.types, self),
|
||||
.union_decl => return type_bridge.resolveInlineUnion(&node.data.union_decl, &self.module.types, self),
|
||||
// A NAMED error-set reference (`!Named`) resolves its name through
|
||||
// `self` (visibility-aware) too; the bare `!` inferred set has no name
|
||||
// to shadow. NOTE: this reference-side resolution is currently DORMANT
|
||||
// for same-name error-set collisions — error-set DECLARATIONS don't
|
||||
// yet get per-decl nominal identity (E6a covers struct/enum/union
|
||||
// only), so a same-name set collapses to one TypeId at registration
|
||||
// and there is nothing distinct for the reference to select. See issue
|
||||
// 0134; once decls get nominal identity this activates with no change
|
||||
// here. `error_set_decl` is NOT in this switch: it interns only tag
|
||||
// names, resolving no type names, so it stays on the flat `else`.
|
||||
.error_type_expr => return type_bridge.resolveErrorType(&node.data.error_type_expr, &self.module.types, self),
|
||||
else => return type_bridge.resolveAstType(node, &self.module.types, &self.program_index.type_alias_map, &self.program_index.module_const_map),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user