@@ -12,11 +12,11 @@ use rustc_hir::def_id::LOCAL_CRATE;
1212use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId } ;
1313use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
1414use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
15- use rustc_hir:: { HirIdSet , Node } ;
15+ use rustc_hir:: Node ;
1616use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
1717use rustc_middle:: middle:: privacy;
1818use rustc_middle:: ty:: query:: Providers ;
19- use rustc_middle:: ty:: { self , TyCtxt } ;
19+ use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
2020use rustc_session:: config:: CrateType ;
2121use rustc_target:: spec:: abi:: Abi ;
2222
@@ -65,10 +65,11 @@ struct ReachableContext<'tcx> {
6565 tcx : TyCtxt < ' tcx > ,
6666 maybe_typeck_results : Option < & ' tcx ty:: TypeckResults < ' tcx > > ,
6767 // The set of items which must be exported in the linkage sense.
68- reachable_symbols : HirIdSet ,
68+ reachable_symbols : FxHashSet < LocalDefId > ,
6969 // A worklist of item IDs. Each item ID in this worklist will be inlined
7070 // and will be scanned for further references.
71- worklist : Vec < hir:: HirId > ,
71+ // FIXME(eddyb) benchmark if this would be faster as a `VecDeque`.
72+ worklist : Vec < LocalDefId > ,
7273 // Whether any output of this compilation is a library
7374 any_library : bool ,
7475}
@@ -100,37 +101,27 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
100101 _ => None ,
101102 } ;
102103
103- match res {
104- Some ( Res :: Local ( hir_id) ) => {
105- self . reachable_symbols . insert ( hir_id) ;
106- }
107- Some ( res) => {
108- if let Some ( ( hir_id, def_id) ) = res. opt_def_id ( ) . and_then ( |def_id| {
109- def_id
110- . as_local ( )
111- . map ( |def_id| ( self . tcx . hir ( ) . local_def_id_to_hir_id ( def_id) , def_id) )
112- } ) {
113- if self . def_id_represents_local_inlined_item ( def_id. to_def_id ( ) ) {
114- self . worklist . push ( hir_id) ;
115- } else {
116- match res {
117- // If this path leads to a constant, then we need to
118- // recurse into the constant to continue finding
119- // items that are reachable.
120- Res :: Def ( DefKind :: Const | DefKind :: AssocConst , _) => {
121- self . worklist . push ( hir_id) ;
122- }
104+ if let Some ( res) = res {
105+ if let Some ( def_id) = res. opt_def_id ( ) . and_then ( |def_id| def_id. as_local ( ) ) {
106+ if self . def_id_represents_local_inlined_item ( def_id. to_def_id ( ) ) {
107+ self . worklist . push ( def_id) ;
108+ } else {
109+ match res {
110+ // If this path leads to a constant, then we need to
111+ // recurse into the constant to continue finding
112+ // items that are reachable.
113+ Res :: Def ( DefKind :: Const | DefKind :: AssocConst , _) => {
114+ self . worklist . push ( def_id) ;
115+ }
123116
124- // If this wasn't a static, then the destination is
125- // surely reachable.
126- _ => {
127- self . reachable_symbols . insert ( hir_id) ;
128- }
117+ // If this wasn't a static, then the destination is
118+ // surely reachable.
119+ _ => {
120+ self . reachable_symbols . insert ( def_id) ;
129121 }
130122 }
131123 }
132124 }
133- _ => { }
134125 }
135126
136127 intravisit:: walk_expr ( self , expr)
@@ -209,13 +200,15 @@ impl<'tcx> ReachableContext<'tcx> {
209200 continue ;
210201 }
211202
212- if let Some ( ref item) = self . tcx . hir ( ) . find ( search_item) {
203+ if let Some ( ref item) =
204+ self . tcx . hir ( ) . find ( self . tcx . hir ( ) . local_def_id_to_hir_id ( search_item) )
205+ {
213206 self . propagate_node ( item, search_item) ;
214207 }
215208 }
216209 }
217210
218- fn propagate_node ( & mut self , node : & Node < ' tcx > , search_item : hir :: HirId ) {
211+ fn propagate_node ( & mut self , node : & Node < ' tcx > , search_item : LocalDefId ) {
219212 if !self . any_library {
220213 // If we are building an executable, only explicitly extern
221214 // types need to be exported.
@@ -297,8 +290,9 @@ impl<'tcx> ReachableContext<'tcx> {
297290 self . visit_nested_body ( body) ;
298291 }
299292 hir:: ImplItemKind :: Fn ( _, body) => {
300- let did = self . tcx . hir ( ) . get_parent_did ( search_item) ;
301- if method_might_be_inlined ( self . tcx , impl_item, did) {
293+ let impl_def_id =
294+ self . tcx . parent ( search_item. to_def_id ( ) ) . unwrap ( ) . expect_local ( ) ;
295+ if method_might_be_inlined ( self . tcx , impl_item, impl_def_id) {
302296 self . visit_nested_body ( body)
303297 }
304298 }
@@ -317,7 +311,9 @@ impl<'tcx> ReachableContext<'tcx> {
317311 _ => {
318312 bug ! (
319313 "found unexpected node kind in worklist: {} ({:?})" ,
320- self . tcx. hir( ) . node_to_string( search_item) ,
314+ self . tcx
315+ . hir( )
316+ . node_to_string( self . tcx. hir( ) . local_def_id_to_hir_id( search_item) ) ,
321317 node,
322318 ) ;
323319 }
@@ -336,7 +332,7 @@ impl<'tcx> ReachableContext<'tcx> {
336332struct CollectPrivateImplItemsVisitor < ' a , ' tcx > {
337333 tcx : TyCtxt < ' tcx > ,
338334 access_levels : & ' a privacy:: AccessLevels ,
339- worklist : & ' a mut Vec < hir :: HirId > ,
335+ worklist : & ' a mut Vec < LocalDefId > ,
340336}
341337
342338impl < ' a , ' tcx > ItemLikeVisitor < ' tcx > for CollectPrivateImplItemsVisitor < ' a , ' tcx > {
@@ -349,13 +345,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
349345 if codegen_attrs. contains_extern_indicator ( )
350346 || codegen_attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_STD_INTERNAL_SYMBOL )
351347 {
352- self . worklist . push ( item . hir_id ) ;
348+ self . worklist . push ( def_id ) ;
353349 }
354350
355351 // We need only trait impls here, not inherent impls, and only non-exported ones
356352 if let hir:: ItemKind :: Impl { of_trait : Some ( ref trait_ref) , ref items, .. } = item. kind {
357353 if !self . access_levels . is_reachable ( item. hir_id ) {
358- self . worklist . extend ( items. iter ( ) . map ( |ii_ref| ii_ref. id . hir_id ) ) ;
354+ // FIXME(#53488) remove `let`
355+ let tcx = self . tcx ;
356+ self . worklist
357+ . extend ( items. iter ( ) . map ( |ii_ref| tcx. hir ( ) . local_def_id ( ii_ref. id . hir_id ) ) ) ;
359358
360359 let trait_def_id = match trait_ref. path . res {
361360 Res :: Def ( DefKind :: Trait , def_id) => def_id,
@@ -366,12 +365,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
366365 return ;
367366 }
368367
369- // FIXME(#53488) remove `let`
370- let tcx = self . tcx ;
371- self . worklist
372- . extend ( tcx. provided_trait_methods ( trait_def_id) . map ( |assoc| {
373- tcx. hir ( ) . local_def_id_to_hir_id ( assoc. def_id . expect_local ( ) )
374- } ) ) ;
368+ self . worklist . extend (
369+ tcx. provided_trait_methods ( trait_def_id)
370+ . map ( |assoc| assoc. def_id . expect_local ( ) ) ,
371+ ) ;
375372 }
376373 }
377374 }
@@ -383,7 +380,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
383380 }
384381}
385382
386- fn reachable_set < ' tcx > ( tcx : TyCtxt < ' tcx > , crate_num : CrateNum ) -> & ' tcx HirIdSet {
383+ fn reachable_set < ' tcx > ( tcx : TyCtxt < ' tcx > , crate_num : CrateNum ) -> FxHashSet < LocalDefId > {
387384 debug_assert ! ( crate_num == LOCAL_CRATE ) ;
388385
389386 let access_levels = & tcx. privacy_access_levels ( LOCAL_CRATE ) ;
@@ -405,11 +402,13 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
405402 // If other crates link to us, they're going to expect to be able to
406403 // use the lang items, so we need to be sure to mark them as
407404 // exported.
408- reachable_context. worklist . extend ( access_levels. map . iter ( ) . map ( |( id, _) | * id) ) ;
405+ reachable_context
406+ . worklist
407+ . extend ( access_levels. map . iter ( ) . map ( |( id, _) | tcx. hir ( ) . local_def_id ( * id) ) ) ;
409408 for item in tcx. lang_items ( ) . items ( ) . iter ( ) {
410- if let Some ( did ) = * item {
411- if let Some ( hir_id ) = did . as_local ( ) . map ( |did| tcx . hir ( ) . local_def_id_to_hir_id ( did ) ) {
412- reachable_context. worklist . push ( hir_id ) ;
409+ if let Some ( def_id ) = * item {
410+ if let Some ( def_id ) = def_id . as_local ( ) {
411+ reachable_context. worklist . push ( def_id ) ;
413412 }
414413 }
415414 }
@@ -428,7 +427,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
428427 debug ! ( "Inline reachability shows: {:?}" , reachable_context. reachable_symbols) ;
429428
430429 // Return the set of reachable symbols.
431- tcx . arena . alloc ( reachable_context. reachable_symbols )
430+ reachable_context. reachable_symbols
432431}
433432
434433pub fn provide ( providers : & mut Providers ) {
0 commit comments