@@ -1067,17 +1067,11 @@ impl<'a> Resolver<'a> {
10671067 declaration_id : DeclarationId ,
10681068 context : & mut LinearizationContext ,
10691069 ) -> Option < Vec < Ancestor > > {
1070- if declaration_id == * BASIC_OBJECT_ID {
1071- return None ;
1072- }
1073-
10741070 let declaration = self . graph . declarations ( ) . get ( & declaration_id) . unwrap ( ) ;
10751071
10761072 match declaration {
10771073 Declaration :: Namespace ( Namespace :: Class ( _) ) => {
1078- let definition_ids = declaration. definitions ( ) . to_vec ( ) ;
1079-
1080- Some ( match self . linearize_parent_class ( & definition_ids, context) {
1074+ Some ( match self . linearize_superclass ( declaration_id, context) ? {
10811075 Ancestors :: Complete ( ids) => ids,
10821076 Ancestors :: Cyclic ( ids) => {
10831077 context. cyclic = true ;
@@ -2020,11 +2014,6 @@ impl<'a> Resolver<'a> {
20202014 /// - Class: parent is the singleton class of the original parent class
20212015 /// - Singleton class: recurse as many times as necessary to wrap the original attached object's parent class
20222016 fn singleton_parent_id ( & mut self , attached_id : DeclarationId ) -> ( DeclarationId , bool ) {
2023- // Base case: if we reached `BasicObject`, then the parent is `Class`
2024- if attached_id == * BASIC_OBJECT_ID {
2025- return ( * CLASS_ID , false ) ;
2026- }
2027-
20282017 let decl = self . graph . declarations ( ) . get ( & attached_id) . unwrap ( ) ;
20292018
20302019 match decl {
@@ -2042,14 +2031,15 @@ impl<'a> Resolver<'a> {
20422031 )
20432032 }
20442033 Declaration :: Namespace ( Namespace :: Class ( _) ) => {
2045- // For classes (the regular case), we need to return the singleton class of its parent
2046- let definition_ids = decl. definitions ( ) . to_vec ( ) ;
2047-
2048- let ( picked_parent, unresolved_parent) = self . get_parent_class ( & definition_ids) ;
2034+ // For classes (the regular case), we need to return the singleton class of its superclass
2035+ let Some ( ( superclass_id, unresolved_superclass) ) = self . get_superclass ( attached_id) else {
2036+ // BasicObject has no superclass, but its singleton class inherits from Class
2037+ return ( * CLASS_ID , false ) ;
2038+ } ;
20492039 (
2050- self . get_or_create_singleton_class ( picked_parent , SingletonAncestors :: Deferred )
2051- . expect ( "parent class should always be a namespace" ) ,
2052- unresolved_parent . is_some ( ) ,
2040+ self . get_or_create_singleton_class ( superclass_id , SingletonAncestors :: Deferred )
2041+ . expect ( "superclass should always be a namespace" ) ,
2042+ unresolved_superclass . is_some ( ) ,
20532043 )
20542044 }
20552045 _ => {
@@ -2060,11 +2050,18 @@ impl<'a> Resolver<'a> {
20602050 }
20612051 }
20622052
2063- fn get_parent_class ( & self , definition_ids : & [ DefinitionId ] ) -> ( DeclarationId , Option < NameId > ) {
2064- let mut explicit_parents = Vec :: new ( ) ;
2065- let mut unresolved_parent = None ;
2053+ /// Returns the selected superclass and any unresolved explicit superclass. The top-level `BasicObject` declaration
2054+ /// is Ruby's root class and is the only class without a superclass.
2055+ fn get_superclass ( & self , declaration_id : DeclarationId ) -> Option < ( DeclarationId , Option < NameId > ) > {
2056+ if declaration_id == * BASIC_OBJECT_ID {
2057+ return None ;
2058+ }
2059+
2060+ let declaration = self . graph . declarations ( ) . get ( & declaration_id) . unwrap ( ) ;
2061+ let mut explicit_superclasses = Vec :: new ( ) ;
2062+ let mut unresolved_superclass = None ;
20662063
2067- for definition_id in definition_ids {
2064+ for definition_id in declaration . definitions ( ) {
20682065 let definition = self . graph . definitions ( ) . get ( definition_id) . unwrap ( ) ;
20692066
20702067 if let Definition :: Class ( class) = definition
@@ -2075,47 +2072,47 @@ impl<'a> Resolver<'a> {
20752072
20762073 match name {
20772074 NameRef :: Resolved ( resolved) => {
2078- if let Some ( parent_id ) = self . resolve_to_namespace ( * resolved. declaration_id ( ) ) {
2079- explicit_parents . push ( parent_id ) ;
2075+ if let Some ( superclass_id ) = self . resolve_to_namespace ( * resolved. declaration_id ( ) ) {
2076+ explicit_superclasses . push ( superclass_id ) ;
20802077 }
20812078 }
20822079 NameRef :: Unresolved ( _) => {
2083- unresolved_parent = Some ( * constant_reference. name_id ( ) ) ;
2080+ unresolved_superclass = Some ( * constant_reference. name_id ( ) ) ;
20842081 }
20852082 }
20862083 }
20872084 }
20882085
2089- // If there's more than one parent class that isn't `Object` and they are different, then there's a superclass
2086+ // If there's more than one superclass that isn't `Object` and they are different, then there's a superclass
20902087 // mismatch error. TODO: We should add a diagnostic here
2091- (
2092- explicit_parents . first ( ) . copied ( ) . unwrap_or ( * OBJECT_ID ) ,
2093- unresolved_parent ,
2094- )
2088+ Some ( (
2089+ explicit_superclasses . first ( ) . copied ( ) . unwrap_or ( * OBJECT_ID ) ,
2090+ unresolved_superclass ,
2091+ ) )
20952092 }
20962093
2097- fn linearize_parent_class (
2094+ fn linearize_superclass (
20982095 & mut self ,
2099- definition_ids : & [ DefinitionId ] ,
2096+ declaration_id : DeclarationId ,
21002097 context : & mut LinearizationContext ,
2101- ) -> Ancestors {
2102- let ( picked_parent , unresolved_parent ) = self . get_parent_class ( definition_ids ) ;
2103- let mut result = self . linearize_ancestors ( picked_parent , context) ;
2098+ ) -> Option < Ancestors > {
2099+ let ( superclass_id , unresolved_superclass ) = self . get_superclass ( declaration_id ) ? ;
2100+ let mut result = self . linearize_ancestors ( superclass_id , context) ;
21042101
2105- if let Some ( name_id) = unresolved_parent {
2102+ if let Some ( name_id) = unresolved_superclass {
21062103 context. partial = true ;
21072104
2108- // Insert the unresolved parent as a Partial ancestor at the front of the chain, so it
2105+ // Insert the unresolved superclass as a Partial ancestor at the front of the chain, so it
21092106 // appears before the default Object ancestors
21102107 let ancestors = match & mut result {
21112108 Ancestors :: Complete ( ids) | Ancestors :: Cyclic ( ids) | Ancestors :: Partial ( ids) => ids,
21122109 } ;
21132110 ancestors. insert ( 0 , Ancestor :: Partial ( name_id) ) ;
21142111
2115- result. to_partial ( )
2116- } else {
2117- result
2112+ result = result. to_partial ( ) ;
21182113 }
2114+
2115+ Some ( result)
21192116 }
21202117
21212118 fn mixins_of ( & self , definition_id : DefinitionId ) -> Option < Vec < Mixin > > {
0 commit comments