@@ -9,6 +9,7 @@ use hir_def::{
99 ModuleDefId , ModuleId , TraitId ,
1010 db:: DefDatabase ,
1111 item_scope:: { ImportId , ImportOrExternCrate , ImportOrGlob } ,
12+ nameres:: crate_def_map,
1213 per_ns:: Item ,
1314 src:: { HasChildSource , HasSource } ,
1415 visibility:: { Visibility , VisibilityExplicitness } ,
@@ -40,14 +41,14 @@ pub struct FileSymbol<'db> {
4041 _marker : PhantomData < & ' db ( ) > ,
4142}
4243
43- #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
44+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
4445pub struct DeclarationLocation {
4546 /// The file id for both the `ptr` and `name_ptr`.
4647 pub hir_file_id : HirFileId ,
4748 /// This points to the whole syntax node of the declaration.
4849 pub ptr : SyntaxNodePtr ,
4950 /// This points to the [`syntax::ast::Name`] identifier of the declaration.
50- pub name_ptr : AstPtr < Either < syntax:: ast:: Name , syntax:: ast:: NameRef > > ,
51+ pub name_ptr : Option < AstPtr < Either < syntax:: ast:: Name , syntax:: ast:: NameRef > > > ,
5152}
5253
5354impl DeclarationLocation {
@@ -99,6 +100,11 @@ impl<'a> SymbolCollector<'a> {
99100 let _p = tracing:: info_span!( "SymbolCollector::collect" , ?module) . entered ( ) ;
100101 tracing:: info!( ?module, "SymbolCollector::collect" ) ;
101102
103+ // If this is a crate root module, add a symbol for the crate itself
104+ if module. is_crate_root ( self . db ) {
105+ self . push_crate_root ( module) ;
106+ }
107+
102108 // The initial work is the root module we're collecting, additional work will
103109 // be populated as we traverse the module's definitions.
104110 self . work . push ( SymbolCollectorWork { module_id : module. into ( ) , parent : None } ) ;
@@ -108,6 +114,51 @@ impl<'a> SymbolCollector<'a> {
108114 }
109115 }
110116
117+ /// Push a symbol for a crate's root module.
118+ /// This allows crate roots to appear in the symbol index for queries like `::` or `::foo`.
119+ fn push_crate_root ( & mut self , module : Module ) {
120+ let krate = module. krate ( self . db ) ;
121+ let Some ( display_name) = krate. display_name ( self . db ) else { return } ;
122+ let crate_name = display_name. crate_name ( ) ;
123+ let canonical_name = display_name. canonical_name ( ) ;
124+
125+ let def_map = crate_def_map ( self . db , krate. into ( ) ) ;
126+ let module_data = & def_map[ def_map. crate_root ( self . db ) ] ;
127+
128+ let definition = module_data. origin . definition_source ( self . db ) ;
129+ let hir_file_id = definition. file_id ;
130+ let syntax_node = definition. value . node ( ) ;
131+ let ptr = SyntaxNodePtr :: new ( & syntax_node) ;
132+
133+ let loc = DeclarationLocation { hir_file_id, ptr, name_ptr : None } ;
134+
135+ self . symbols . insert ( FileSymbol {
136+ name : crate_name. symbol ( ) . clone ( ) ,
137+ def : ModuleDef :: Module ( module) ,
138+ loc,
139+ container_name : None ,
140+ is_alias : false ,
141+ is_assoc : false ,
142+ is_import : false ,
143+ do_not_complete : Complete :: Yes ,
144+ _marker : PhantomData ,
145+ } ) ;
146+
147+ if canonical_name != crate_name. symbol ( ) {
148+ self . symbols . insert ( FileSymbol {
149+ name : canonical_name. clone ( ) ,
150+ def : ModuleDef :: Module ( module) ,
151+ loc,
152+ container_name : None ,
153+ is_alias : false ,
154+ is_assoc : false ,
155+ is_import : false ,
156+ do_not_complete : Complete :: Yes ,
157+ _marker : PhantomData ,
158+ } ) ;
159+ }
160+ }
161+
111162 pub fn finish ( self ) -> Box < [ FileSymbol < ' a > ] > {
112163 self . symbols . into_iter ( ) . collect ( )
113164 }
@@ -209,7 +260,7 @@ impl<'a> SymbolCollector<'a> {
209260 let dec_loc = DeclarationLocation {
210261 hir_file_id : source. file_id ,
211262 ptr : SyntaxNodePtr :: new ( use_tree_src. syntax ( ) ) ,
212- name_ptr : AstPtr :: new ( & name_syntax) ,
263+ name_ptr : Some ( AstPtr :: new ( & name_syntax) ) ,
213264 } ;
214265 this. symbols . insert ( FileSymbol {
215266 name : name. symbol ( ) . clone ( ) ,
@@ -244,7 +295,7 @@ impl<'a> SymbolCollector<'a> {
244295 let dec_loc = DeclarationLocation {
245296 hir_file_id : source. file_id ,
246297 ptr : SyntaxNodePtr :: new ( source. value . syntax ( ) ) ,
247- name_ptr : AstPtr :: new ( & name_syntax) ,
298+ name_ptr : Some ( AstPtr :: new ( & name_syntax) ) ,
248299 } ;
249300 this. symbols . insert ( FileSymbol {
250301 name : name. symbol ( ) . clone ( ) ,
@@ -409,10 +460,10 @@ impl<'a> SymbolCollector<'a> {
409460 let source = loc. source ( self . db ) ;
410461 let Some ( name_node) = source. value . name ( ) else { return Complete :: Yes } ;
411462 let def = ModuleDef :: from ( id. into ( ) ) ;
412- let dec_loc = DeclarationLocation {
463+ let loc = DeclarationLocation {
413464 hir_file_id : source. file_id ,
414465 ptr : SyntaxNodePtr :: new ( source. value . syntax ( ) ) ,
415- name_ptr : AstPtr :: new ( & name_node) . wrap_left ( ) ,
466+ name_ptr : Some ( AstPtr :: new ( & name_node) . wrap_left ( ) ) ,
416467 } ;
417468
418469 let mut do_not_complete = Complete :: Yes ;
@@ -427,7 +478,7 @@ impl<'a> SymbolCollector<'a> {
427478 self . symbols . insert ( FileSymbol {
428479 name : alias. clone ( ) ,
429480 def,
430- loc : dec_loc . clone ( ) ,
481+ loc,
431482 container_name : self . current_container_name . clone ( ) ,
432483 is_alias : true ,
433484 is_assoc,
@@ -442,7 +493,7 @@ impl<'a> SymbolCollector<'a> {
442493 name : name. symbol ( ) . clone ( ) ,
443494 def,
444495 container_name : self . current_container_name . clone ( ) ,
445- loc : dec_loc ,
496+ loc,
446497 is_alias : false ,
447498 is_assoc,
448499 is_import : false ,
@@ -459,10 +510,10 @@ impl<'a> SymbolCollector<'a> {
459510 let Some ( declaration) = module_data. origin . declaration ( ) else { return } ;
460511 let module = declaration. to_node ( self . db ) ;
461512 let Some ( name_node) = module. name ( ) else { return } ;
462- let dec_loc = DeclarationLocation {
513+ let loc = DeclarationLocation {
463514 hir_file_id : declaration. file_id ,
464515 ptr : SyntaxNodePtr :: new ( module. syntax ( ) ) ,
465- name_ptr : AstPtr :: new ( & name_node) . wrap_left ( ) ,
516+ name_ptr : Some ( AstPtr :: new ( & name_node) . wrap_left ( ) ) ,
466517 } ;
467518
468519 let def = ModuleDef :: Module ( module_id. into ( ) ) ;
@@ -475,7 +526,7 @@ impl<'a> SymbolCollector<'a> {
475526 self . symbols . insert ( FileSymbol {
476527 name : alias. clone ( ) ,
477528 def,
478- loc : dec_loc . clone ( ) ,
529+ loc,
479530 container_name : self . current_container_name . clone ( ) ,
480531 is_alias : true ,
481532 is_assoc : false ,
@@ -490,7 +541,7 @@ impl<'a> SymbolCollector<'a> {
490541 name : name. symbol ( ) . clone ( ) ,
491542 def : ModuleDef :: Module ( module_id. into ( ) ) ,
492543 container_name : self . current_container_name . clone ( ) ,
493- loc : dec_loc ,
544+ loc,
494545 is_alias : false ,
495546 is_assoc : false ,
496547 is_import : false ,
0 commit comments