@@ -11,6 +11,7 @@ use crate::middle::cstore::CrateStoreDyn;
11
11
12
12
use rustc_target:: spec:: abi:: Abi ;
13
13
use rustc_data_structures:: svh:: Svh ;
14
+ use rustc_data_structures:: indexed_vec:: IndexVec ;
14
15
use syntax:: ast:: { self , Name , NodeId } ;
15
16
use syntax:: source_map:: Spanned ;
16
17
use syntax:: ext:: base:: MacroKind ;
@@ -161,6 +162,8 @@ impl Forest {
161
162
}
162
163
}
163
164
165
+ pub ( super ) type HirMap < ' hir > = [ Vec < Option < IndexVec < ItemLocalId , Option < Entry < ' hir > > > > > ; 2 ] ;
166
+
164
167
/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
165
168
#[ derive( Clone ) ]
166
169
pub struct Map < ' hir > {
@@ -174,7 +177,7 @@ pub struct Map<'hir> {
174
177
/// The SVH of the local crate.
175
178
pub crate_hash : Svh ,
176
179
177
- map : FxHashMap < HirId , Entry < ' hir > > ,
180
+ map : HirMap < ' hir > ,
178
181
179
182
definitions : & ' hir Definitions ,
180
183
@@ -183,6 +186,12 @@ pub struct Map<'hir> {
183
186
}
184
187
185
188
impl < ' hir > Map < ' hir > {
189
+ #[ inline]
190
+ fn lookup ( & self , id : HirId ) -> Option < & Entry < ' hir > > {
191
+ let local_map = self . map [ id. owner . address_space ( ) . index ( ) ] . get ( id. owner . as_array_index ( ) ) ?;
192
+ local_map. as_ref ( ) ?. get ( id. local_id ) ?. as_ref ( )
193
+ }
194
+
186
195
/// Registers a read in the dependency graph of the AST node with
187
196
/// the given `id`. This needs to be called each time a public
188
197
/// function returns the HIR for a node -- in other words, when it
@@ -191,7 +200,7 @@ impl<'hir> Map<'hir> {
191
200
/// read recorded). If the function just returns a DefId or
192
201
/// NodeId, no actual content was returned, so no read is needed.
193
202
pub fn read ( & self , hir_id : HirId ) {
194
- if let Some ( entry) = self . map . get ( & hir_id) {
203
+ if let Some ( entry) = self . lookup ( hir_id) {
195
204
self . dep_graph . read_index ( entry. dep_node ) ;
196
205
} else {
197
206
bug ! ( "called `HirMap::read()` with invalid `HirId`: {:?}" , hir_id)
@@ -378,12 +387,8 @@ impl<'hir> Map<'hir> {
378
387
} )
379
388
}
380
389
381
- fn entry_count ( & self ) -> usize {
382
- self . map . len ( )
383
- }
384
-
385
390
fn find_entry ( & self , id : HirId ) -> Option < Entry < ' hir > > {
386
- self . map . get ( & id) . cloned ( )
391
+ self . lookup ( id) . cloned ( )
387
392
}
388
393
389
394
pub fn krate ( & self ) -> & ' hir Crate {
@@ -433,7 +438,7 @@ impl<'hir> Map<'hir> {
433
438
/// item (possibly associated), a closure, or a `hir::AnonConst`.
434
439
pub fn body_owner ( & self , BodyId { hir_id } : BodyId ) -> NodeId {
435
440
let parent = self . get_parent_node_by_hir_id ( hir_id) ;
436
- assert ! ( self . map . get ( & parent) . map_or( false , |e| e. is_body_owner( hir_id) ) ) ;
441
+ assert ! ( self . lookup ( parent) . map_or( false , |e| e. is_body_owner( hir_id) ) ) ;
437
442
self . hir_to_node_id ( parent)
438
443
}
439
444
@@ -1004,6 +1009,24 @@ impl<'hir> Map<'hir> {
1004
1009
attrs. unwrap_or ( & [ ] )
1005
1010
}
1006
1011
1012
+ /// Returns an iterator that yields all the hir ids in the map.
1013
+ fn all_ids < ' a > ( & ' a self ) -> impl Iterator < Item = HirId > + ' a {
1014
+ let map = & self . map ;
1015
+ let spaces = [ DefIndexAddressSpace :: Low , DefIndexAddressSpace :: High ] . iter ( ) . cloned ( ) ;
1016
+ spaces. flat_map ( move |space| {
1017
+ map[ space. index ( ) ] . iter ( ) . enumerate ( ) . filter_map ( |( i, local_map) | {
1018
+ local_map. as_ref ( ) . map ( |m| ( i, m) )
1019
+ } ) . flat_map ( move |( def_index, local_map) | {
1020
+ local_map. iter_enumerated ( ) . filter_map ( move |( i, entry) | entry. map ( move |_| {
1021
+ HirId {
1022
+ owner : DefIndex :: from_array_index ( def_index, space) ,
1023
+ local_id : i,
1024
+ }
1025
+ } ) )
1026
+ } )
1027
+ } )
1028
+ }
1029
+
1007
1030
/// Returns an iterator that yields the node id's with paths that
1008
1031
/// match `parts`. (Requires `parts` is non-empty.)
1009
1032
///
@@ -1012,13 +1035,16 @@ impl<'hir> Map<'hir> {
1012
1035
/// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
1013
1036
/// any other such items it can find in the map.
1014
1037
pub fn nodes_matching_suffix < ' a > ( & ' a self , parts : & ' a [ String ] )
1015
- -> NodesMatchingSuffix < ' a , ' hir > {
1016
- NodesMatchingSuffix {
1038
+ -> impl Iterator < Item = NodeId > + ' a {
1039
+ let nodes = NodesMatchingSuffix {
1017
1040
map : self ,
1018
1041
item_name : parts. last ( ) . unwrap ( ) ,
1019
1042
in_which : & parts[ ..parts. len ( ) - 1 ] ,
1020
- idx : ast:: CRATE_NODE_ID ,
1021
- }
1043
+ } ;
1044
+
1045
+ self . all_ids ( ) . filter ( move |hir| nodes. matces_suffix ( * hir) ) . map ( move |hir| {
1046
+ self . hir_to_node_id ( hir)
1047
+ } )
1022
1048
}
1023
1049
1024
1050
pub fn span ( & self , id : NodeId ) -> Span {
@@ -1097,21 +1123,20 @@ impl<'hir> Map<'hir> {
1097
1123
}
1098
1124
}
1099
1125
1100
- pub struct NodesMatchingSuffix < ' a , ' hir : ' a > {
1101
- map : & ' a Map < ' hir > ,
1126
+ pub struct NodesMatchingSuffix < ' a > {
1127
+ map : & ' a Map < ' a > ,
1102
1128
item_name : & ' a String ,
1103
1129
in_which : & ' a [ String ] ,
1104
- idx : NodeId ,
1105
1130
}
1106
1131
1107
- impl < ' a , ' hir > NodesMatchingSuffix < ' a , ' hir > {
1132
+ impl < ' a > NodesMatchingSuffix < ' a > {
1108
1133
/// Returns `true` only if some suffix of the module path for parent
1109
1134
/// matches `self.in_which`.
1110
1135
///
1111
1136
/// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
1112
1137
/// returns true if parent's path ends with the suffix
1113
1138
/// `x_0::x_1::...::x_k`.
1114
- fn suffix_matches ( & self , parent : NodeId ) -> bool {
1139
+ fn suffix_matches ( & self , parent : HirId ) -> bool {
1115
1140
let mut cursor = parent;
1116
1141
for part in self . in_which . iter ( ) . rev ( ) {
1117
1142
let ( mod_id, mod_name) = match find_first_mod_parent ( self . map , cursor) {
@@ -1121,7 +1146,7 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
1121
1146
if mod_name != & * * part {
1122
1147
return false ;
1123
1148
}
1124
- cursor = self . map . get_parent ( mod_id) ;
1149
+ cursor = self . map . get_parent_item ( mod_id) ;
1125
1150
}
1126
1151
return true ;
1127
1152
@@ -1131,14 +1156,14 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
1131
1156
// If `id` itself is a mod named `m` with parent `p`, then
1132
1157
// returns `Some(id, m, p)`. If `id` has no mod in its parent
1133
1158
// chain, then returns `None`.
1134
- fn find_first_mod_parent < ' a > ( map : & ' a Map < ' _ > , mut id : NodeId ) -> Option < ( NodeId , Name ) > {
1159
+ fn find_first_mod_parent < ' a > ( map : & ' a Map < ' _ > , mut id : HirId ) -> Option < ( HirId , Name ) > {
1135
1160
loop {
1136
- if let Node :: Item ( item) = map. find ( id) ? {
1161
+ if let Node :: Item ( item) = map. find_by_hir_id ( id) ? {
1137
1162
if item_is_mod ( & item) {
1138
1163
return Some ( ( id, item. ident . name ) )
1139
1164
}
1140
1165
}
1141
- let parent = map. get_parent ( id) ;
1166
+ let parent = map. get_parent_item ( id) ;
1142
1167
if parent == id { return None }
1143
1168
id = parent;
1144
1169
}
@@ -1154,35 +1179,21 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
1154
1179
1155
1180
// We are looking at some node `n` with a given name and parent
1156
1181
// id; do their names match what I am seeking?
1157
- fn matches_names ( & self , parent_of_n : NodeId , name : Name ) -> bool {
1182
+ fn matches_names ( & self , parent_of_n : HirId , name : Name ) -> bool {
1158
1183
name == & * * self . item_name && self . suffix_matches ( parent_of_n)
1159
1184
}
1160
- }
1161
1185
1162
- impl < ' a , ' hir > Iterator for NodesMatchingSuffix < ' a , ' hir > {
1163
- type Item = NodeId ;
1164
-
1165
- fn next ( & mut self ) -> Option < NodeId > {
1166
- loop {
1167
- let idx = self . idx ;
1168
- if idx. as_usize ( ) >= self . map . entry_count ( ) {
1169
- return None ;
1170
- }
1171
- self . idx = NodeId :: from_u32 ( self . idx . as_u32 ( ) + 1 ) ;
1172
- let hir_idx = self . map . node_to_hir_id ( idx) ;
1173
- let name = match self . map . find_entry ( hir_idx) . map ( |entry| entry. node ) {
1174
- Some ( Node :: Item ( n) ) => n. name ( ) ,
1175
- Some ( Node :: ForeignItem ( n) ) => n. name ( ) ,
1176
- Some ( Node :: TraitItem ( n) ) => n. name ( ) ,
1177
- Some ( Node :: ImplItem ( n) ) => n. name ( ) ,
1178
- Some ( Node :: Variant ( n) ) => n. name ( ) ,
1179
- Some ( Node :: Field ( n) ) => n. name ( ) ,
1180
- _ => continue ,
1181
- } ;
1182
- if self . matches_names ( self . map . get_parent ( idx) , name) {
1183
- return Some ( idx)
1184
- }
1185
- }
1186
+ fn matces_suffix ( & self , hir : HirId ) -> bool {
1187
+ let name = match self . map . find_entry ( hir) . map ( |entry| entry. node ) {
1188
+ Some ( Node :: Item ( n) ) => n. name ( ) ,
1189
+ Some ( Node :: ForeignItem ( n) ) => n. name ( ) ,
1190
+ Some ( Node :: TraitItem ( n) ) => n. name ( ) ,
1191
+ Some ( Node :: ImplItem ( n) ) => n. name ( ) ,
1192
+ Some ( Node :: Variant ( n) ) => n. name ( ) ,
1193
+ Some ( Node :: Field ( n) ) => n. name ( ) ,
1194
+ _ => return false ,
1195
+ } ;
1196
+ self . matches_names ( self . map . get_parent_item ( hir) , name)
1186
1197
}
1187
1198
}
1188
1199
0 commit comments