@@ -162,6 +162,14 @@ macro_rules! namespace_declaration {
162162 self . singleton_class_id = Some ( declaration_id) ;
163163 }
164164
165+ /// Clears `singleton_class_id` only if it matches `expected`.
166+ /// Prevents accidentally clearing a pointer to a re-created singleton.
167+ pub fn clear_singleton_class_id( & mut self , expected: & DeclarationId ) {
168+ if self . singleton_class_id. as_ref( ) == Some ( expected) {
169+ self . singleton_class_id = None ;
170+ }
171+ }
172+
165173 pub fn singleton_class_id( & self ) -> Option <& DeclarationId > {
166174 self . singleton_class_id. as_ref( )
167175 }
@@ -346,15 +354,24 @@ impl Declaration {
346354 }
347355
348356 /// Returns true if this declaration has no backing definitions and is eligible
349- /// for removal. Synthetic declarations (singleton classes, bootstrap Object/Module/Class)
350- /// are never definition-backed — they should only be removed when their owner is removed.
357+ /// for removal. Bootstrap declarations (Object, Module, Class) are never
358+ /// removable. Singleton classes are only removable when they have no
359+ /// definitions AND no members — populated singletons serve as namespace
360+ /// parents for class-level methods.
351361 #[ must_use]
352362 pub fn has_no_backing_definitions ( & self , decl_id : & DeclarationId ) -> bool {
353- let is_synthetic = matches ! ( self , Declaration :: Namespace ( Namespace :: SingletonClass ( _) ) )
354- || * decl_id == * super :: graph:: OBJECT_ID
363+ if * decl_id == * super :: graph:: OBJECT_ID
355364 || * decl_id == * super :: graph:: MODULE_ID
356- || * decl_id == * super :: graph:: CLASS_ID ;
357- !is_synthetic && self . has_no_definitions ( )
365+ || * decl_id == * super :: graph:: CLASS_ID
366+ {
367+ return false ;
368+ }
369+
370+ if matches ! ( self , Declaration :: Namespace ( Namespace :: SingletonClass ( _) ) ) {
371+ return self . has_no_definitions ( ) && self . as_namespace ( ) . is_some_and ( |ns| ns. members ( ) . is_empty ( ) ) ;
372+ }
373+
374+ self . has_no_definitions ( )
358375 }
359376
360377 pub fn add_definition ( & mut self , definition_id : DefinitionId ) {
@@ -590,6 +607,10 @@ impl Namespace {
590607 all_namespaces ! ( self , it => it. set_singleton_class_id( declaration_id) ) ;
591608 }
592609
610+ pub fn clear_singleton_class_id ( & mut self , expected : & DeclarationId ) {
611+ all_namespaces ! ( self , it => it. clear_singleton_class_id( expected) ) ;
612+ }
613+
593614 #[ must_use]
594615 pub fn owner_id ( & self ) -> & DeclarationId {
595616 all_namespaces ! ( self , it => & it. owner_id)
0 commit comments