@@ -979,27 +979,42 @@ fn processAssociatedItemsSecondPass(
979979 // Create anno-only def with the qualified name
980980 const def_idx = try self .createAnnoOnlyDef (qualified_idx , type_anno_idx , where_clauses , region );
981981
982- // Register this associated item by its unqualified name
982+ // Get the type annotation index from the def - this is what has the actual type!
983+ // For anno-only defs, the expr is e_anno_only which doesn't have a type; the type anno has it.
984+ const def_cir = self .env .store .getDef (def_idx );
985+ const annotation_idx = def_cir .annotation .? ;
986+ const annotation_cir = self .env .store .getAnnotation (annotation_idx );
987+ const type_anno_node_idx = annotation_cir .anno ;
988+ const type_anno_idx_u16 : u16 = @intCast (@intFromEnum (type_anno_node_idx ));
989+
990+
991+ // Register this associated item by its unqualified name using the TYPE ANNOTATION index
983992 // (e.g., "is_empty" not "Str.is_empty")
984- const def_idx_u16 : u16 = @intCast (@intFromEnum (def_idx ));
985- try self .env .setExposedNodeIndexById (name_ident , def_idx_u16 );
993+ try self .env .setExposedNodeIndexById (name_ident , type_anno_idx_u16 );
986994
987- // Also register by the type-qualified name for type modules
988- // This is needed so lookups like "Builtin.Str.is_empty" work
989- if (self .env .module_kind == .type_module ) {
990- try self .env .setExposedNodeIndexById (qualified_idx , def_idx_u16 );
995+ // Compute type-qualified name (e.g., "Str.is_empty")
996+ const type_qualified_idx = try self .env .insertQualifiedIdent (self .env .getIdent (parent_type_name ), name_text );
997+
998+ // Always register by the type-qualified name (e.g., "Str.is_empty") using TYPE ANNOTATION index
999+ // This is needed so lookups like "Str.is_empty" work from other modules
1000+ if (type_qualified_idx .idx != name_ident .idx ) {
1001+ try self .env .setExposedNodeIndexById (type_qualified_idx , type_anno_idx_u16 );
1002+ }
1003+
1004+ // Also ALWAYS register by the fully qualified name (e.g., "Builtin.Str.is_empty") using TYPE ANNOTATION index
1005+ // This is needed for nested types inside regular modules (not just type modules)
1006+ if (qualified_idx .idx != type_qualified_idx .idx and qualified_idx .idx != name_ident .idx ) {
1007+ try self .env .setExposedNodeIndexById (qualified_idx , type_anno_idx_u16 );
9911008 }
9921009
9931010 // Make the real pattern available in current scope (replaces placeholder)
994- const def_cir = self .env .store .getDef (def_idx );
9951011 const pattern_idx = def_cir .pattern ;
9961012 const current_scope = & self .scopes .items [self .scopes .items .len - 1 ];
9971013
9981014 // Update unqualified name (e.g., "is_empty")
9991015 try self .updatePlaceholder (current_scope , name_ident , pattern_idx );
10001016
1001- // Update type-qualified name (e.g., "List.is_empty")
1002- const type_qualified_idx = try self .env .insertQualifiedIdent (self .env .getIdent (parent_type_name ), name_text );
1017+ // Update type-qualified name (e.g., "List.is_empty") - reuse already computed value
10031018 if (type_qualified_idx .idx != name_ident .idx ) {
10041019 try self .updatePlaceholder (current_scope , type_qualified_idx , pattern_idx );
10051020 }
@@ -9732,9 +9747,10 @@ fn exposeAssociatedItems(self: *Self, parent_name: Ident.Idx, type_decl: std.met
97329747 const decl_text = self .env .getIdent (decl_ident );
97339748 const qualified_idx = try self .env .insertQualifiedIdent (parent_text , decl_text );
97349749
9735- // Node index was already set during definition processing
9736- // Just ensure qualified name is in exposed_items
9737- try self .env .addExposedById (qualified_idx );
9750+ // Node index was already set during processAssociatedItemsSecondPass
9751+ // DO NOT call addExposedById here - it would overwrite the correct value with 0
9752+ // since the items array isn't sorted yet at this point
9753+ _ = qualified_idx ; // The value was already set, nothing to do here
97389754 }
97399755 }
97409756 },
@@ -9746,9 +9762,10 @@ fn exposeAssociatedItems(self: *Self, parent_name: Ident.Idx, type_decl: std.met
97469762 const anno_text = self .env .getIdent (anno_ident );
97479763 const qualified_idx = try self .env .insertQualifiedIdent (parent_text , anno_text );
97489764
9749- // Node index was already set during definition processing
9750- // Just ensure qualified name is in exposed_items
9751- try self .env .addExposedById (qualified_idx );
9765+ // Node index was already set during processAssociatedItemsSecondPass
9766+ // DO NOT call addExposedById here - it would overwrite the correct value with 0
9767+ // since the items array isn't sorted yet at this point
9768+ _ = qualified_idx ; // The value was already set, nothing to do here
97529769 }
97539770 },
97549771 else = > {},
0 commit comments