@@ -76,8 +76,32 @@ impl Graph {
7676 where
7777 F : FnOnce ( ) -> Declaration ,
7878 {
79- let declaration = self . declarations . entry ( declaration_id) . or_insert_with ( constructor) ;
80- declaration. add_definition ( definition_id) ;
79+ match self . declarations . entry ( declaration_id) {
80+ Entry :: Occupied ( mut occupied_entry) => {
81+ // If we already have a declaration created, we need to check if it needs to be promoted. For example,
82+ // if we thought this declaration was a constant due to meta-programming and then it gets re-opened with
83+ // the `class` keyword, then we must promote it to a class
84+ if matches ! ( occupied_entry. get( ) , Declaration :: Constant ( _) )
85+ && matches ! (
86+ self . definitions. get( & definition_id) . unwrap( ) ,
87+ Definition :: Class ( _) | Definition :: Module ( _) | Definition :: SingletonClass ( _)
88+ )
89+ {
90+ let mut new_declaration = constructor ( ) ;
91+ let removed_declaration = occupied_entry. remove ( ) ;
92+ new_declaration. as_namespace_mut ( ) . unwrap ( ) . extend ( removed_declaration) ;
93+ new_declaration. add_definition ( definition_id) ;
94+ self . declarations . insert ( declaration_id, new_declaration) ;
95+ } else {
96+ occupied_entry. get_mut ( ) . add_definition ( definition_id) ;
97+ }
98+ }
99+ Entry :: Vacant ( vacant_entry) => {
100+ let mut declaration = constructor ( ) ;
101+ declaration. add_definition ( definition_id) ;
102+ vacant_entry. insert ( declaration) ;
103+ }
104+ }
81105 }
82106
83107 /// # Panics
@@ -468,9 +492,6 @@ impl Graph {
468492 Declaration :: Namespace ( Namespace :: SingletonClass ( it) ) => {
469493 it. add_member ( member_str_id, member_declaration_id) ;
470494 }
471- Declaration :: Constant ( _) => {
472- // TODO: temporary hack to avoid crashing on `Struct.new`, `Class.new` and `Module.new`
473- }
474495 _ => panic ! ( "Tried to add member to a declaration that isn't a namespace" ) ,
475496 }
476497 }
0 commit comments