@@ -12,11 +12,11 @@ use rustc_hir::def_id::LOCAL_CRATE;
12
12
use rustc_hir:: def_id:: { CrateNum , DefId , LocalDefId } ;
13
13
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
14
14
use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
15
- use rustc_hir:: { HirIdSet , Node } ;
15
+ use rustc_hir:: Node ;
16
16
use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
17
17
use rustc_middle:: middle:: privacy;
18
18
use rustc_middle:: ty:: query:: Providers ;
19
- use rustc_middle:: ty:: { self , TyCtxt } ;
19
+ use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
20
20
use rustc_session:: config:: CrateType ;
21
21
use rustc_target:: spec:: abi:: Abi ;
22
22
@@ -65,10 +65,11 @@ struct ReachableContext<'tcx> {
65
65
tcx : TyCtxt < ' tcx > ,
66
66
maybe_typeck_results : Option < & ' tcx ty:: TypeckResults < ' tcx > > ,
67
67
// The set of items which must be exported in the linkage sense.
68
- reachable_symbols : HirIdSet ,
68
+ reachable_symbols : FxHashSet < LocalDefId > ,
69
69
// A worklist of item IDs. Each item ID in this worklist will be inlined
70
70
// 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 > ,
72
73
// Whether any output of this compilation is a library
73
74
any_library : bool ,
74
75
}
@@ -100,37 +101,27 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> {
100
101
_ => None ,
101
102
} ;
102
103
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
+ }
123
116
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) ;
129
121
}
130
122
}
131
123
}
132
124
}
133
- _ => { }
134
125
}
135
126
136
127
intravisit:: walk_expr ( self , expr)
@@ -209,13 +200,15 @@ impl<'tcx> ReachableContext<'tcx> {
209
200
continue ;
210
201
}
211
202
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
+ {
213
206
self . propagate_node ( item, search_item) ;
214
207
}
215
208
}
216
209
}
217
210
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 ) {
219
212
if !self . any_library {
220
213
// If we are building an executable, only explicitly extern
221
214
// types need to be exported.
@@ -297,8 +290,9 @@ impl<'tcx> ReachableContext<'tcx> {
297
290
self . visit_nested_body ( body) ;
298
291
}
299
292
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) {
302
296
self . visit_nested_body ( body)
303
297
}
304
298
}
@@ -317,7 +311,9 @@ impl<'tcx> ReachableContext<'tcx> {
317
311
_ => {
318
312
bug ! (
319
313
"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) ) ,
321
317
node,
322
318
) ;
323
319
}
@@ -336,7 +332,7 @@ impl<'tcx> ReachableContext<'tcx> {
336
332
struct CollectPrivateImplItemsVisitor < ' a , ' tcx > {
337
333
tcx : TyCtxt < ' tcx > ,
338
334
access_levels : & ' a privacy:: AccessLevels ,
339
- worklist : & ' a mut Vec < hir :: HirId > ,
335
+ worklist : & ' a mut Vec < LocalDefId > ,
340
336
}
341
337
342
338
impl < ' a , ' tcx > ItemLikeVisitor < ' tcx > for CollectPrivateImplItemsVisitor < ' a , ' tcx > {
@@ -349,13 +345,16 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
349
345
if codegen_attrs. contains_extern_indicator ( )
350
346
|| codegen_attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_STD_INTERNAL_SYMBOL )
351
347
{
352
- self . worklist . push ( item . hir_id ) ;
348
+ self . worklist . push ( def_id ) ;
353
349
}
354
350
355
351
// We need only trait impls here, not inherent impls, and only non-exported ones
356
352
if let hir:: ItemKind :: Impl { of_trait : Some ( ref trait_ref) , ref items, .. } = item. kind {
357
353
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 ) ) ) ;
359
358
360
359
let trait_def_id = match trait_ref. path . res {
361
360
Res :: Def ( DefKind :: Trait , def_id) => def_id,
@@ -366,12 +365,10 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
366
365
return ;
367
366
}
368
367
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
+ ) ;
375
372
}
376
373
}
377
374
}
@@ -383,7 +380,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
383
380
}
384
381
}
385
382
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 > {
387
384
debug_assert ! ( crate_num == LOCAL_CRATE ) ;
388
385
389
386
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
405
402
// If other crates link to us, they're going to expect to be able to
406
403
// use the lang items, so we need to be sure to mark them as
407
404
// 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) ) ) ;
409
408
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 ) ;
413
412
}
414
413
}
415
414
}
@@ -428,7 +427,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
428
427
debug ! ( "Inline reachability shows: {:?}" , reachable_context. reachable_symbols) ;
429
428
430
429
// Return the set of reachable symbols.
431
- tcx . arena . alloc ( reachable_context. reachable_symbols )
430
+ reachable_context. reachable_symbols
432
431
}
433
432
434
433
pub fn provide ( providers : & mut Providers ) {
0 commit comments