@@ -5,11 +5,12 @@ use hir_expand::name::Name;
5
5
use once_cell:: sync:: Lazy ;
6
6
use rustc_hash:: FxHashMap ;
7
7
8
- use crate :: { per_ns:: PerNs , BuiltinType , ImplId , MacroDefId , ModuleDefId , TraitId } ;
8
+ use crate :: { per_ns:: PerNs , AdtId , BuiltinType , ImplId , MacroDefId , ModuleDefId , TraitId } ;
9
9
10
10
#[ derive( Debug , Default , PartialEq , Eq ) ]
11
11
pub struct ItemScope {
12
- items : FxHashMap < Name , Resolution > ,
12
+ visible : FxHashMap < Name , PerNs > ,
13
+ defs : Vec < ModuleDefId > ,
13
14
impls : Vec < ImplId > ,
14
15
/// Macros visible in current module in legacy textual scope
15
16
///
@@ -26,12 +27,10 @@ pub struct ItemScope {
26
27
legacy_macros : FxHashMap < Name , MacroDefId > ,
27
28
}
28
29
29
- static BUILTIN_SCOPE : Lazy < FxHashMap < Name , Resolution > > = Lazy :: new ( || {
30
+ static BUILTIN_SCOPE : Lazy < FxHashMap < Name , PerNs > > = Lazy :: new ( || {
30
31
BuiltinType :: ALL
31
32
. iter ( )
32
- . map ( |( name, ty) | {
33
- ( name. clone ( ) , Resolution { def : PerNs :: types ( ty. clone ( ) . into ( ) ) , import : false } )
34
- } )
33
+ . map ( |( name, ty) | ( name. clone ( ) , PerNs :: types ( ty. clone ( ) . into ( ) ) ) )
35
34
. collect ( )
36
35
} ) ;
37
36
@@ -47,17 +46,13 @@ pub(crate) enum BuiltinShadowMode {
47
46
/// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
48
47
/// Other methods will only resolve values, types and module scoped macros only.
49
48
impl ItemScope {
50
- pub fn entries < ' a > ( & ' a self ) -> impl Iterator < Item = ( & ' a Name , & ' a Resolution ) > + ' a {
49
+ pub fn entries < ' a > ( & ' a self ) -> impl Iterator < Item = ( & ' a Name , PerNs ) > + ' a {
51
50
//FIXME: shadowing
52
- self . items . iter ( ) . chain ( BUILTIN_SCOPE . iter ( ) )
51
+ self . visible . iter ( ) . chain ( BUILTIN_SCOPE . iter ( ) ) . map ( | ( n , def ) | ( n , * def ) )
53
52
}
54
53
55
54
pub fn declarations ( & self ) -> impl Iterator < Item = ModuleDefId > + ' _ {
56
- self . entries ( )
57
- . filter_map ( |( _name, res) | if !res. import { Some ( res. def ) } else { None } )
58
- . flat_map ( |per_ns| {
59
- per_ns. take_types ( ) . into_iter ( ) . chain ( per_ns. take_values ( ) . into_iter ( ) )
60
- } )
55
+ self . defs . iter ( ) . copied ( )
61
56
}
62
57
63
58
pub fn impls ( & self ) -> impl Iterator < Item = ImplId > + ExactSizeIterator + ' _ {
@@ -66,9 +61,7 @@ impl ItemScope {
66
61
67
62
/// Iterate over all module scoped macros
68
63
pub ( crate ) fn macros < ' a > ( & ' a self ) -> impl Iterator < Item = ( & ' a Name , MacroDefId ) > + ' a {
69
- self . items
70
- . iter ( )
71
- . filter_map ( |( name, res) | res. def . take_macros ( ) . map ( |macro_| ( name, macro_) ) )
64
+ self . visible . iter ( ) . filter_map ( |( name, def) | def. take_macros ( ) . map ( |macro_| ( name, macro_) ) )
72
65
}
73
66
74
67
/// Iterate over all legacy textual scoped macros visible at the end of the module
@@ -77,13 +70,13 @@ impl ItemScope {
77
70
}
78
71
79
72
/// Get a name from current module scope, legacy macros are not included
80
- pub ( crate ) fn get ( & self , name : & Name , shadow : BuiltinShadowMode ) -> Option < & Resolution > {
73
+ pub ( crate ) fn get ( & self , name : & Name , shadow : BuiltinShadowMode ) -> Option < & PerNs > {
81
74
match shadow {
82
- BuiltinShadowMode :: Module => self . items . get ( name) . or_else ( || BUILTIN_SCOPE . get ( name) ) ,
75
+ BuiltinShadowMode :: Module => self . visible . get ( name) . or_else ( || BUILTIN_SCOPE . get ( name) ) ,
83
76
BuiltinShadowMode :: Other => {
84
- let item = self . items . get ( name) ;
85
- if let Some ( res ) = item {
86
- if let Some ( ModuleDefId :: ModuleId ( _) ) = res . def . take_types ( ) {
77
+ let item = self . visible . get ( name) ;
78
+ if let Some ( def ) = item {
79
+ if let Some ( ModuleDefId :: ModuleId ( _) ) = def. take_types ( ) {
87
80
return BUILTIN_SCOPE . get ( name) . or ( item) ;
88
81
}
89
82
}
@@ -94,12 +87,16 @@ impl ItemScope {
94
87
}
95
88
96
89
pub ( crate ) fn traits < ' a > ( & ' a self ) -> impl Iterator < Item = TraitId > + ' a {
97
- self . items . values ( ) . filter_map ( |r | match r . def . take_types ( ) {
90
+ self . visible . values ( ) . filter_map ( |def | match def. take_types ( ) {
98
91
Some ( ModuleDefId :: TraitId ( t) ) => Some ( t) ,
99
92
_ => None ,
100
93
} )
101
94
}
102
95
96
+ pub ( crate ) fn define_def ( & mut self , def : ModuleDefId ) {
97
+ self . defs . push ( def)
98
+ }
99
+
103
100
pub ( crate ) fn get_legacy_macro ( & self , name : & Name ) -> Option < MacroDefId > {
104
101
self . legacy_macros . get ( name) . copied ( )
105
102
}
@@ -112,44 +109,49 @@ impl ItemScope {
112
109
self . legacy_macros . insert ( name, mac) ;
113
110
}
114
111
115
- pub ( crate ) fn push_res ( & mut self , name : Name , res : & Resolution , import : bool ) -> bool {
112
+ pub ( crate ) fn push_res ( & mut self , name : Name , def : & PerNs ) -> bool {
116
113
let mut changed = false ;
117
- let existing = self . items . entry ( name. clone ( ) ) . or_default ( ) ;
114
+ let existing = self . visible . entry ( name. clone ( ) ) . or_default ( ) ;
118
115
119
- if existing. def . types . is_none ( ) && res. def . types . is_some ( ) {
120
- existing. def . types = res. def . types ;
121
- existing. import = import || res. import ;
116
+ if existing. types . is_none ( ) && def. types . is_some ( ) {
117
+ existing. types = def. types ;
122
118
changed = true ;
123
119
}
124
- if existing. def . values . is_none ( ) && res. def . values . is_some ( ) {
125
- existing. def . values = res. def . values ;
126
- existing. import = import || res. import ;
120
+ if existing. values . is_none ( ) && def. values . is_some ( ) {
121
+ existing. values = def. values ;
127
122
changed = true ;
128
123
}
129
- if existing. def . macros . is_none ( ) && res. def . macros . is_some ( ) {
130
- existing. def . macros = res. def . macros ;
131
- existing. import = import || res. import ;
124
+ if existing. macros . is_none ( ) && def. macros . is_some ( ) {
125
+ existing. macros = def. macros ;
132
126
changed = true ;
133
127
}
134
128
135
- if existing. def . is_none ( ) && res. def . is_none ( ) && !existing. import && res. import {
136
- existing. import = res. import ;
137
- }
138
129
changed
139
130
}
140
131
141
- pub ( crate ) fn collect_resolutions ( & self ) -> Vec < ( Name , Resolution ) > {
142
- self . items . iter ( ) . map ( |( name, res) | ( name. clone ( ) , res. clone ( ) ) ) . collect ( )
132
+ pub ( crate ) fn collect_resolutions ( & self ) -> Vec < ( Name , PerNs ) > {
133
+ self . visible . iter ( ) . map ( |( name, res) | ( name. clone ( ) , res. clone ( ) ) ) . collect ( )
143
134
}
144
135
145
136
pub ( crate ) fn collect_legacy_macros ( & self ) -> FxHashMap < Name , MacroDefId > {
146
137
self . legacy_macros . clone ( )
147
138
}
148
139
}
149
140
150
- #[ derive( Debug , Clone , PartialEq , Eq , Default ) ]
151
- pub struct Resolution {
152
- /// None for unresolved
153
- pub def : PerNs ,
154
- pub ( crate ) import : bool ,
141
+ impl From < ModuleDefId > for PerNs {
142
+ fn from ( def : ModuleDefId ) -> PerNs {
143
+ match def {
144
+ ModuleDefId :: ModuleId ( _) => PerNs :: types ( def) ,
145
+ ModuleDefId :: FunctionId ( _) => PerNs :: values ( def) ,
146
+ ModuleDefId :: AdtId ( adt) => match adt {
147
+ AdtId :: StructId ( _) | AdtId :: UnionId ( _) => PerNs :: both ( def, def) ,
148
+ AdtId :: EnumId ( _) => PerNs :: types ( def) ,
149
+ } ,
150
+ ModuleDefId :: EnumVariantId ( _) => PerNs :: both ( def, def) ,
151
+ ModuleDefId :: ConstId ( _) | ModuleDefId :: StaticId ( _) => PerNs :: values ( def) ,
152
+ ModuleDefId :: TraitId ( _) => PerNs :: types ( def) ,
153
+ ModuleDefId :: TypeAliasId ( _) => PerNs :: types ( def) ,
154
+ ModuleDefId :: BuiltinType ( _) => PerNs :: types ( def) ,
155
+ }
156
+ }
155
157
}
0 commit comments