@@ -11,6 +11,7 @@ use crate::middle::cstore::CrateStoreDyn;
1111
1212use rustc_target:: spec:: abi:: Abi ;
1313use rustc_data_structures:: svh:: Svh ;
14+ use rustc_data_structures:: indexed_vec:: IndexVec ;
1415use syntax:: ast:: { self , Name , NodeId } ;
1516use syntax:: source_map:: Spanned ;
1617use syntax:: ext:: base:: MacroKind ;
@@ -161,6 +162,8 @@ impl Forest {
161162 }
162163}
163164
165+ pub ( super ) type HirMap < ' hir > = [ Vec < Option < IndexVec < ItemLocalId , Option < Entry < ' hir > > > > > ; 2 ] ;
166+
164167/// Represents a mapping from `NodeId`s to AST elements and their parent `NodeId`s.
165168#[ derive( Clone ) ]
166169pub struct Map < ' hir > {
@@ -174,7 +177,7 @@ pub struct Map<'hir> {
174177 /// The SVH of the local crate.
175178 pub crate_hash : Svh ,
176179
177- map : FxHashMap < HirId , Entry < ' hir > > ,
180+ map : HirMap < ' hir > ,
178181
179182 definitions : & ' hir Definitions ,
180183
@@ -183,6 +186,12 @@ pub struct Map<'hir> {
183186}
184187
185188impl < ' 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+
186195 /// Registers a read in the dependency graph of the AST node with
187196 /// the given `id`. This needs to be called each time a public
188197 /// function returns the HIR for a node -- in other words, when it
@@ -191,7 +200,7 @@ impl<'hir> Map<'hir> {
191200 /// read recorded). If the function just returns a DefId or
192201 /// NodeId, no actual content was returned, so no read is needed.
193202 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) {
195204 self . dep_graph . read_index ( entry. dep_node ) ;
196205 } else {
197206 bug ! ( "called `HirMap::read()` with invalid `HirId`: {:?}" , hir_id)
@@ -378,12 +387,8 @@ impl<'hir> Map<'hir> {
378387 } )
379388 }
380389
381- fn entry_count ( & self ) -> usize {
382- self . map . len ( )
383- }
384-
385390 fn find_entry ( & self , id : HirId ) -> Option < Entry < ' hir > > {
386- self . map . get ( & id) . cloned ( )
391+ self . lookup ( id) . cloned ( )
387392 }
388393
389394 pub fn krate ( & self ) -> & ' hir Crate {
@@ -433,7 +438,7 @@ impl<'hir> Map<'hir> {
433438 /// item (possibly associated), a closure, or a `hir::AnonConst`.
434439 pub fn body_owner ( & self , BodyId { hir_id } : BodyId ) -> NodeId {
435440 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) ) ) ;
437442 self . hir_to_node_id ( parent)
438443 }
439444
@@ -1004,6 +1009,24 @@ impl<'hir> Map<'hir> {
10041009 attrs. unwrap_or ( & [ ] )
10051010 }
10061011
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+
10071030 /// Returns an iterator that yields the node id's with paths that
10081031 /// match `parts`. (Requires `parts` is non-empty.)
10091032 ///
@@ -1012,13 +1035,16 @@ impl<'hir> Map<'hir> {
10121035 /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and
10131036 /// any other such items it can find in the map.
10141037 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 {
10171040 map : self ,
10181041 item_name : parts. last ( ) . unwrap ( ) ,
10191042 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+ } )
10221048 }
10231049
10241050 pub fn span ( & self , id : NodeId ) -> Span {
@@ -1097,21 +1123,20 @@ impl<'hir> Map<'hir> {
10971123 }
10981124}
10991125
1100- pub struct NodesMatchingSuffix < ' a , ' hir : ' a > {
1101- map : & ' a Map < ' hir > ,
1126+ pub struct NodesMatchingSuffix < ' a > {
1127+ map : & ' a Map < ' a > ,
11021128 item_name : & ' a String ,
11031129 in_which : & ' a [ String ] ,
1104- idx : NodeId ,
11051130}
11061131
1107- impl < ' a , ' hir > NodesMatchingSuffix < ' a , ' hir > {
1132+ impl < ' a > NodesMatchingSuffix < ' a > {
11081133 /// Returns `true` only if some suffix of the module path for parent
11091134 /// matches `self.in_which`.
11101135 ///
11111136 /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`;
11121137 /// returns true if parent's path ends with the suffix
11131138 /// `x_0::x_1::...::x_k`.
1114- fn suffix_matches ( & self , parent : NodeId ) -> bool {
1139+ fn suffix_matches ( & self , parent : HirId ) -> bool {
11151140 let mut cursor = parent;
11161141 for part in self . in_which . iter ( ) . rev ( ) {
11171142 let ( mod_id, mod_name) = match find_first_mod_parent ( self . map , cursor) {
@@ -1121,7 +1146,7 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
11211146 if mod_name != & * * part {
11221147 return false ;
11231148 }
1124- cursor = self . map . get_parent ( mod_id) ;
1149+ cursor = self . map . get_parent_item ( mod_id) ;
11251150 }
11261151 return true ;
11271152
@@ -1131,14 +1156,14 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
11311156 // If `id` itself is a mod named `m` with parent `p`, then
11321157 // returns `Some(id, m, p)`. If `id` has no mod in its parent
11331158 // 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 ) > {
11351160 loop {
1136- if let Node :: Item ( item) = map. find ( id) ? {
1161+ if let Node :: Item ( item) = map. find_by_hir_id ( id) ? {
11371162 if item_is_mod ( & item) {
11381163 return Some ( ( id, item. ident . name ) )
11391164 }
11401165 }
1141- let parent = map. get_parent ( id) ;
1166+ let parent = map. get_parent_item ( id) ;
11421167 if parent == id { return None }
11431168 id = parent;
11441169 }
@@ -1154,35 +1179,21 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> {
11541179
11551180 // We are looking at some node `n` with a given name and parent
11561181 // 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 {
11581183 name == & * * self . item_name && self . suffix_matches ( parent_of_n)
11591184 }
1160- }
11611185
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)
11861197 }
11871198}
11881199
0 commit comments