@@ -6,6 +6,7 @@ use std::collections::hash_map::Entry;
66use base_db:: CrateId ;
77use hir_expand:: { attrs:: AttrId , db:: ExpandDatabase , name:: Name , AstId , MacroCallId } ;
88use itertools:: Itertools ;
9+ use la_arena:: Idx ;
910use once_cell:: sync:: Lazy ;
1011use profile:: Count ;
1112use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -32,15 +33,50 @@ pub struct PerNsGlobImports {
3233 macros : FxHashSet < ( LocalModuleId , Name ) > ,
3334}
3435
36+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
37+ pub enum ImportOrExternCrate {
38+ Import ( ImportId ) ,
39+ Glob ( UseId ) ,
40+ ExternCrate ( ExternCrateId ) ,
41+ }
42+
43+ impl ImportOrExternCrate {
44+ pub fn into_import ( self ) -> Option < ImportId > {
45+ match self {
46+ ImportOrExternCrate :: Import ( it) => Some ( it) ,
47+ _ => None ,
48+ }
49+ }
50+
51+ pub fn into_glob ( self ) -> Option < UseId > {
52+ match self {
53+ ImportOrExternCrate :: Glob ( it) => Some ( it) ,
54+ _ => None ,
55+ }
56+ }
57+ }
58+
59+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
60+ pub enum ImportOrDef {
61+ Import ( ImportId ) ,
62+ ExternCrate ( ExternCrateId ) ,
63+ Def ( ModuleDefId ) ,
64+ }
65+ #[ derive( Debug , Copy , Clone , PartialEq , Eq , Hash ) ]
66+ pub struct ImportId {
67+ pub import : UseId ,
68+ pub idx : Idx < ast:: UseTree > ,
69+ }
70+
3571#[ derive( Debug , Default , PartialEq , Eq ) ]
3672pub struct ItemScope {
3773 _c : Count < Self > ,
3874
3975 /// Defs visible in this scope. This includes `declarations`, but also
4076 /// imports.
41- types : FxHashMap < Name , ( ModuleDefId , Visibility ) > ,
42- values : FxHashMap < Name , ( ModuleDefId , Visibility ) > ,
43- macros : FxHashMap < Name , ( MacroId , Visibility ) > ,
77+ types : FxHashMap < Name , ( ModuleDefId , Visibility , Option < ImportOrExternCrate > ) > ,
78+ values : FxHashMap < Name , ( ModuleDefId , Visibility , Option < ImportId > ) > ,
79+ macros : FxHashMap < Name , ( MacroId , Visibility , Option < ImportId > ) > ,
4480 unresolved : FxHashSet < Name > ,
4581
4682 /// The defs declared in this scope. Each def has a single scope where it is
@@ -50,7 +86,14 @@ pub struct ItemScope {
5086 impls : Vec < ImplId > ,
5187 unnamed_consts : Vec < ConstId > ,
5288 /// Traits imported via `use Trait as _;`.
53- unnamed_trait_imports : FxHashMap < TraitId , Visibility > ,
89+ unnamed_trait_imports : FxHashMap < TraitId , ( Visibility , Option < ImportId > ) > ,
90+
91+ // the resolutions of the imports of this scope
92+ use_imports_types : FxHashMap < UseId , ImportOrDef > ,
93+ use_imports_values : FxHashMap < UseId , ImportOrDef > ,
94+ use_imports_macros : FxHashMap < UseId , ImportOrDef > ,
95+
96+ use_decls : Vec < UseId > ,
5497 extern_crate_decls : Vec < ExternCrateId > ,
5598 /// Macros visible in current module in legacy textual scope
5699 ///
@@ -121,8 +164,7 @@ impl ItemScope {
121164 }
122165
123166 pub fn use_decls ( & self ) -> impl Iterator < Item = UseId > + ExactSizeIterator + ' _ {
124- // FIXME: to be implemented
125- std:: iter:: empty ( )
167+ self . use_decls . iter ( ) . copied ( )
126168 }
127169
128170 pub fn impls ( & self ) -> impl Iterator < Item = ImplId > + ExactSizeIterator + ' _ {
@@ -132,13 +174,13 @@ impl ItemScope {
132174 pub fn values (
133175 & self ,
134176 ) -> impl Iterator < Item = ( ModuleDefId , Visibility ) > + ExactSizeIterator + ' _ {
135- self . values . values ( ) . copied ( )
177+ self . values . values ( ) . copied ( ) . map ( | ( a , b , _ ) | ( a , b ) )
136178 }
137179
138- pub fn types (
180+ pub ( crate ) fn types (
139181 & self ,
140182 ) -> impl Iterator < Item = ( ModuleDefId , Visibility ) > + ExactSizeIterator + ' _ {
141- self . types . values ( ) . copied ( )
183+ self . types . values ( ) . copied ( ) . map ( | ( def , vis , _ ) | ( def , vis ) )
142184 }
143185
144186 pub fn unnamed_consts ( & self ) -> impl Iterator < Item = ConstId > + ' _ {
@@ -165,33 +207,48 @@ impl ItemScope {
165207 }
166208
167209 pub ( crate ) fn type_ ( & self , name : & Name ) -> Option < ( ModuleDefId , Visibility ) > {
168- self . types . get ( name) . copied ( )
210+ self . types . get ( name) . copied ( ) . map ( | ( a , b , _ ) | ( a , b ) )
169211 }
170212
171213 /// XXX: this is O(N) rather than O(1), try to not introduce new usages.
172214 pub ( crate ) fn name_of ( & self , item : ItemInNs ) -> Option < ( & Name , Visibility ) > {
173- let ( def, mut iter) = match item {
174- ItemInNs :: Macros ( def) => {
175- return self . macros . iter ( ) . find_map ( |( name, & ( other_def, vis) ) | {
176- ( other_def == def) . then_some ( ( name, vis) )
177- } ) ;
178- }
179- ItemInNs :: Types ( def) => ( def, self . types . iter ( ) ) ,
180- ItemInNs :: Values ( def) => ( def, self . values . iter ( ) ) ,
181- } ;
182- iter. find_map ( |( name, & ( other_def, vis) ) | ( other_def == def) . then_some ( ( name, vis) ) )
215+ match item {
216+ ItemInNs :: Macros ( def) => self
217+ . macros
218+ . iter ( )
219+ . find_map ( |( name, & ( other_def, vis, _) ) | ( other_def == def) . then_some ( ( name, vis) ) ) ,
220+ ItemInNs :: Types ( def) => self
221+ . types
222+ . iter ( )
223+ . find_map ( |( name, & ( other_def, vis, _) ) | ( other_def == def) . then_some ( ( name, vis) ) ) ,
224+
225+ ItemInNs :: Values ( def) => self
226+ . values
227+ . iter ( )
228+ . find_map ( |( name, & ( other_def, vis, _) ) | ( other_def == def) . then_some ( ( name, vis) ) ) ,
229+ }
183230 }
184231
185232 pub ( crate ) fn traits ( & self ) -> impl Iterator < Item = TraitId > + ' _ {
186233 self . types
187234 . values ( )
188- . filter_map ( |& ( def, _) | match def {
235+ . filter_map ( |& ( def, _, _ ) | match def {
189236 ModuleDefId :: TraitId ( t) => Some ( t) ,
190237 _ => None ,
191238 } )
192239 . chain ( self . unnamed_trait_imports . keys ( ) . copied ( ) )
193240 }
194241
242+ pub ( crate ) fn resolutions ( & self ) -> impl Iterator < Item = ( Option < Name > , PerNs ) > + ' _ {
243+ self . entries ( ) . map ( |( name, res) | ( Some ( name. clone ( ) ) , res) ) . chain (
244+ self . unnamed_trait_imports
245+ . iter ( )
246+ . map ( |( tr, ( vis, _) ) | ( None , PerNs :: types ( ModuleDefId :: TraitId ( * tr) , * vis) ) ) ,
247+ )
248+ }
249+ }
250+
251+ impl ItemScope {
195252 pub ( crate ) fn declare ( & mut self , def : ModuleDefId ) {
196253 self . declarations . push ( def)
197254 }
@@ -278,11 +335,11 @@ impl ItemScope {
278335 }
279336
280337 pub ( crate ) fn unnamed_trait_vis ( & self , tr : TraitId ) -> Option < Visibility > {
281- self . unnamed_trait_imports . get ( & tr) . copied ( )
338+ self . unnamed_trait_imports . get ( & tr) . copied ( ) . map ( | ( a , _ ) | a )
282339 }
283340
284341 pub ( crate ) fn push_unnamed_trait ( & mut self , tr : TraitId , vis : Visibility ) {
285- self . unnamed_trait_imports . insert ( tr, vis) ;
342+ self . unnamed_trait_imports . insert ( tr, ( vis, None ) ) ;
286343 }
287344
288345 pub ( crate ) fn push_res_with_import (
@@ -343,27 +400,18 @@ impl ItemScope {
343400 changed
344401 }
345402
346- pub ( crate ) fn resolutions ( & self ) -> impl Iterator < Item = ( Option < Name > , PerNs ) > + ' _ {
347- self . entries ( ) . map ( |( name, res) | ( Some ( name. clone ( ) ) , res) ) . chain (
348- self . unnamed_trait_imports
349- . iter ( )
350- . map ( |( tr, vis) | ( None , PerNs :: types ( ModuleDefId :: TraitId ( * tr) , * vis) ) ) ,
351- )
352- }
353-
354403 /// Marks everything that is not a procedural macro as private to `this_module`.
355404 pub ( crate ) fn censor_non_proc_macros ( & mut self , this_module : ModuleId ) {
356405 self . types
357406 . values_mut ( )
358- . chain ( self . values . values_mut ( ) )
407+ . map ( |( def, vis, _) | ( def, vis) )
408+ . chain ( self . values . values_mut ( ) . map ( |( def, vis, _) | ( def, vis) ) )
359409 . map ( |( _, v) | v)
360- . chain ( self . unnamed_trait_imports . values_mut ( ) )
410+ . chain ( self . unnamed_trait_imports . values_mut ( ) . map ( | ( vis , _ ) | vis ) )
361411 . for_each ( |vis| * vis = Visibility :: Module ( this_module) ) ;
362412
363- for ( mac, vis) in self . macros . values_mut ( ) {
364- if let MacroId :: ProcMacroId ( _) = mac {
365- // FIXME: Technically this is insufficient since reexports of proc macros are also
366- // forbidden. Practically nobody does that.
413+ for ( mac, vis, import) in self . macros . values_mut ( ) {
414+ if matches ! ( mac, MacroId :: ProcMacroId ( _) if import. is_none( ) ) {
367415 continue ;
368416 }
369417
@@ -415,10 +463,17 @@ impl ItemScope {
415463 attr_macros,
416464 derive_macros,
417465 extern_crate_decls,
466+ use_decls,
467+ use_imports_values,
468+ use_imports_types,
469+ use_imports_macros,
418470 } = self ;
419471 types. shrink_to_fit ( ) ;
420472 values. shrink_to_fit ( ) ;
421473 macros. shrink_to_fit ( ) ;
474+ use_imports_types. shrink_to_fit ( ) ;
475+ use_imports_values. shrink_to_fit ( ) ;
476+ use_imports_macros. shrink_to_fit ( ) ;
422477 unresolved. shrink_to_fit ( ) ;
423478 declarations. shrink_to_fit ( ) ;
424479 impls. shrink_to_fit ( ) ;
@@ -428,6 +483,7 @@ impl ItemScope {
428483 attr_macros. shrink_to_fit ( ) ;
429484 derive_macros. shrink_to_fit ( ) ;
430485 extern_crate_decls. shrink_to_fit ( ) ;
486+ use_decls. shrink_to_fit ( ) ;
431487 }
432488}
433489
0 commit comments