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:
29
examples/0781-modules-same-name-enum-payload-own-wins.sx
Normal file
29
examples/0781-modules-same-name-enum-payload-own-wins.sx
Normal file
@@ -0,0 +1,29 @@
|
||||
// Own-wins for ENUM-PAYLOAD type registration over a NAMESPACED import.
|
||||
// Regression (issue 0132, broader class).
|
||||
//
|
||||
// `#import "modules/std.sx"` carries the stdlib `event.Event` struct — it is
|
||||
// NAMESPACED (reachable only as `event.Event`), never flat-visible. This file
|
||||
// ALSO authors its OWN `Event :: struct { code }`, used as the payload of the
|
||||
// enum `Wrap`. The payload type name `Event` must resolve at REGISTRATION to
|
||||
// THIS file's own `Event` (which has `code`), not the namespaced stdlib struct.
|
||||
//
|
||||
// Fail-before: `registerEnumDecl` built the tagged-union body through the
|
||||
// stateless `type_bridge.buildEnumInfo`, whose flat `findByName` picked the
|
||||
// wrong same-name author — `got`'s payload became the stdlib `Event`, so
|
||||
// `e.code` errored "field 'code' not found on type 'Event'". Fixed by threading
|
||||
// the visibility-aware resolver (`*Lowering` as the `resolveInner` hook) through
|
||||
// `buildEnumInfo` / `buildUnionInfo`, matching what `registerStructDecl` already
|
||||
// does for struct fields.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Event :: struct { code: i64; }
|
||||
Wrap :: enum { none; got: Event; }
|
||||
|
||||
main :: () {
|
||||
w : Wrap = .got(.{ code = 7 });
|
||||
if w == {
|
||||
case .got: (e) { print("code={}\n", e.code); }
|
||||
case .none: print("none\n");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Own-wins for an INLINE struct field's member type over a NAMESPACED import.
|
||||
// Regression (issue 0132's broader class — the inline-decl resolution boundary).
|
||||
//
|
||||
// `Holder.inner` is an inline `struct { e: Event }`. The member type `Event`
|
||||
// must resolve to THIS file's `Event` (which has `code`), not the namespaced
|
||||
// stdlib `event.Event` struct carried by `#import "modules/std.sx"` (reachable
|
||||
// only as `event.Event`, never bare).
|
||||
//
|
||||
// Fail-before: `Lowering.resolveTypeWithBindings` delegated inline `struct_decl`
|
||||
// field types to the FLAT `type_bridge.resolveAstType`, dropping the visibility
|
||||
// context — so `e: Event` resolved via global `findByName` to the stdlib struct
|
||||
// and `h.inner.e.code` errored "field 'code' not found on type 'Event'". Fixed
|
||||
// by routing inline enum/struct/union decls through the `inner` recursion hook
|
||||
// with `self` (visibility-aware), the same own-wins rule top-level decls use.
|
||||
|
||||
#import "modules/std.sx";
|
||||
|
||||
Event :: struct { code: i64; }
|
||||
Holder :: struct { inner: struct { e: Event; }; }
|
||||
|
||||
main :: () {
|
||||
h : Holder = ---;
|
||||
h.inner.e = .{ code = 5 };
|
||||
print("code={}\n", h.inner.e.code);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
code=7
|
||||
@@ -0,0 +1 @@
|
||||
0
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
code=5
|
||||
Reference in New Issue
Block a user