Skip to content

Commit aeeaa6e

Browse files
committed
Expose type-qualified names for nested associated items
1 parent 862246f commit aeeaa6e

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

src/canonicalize/Can.zig

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -922,10 +922,21 @@ fn processAssociatedItemsSecondPass(
922922
const def_idx_u16: u16 = @intCast(@intFromEnum(def_idx));
923923
try self.env.setExposedNodeIndexById(decl_ident, def_idx_u16);
924924

925-
// Also register by the type-qualified name for type modules
926-
// This is needed so lookups like "Builtin.Str.is_empty" work
925+
// Compute type-qualified name first (e.g., "Bool.not") before exposing
926+
const type_qualified_idx = try self.env.insertQualifiedIdent(self.env.getIdent(parent_type_name), decl_text);
927+
928+
// Always register by the type-qualified name (e.g., "Bool.not")
929+
// This is needed so lookups like "Bool.not" work from other modules
930+
if (type_qualified_idx.idx != decl_ident.idx) {
931+
try self.env.setExposedNodeIndexById(type_qualified_idx, def_idx_u16);
932+
}
933+
934+
// Also register by the fully qualified name for type modules (e.g., "Builtin.Bool.not")
935+
// This is needed so lookups like "Builtin.Bool.not" work
927936
if (self.env.module_kind == .type_module) {
928-
try self.env.setExposedNodeIndexById(qualified_idx, def_idx_u16);
937+
if (qualified_idx.idx != type_qualified_idx.idx and qualified_idx.idx != decl_ident.idx) {
938+
try self.env.setExposedNodeIndexById(qualified_idx, def_idx_u16);
939+
}
929940
}
930941

931942
// Make the real pattern available in current scope (replaces placeholder)
@@ -939,7 +950,6 @@ fn processAssociatedItemsSecondPass(
939950
try self.updatePlaceholder(current_scope, decl_ident, pattern_idx);
940951

941952
// Update type-qualified name (e.g., "MyBool.my_not")
942-
const type_qualified_idx = try self.env.insertQualifiedIdent(self.env.getIdent(parent_type_name), decl_text);
943953
if (type_qualified_idx.idx != decl_ident.idx) {
944954
try self.updatePlaceholder(current_scope, type_qualified_idx, pattern_idx);
945955
}
@@ -974,10 +984,21 @@ fn processAssociatedItemsSecondPass(
974984
const def_idx_u16: u16 = @intCast(@intFromEnum(def_idx));
975985
try self.env.setExposedNodeIndexById(name_ident, def_idx_u16);
976986

977-
// Also register by the type-qualified name for type modules
987+
// Compute type-qualified name first (e.g., "Str.is_empty") before exposing
988+
const type_qualified_idx = try self.env.insertQualifiedIdent(self.env.getIdent(parent_type_name), name_text);
989+
990+
// Always register by the type-qualified name (e.g., "Str.is_empty")
991+
// This is needed so lookups like "Str.is_empty" work from other modules
992+
if (type_qualified_idx.idx != name_ident.idx) {
993+
try self.env.setExposedNodeIndexById(type_qualified_idx, def_idx_u16);
994+
}
995+
996+
// Also register by the fully qualified name for type modules (e.g., "Builtin.Str.is_empty")
978997
// This is needed so lookups like "Builtin.Str.is_empty" work
979998
if (self.env.module_kind == .type_module) {
980-
try self.env.setExposedNodeIndexById(qualified_idx, def_idx_u16);
999+
if (qualified_idx.idx != type_qualified_idx.idx and qualified_idx.idx != name_ident.idx) {
1000+
try self.env.setExposedNodeIndexById(qualified_idx, def_idx_u16);
1001+
}
9811002
}
9821003

9831004
// Make the real pattern available in current scope (replaces placeholder)
@@ -989,7 +1010,6 @@ fn processAssociatedItemsSecondPass(
9891010
try self.updatePlaceholder(current_scope, name_ident, pattern_idx);
9901011

9911012
// Update type-qualified name (e.g., "List.is_empty")
992-
const type_qualified_idx = try self.env.insertQualifiedIdent(self.env.getIdent(parent_type_name), name_text);
9931013
if (type_qualified_idx.idx != name_ident.idx) {
9941014
try self.updatePlaceholder(current_scope, type_qualified_idx, pattern_idx);
9951015
}
@@ -1022,6 +1042,19 @@ fn processAssociatedItemsSecondPass(
10221042
// (e.g., "bar" not "Foo.bar")
10231043
const def_idx_u16: u16 = @intCast(@intFromEnum(def_idx));
10241044
try self.env.setExposedNodeIndexById(decl_ident, def_idx_u16);
1045+
1046+
// Compute type-qualified name (e.g., "MyType.bar") and expose it
1047+
const type_qualified_idx = try self.env.insertQualifiedIdent(self.env.getIdent(parent_type_name), decl_text);
1048+
if (type_qualified_idx.idx != decl_ident.idx) {
1049+
try self.env.setExposedNodeIndexById(type_qualified_idx, def_idx_u16);
1050+
}
1051+
1052+
// Also register by the fully qualified name for type modules (e.g., "Module.MyType.bar")
1053+
if (self.env.module_kind == .type_module) {
1054+
if (qualified_idx.idx != type_qualified_idx.idx and qualified_idx.idx != decl_ident.idx) {
1055+
try self.env.setExposedNodeIndexById(qualified_idx, def_idx_u16);
1056+
}
1057+
}
10251058
}
10261059
} else {
10271060
// Non-identifier patterns are not supported in associated blocks

0 commit comments

Comments
 (0)