@@ -8,7 +8,6 @@ use rustc_hir as hir;
8
8
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
9
9
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
10
10
use rustc_hir:: intravisit:: { self , Visitor } ;
11
- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
12
11
use rustc_hir:: { Node , PatKind , TyKind } ;
13
12
use rustc_middle:: hir:: nested_filter;
14
13
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
@@ -468,7 +467,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
468
467
tcx. lint_level_at_node ( lint:: builtin:: DEAD_CODE , id) . 0 == lint:: Allow
469
468
}
470
469
471
- // This visitor seeds items that
470
+ // These check_* functions seeds items that
472
471
// 1) We want to explicitly consider as live:
473
472
// * Item annotated with #[allow(dead_code)]
474
473
// - This is done so that if we want to suppress warnings for a
@@ -481,90 +480,99 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
481
480
// or
482
481
// 2) We are not sure to be live or not
483
482
// * Implementations of traits and trait methods
484
- struct LifeSeeder < ' tcx > {
485
- worklist : Vec < LocalDefId > ,
483
+ fn check_item < ' tcx > (
486
484
tcx : TyCtxt < ' tcx > ,
487
- // see `MarkSymbolVisitor::struct_constructors`
488
- struct_constructors : FxHashMap < LocalDefId , LocalDefId > ,
489
- }
490
-
491
- impl < ' v , ' tcx > ItemLikeVisitor < ' v > for LifeSeeder < ' tcx > {
492
- fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
493
- let allow_dead_code = has_allow_dead_code_or_lang_attr ( self . tcx , item. hir_id ( ) ) ;
494
- if allow_dead_code {
495
- self . worklist . push ( item. def_id ) ;
496
- }
497
- match item. kind {
498
- hir:: ItemKind :: Enum ( ref enum_def, _) => {
499
- let hir = self . tcx . hir ( ) ;
485
+ worklist : & mut Vec < LocalDefId > ,
486
+ struct_constructors : & mut FxHashMap < LocalDefId , LocalDefId > ,
487
+ id : hir:: ItemId ,
488
+ ) {
489
+ let allow_dead_code = has_allow_dead_code_or_lang_attr ( tcx, id. hir_id ( ) ) ;
490
+ if allow_dead_code {
491
+ worklist. push ( id. def_id ) ;
492
+ }
493
+
494
+ match tcx. hir ( ) . def_kind ( id. def_id ) {
495
+ DefKind :: Enum => {
496
+ let item = tcx. hir ( ) . item ( id) ;
497
+ if let hir:: ItemKind :: Enum ( ref enum_def, _) = item. kind {
498
+ let hir = tcx. hir ( ) ;
500
499
if allow_dead_code {
501
- self . worklist . extend (
500
+ worklist. extend (
502
501
enum_def. variants . iter ( ) . map ( |variant| hir. local_def_id ( variant. id ) ) ,
503
502
) ;
504
503
}
505
504
506
505
for variant in enum_def. variants {
507
506
if let Some ( ctor_hir_id) = variant. data . ctor_hir_id ( ) {
508
- self . struct_constructors
507
+ struct_constructors
509
508
. insert ( hir. local_def_id ( ctor_hir_id) , hir. local_def_id ( variant. id ) ) ;
510
509
}
511
510
}
512
511
}
513
- hir:: ItemKind :: Impl ( hir:: Impl { ref of_trait, items, .. } ) => {
512
+ }
513
+ DefKind :: Impl => {
514
+ let item = tcx. hir ( ) . item ( id) ;
515
+ if let hir:: ItemKind :: Impl ( hir:: Impl { ref of_trait, items, .. } ) = item. kind {
514
516
if of_trait. is_some ( ) {
515
- self . worklist . push ( item. def_id ) ;
517
+ worklist. push ( item. def_id ) ;
516
518
}
517
519
for impl_item_ref in * items {
518
- let impl_item = self . tcx . hir ( ) . impl_item ( impl_item_ref. id ) ;
520
+ let impl_item = tcx. hir ( ) . impl_item ( impl_item_ref. id ) ;
519
521
if of_trait. is_some ( )
520
- || has_allow_dead_code_or_lang_attr ( self . tcx , impl_item. hir_id ( ) )
522
+ || has_allow_dead_code_or_lang_attr ( tcx, impl_item. hir_id ( ) )
521
523
{
522
- self . worklist . push ( impl_item_ref. id . def_id ) ;
524
+ worklist. push ( impl_item_ref. id . def_id ) ;
523
525
}
524
526
}
525
527
}
526
- hir:: ItemKind :: Struct ( ref variant_data, _) => {
528
+ }
529
+ DefKind :: Struct => {
530
+ let item = tcx. hir ( ) . item ( id) ;
531
+ if let hir:: ItemKind :: Struct ( ref variant_data, _) = item. kind {
527
532
if let Some ( ctor_hir_id) = variant_data. ctor_hir_id ( ) {
528
- self . struct_constructors
529
- . insert ( self . tcx . hir ( ) . local_def_id ( ctor_hir_id) , item. def_id ) ;
533
+ struct_constructors. insert ( tcx. hir ( ) . local_def_id ( ctor_hir_id) , item. def_id ) ;
530
534
}
531
535
}
532
- hir:: ItemKind :: GlobalAsm ( _) => {
533
- // global_asm! is always live.
534
- self . worklist . push ( item. def_id ) ;
535
- }
536
- _ => ( ) ,
537
536
}
537
+ DefKind :: GlobalAsm => {
538
+ // global_asm! is always live.
539
+ worklist. push ( id. def_id ) ;
540
+ }
541
+ _ => { }
538
542
}
543
+ }
539
544
540
- fn visit_trait_item ( & mut self , trait_item : & hir:: TraitItem < ' _ > ) {
541
- use hir:: TraitItemKind :: { Const , Fn } ;
545
+ fn check_trait_item < ' tcx > ( tcx : TyCtxt < ' tcx > , worklist : & mut Vec < LocalDefId > , id : hir:: TraitItemId ) {
546
+ use hir:: TraitItemKind :: { Const , Fn } ;
547
+ if matches ! ( tcx. hir( ) . def_kind( id. def_id) , DefKind :: AssocConst | DefKind :: AssocFn ) {
548
+ let trait_item = tcx. hir ( ) . trait_item ( id) ;
542
549
if matches ! ( trait_item. kind, Const ( _, Some ( _) ) | Fn ( _, hir:: TraitFn :: Provided ( _) ) )
543
- && has_allow_dead_code_or_lang_attr ( self . tcx , trait_item. hir_id ( ) )
550
+ && has_allow_dead_code_or_lang_attr ( tcx, trait_item. hir_id ( ) )
544
551
{
545
- self . worklist . push ( trait_item. def_id ) ;
552
+ worklist. push ( trait_item. def_id ) ;
546
553
}
547
554
}
555
+ }
548
556
549
- fn visit_impl_item ( & mut self , _item : & hir:: ImplItem < ' _ > ) {
550
- // ignore: we are handling this in `visit_item` above
551
- }
552
-
553
- fn visit_foreign_item ( & mut self , foreign_item : & hir:: ForeignItem < ' _ > ) {
554
- use hir:: ForeignItemKind :: { Fn , Static } ;
555
- if matches ! ( foreign_item. kind, Static ( ..) | Fn ( ..) )
556
- && has_allow_dead_code_or_lang_attr ( self . tcx , foreign_item. hir_id ( ) )
557
- {
558
- self . worklist . push ( foreign_item. def_id ) ;
559
- }
557
+ fn check_foreign_item < ' tcx > (
558
+ tcx : TyCtxt < ' tcx > ,
559
+ worklist : & mut Vec < LocalDefId > ,
560
+ id : hir:: ForeignItemId ,
561
+ ) {
562
+ if matches ! ( tcx. hir( ) . def_kind( id. def_id) , DefKind :: Static ( _) | DefKind :: Fn )
563
+ && has_allow_dead_code_or_lang_attr ( tcx, id. hir_id ( ) )
564
+ {
565
+ worklist. push ( id. def_id ) ;
560
566
}
561
567
}
562
568
563
569
fn create_and_seed_worklist < ' tcx > (
564
570
tcx : TyCtxt < ' tcx > ,
565
571
) -> ( Vec < LocalDefId > , FxHashMap < LocalDefId , LocalDefId > ) {
566
572
let access_levels = & tcx. privacy_access_levels ( ( ) ) ;
567
- let worklist = access_levels
573
+ // see `MarkSymbolVisitor::struct_constructors`
574
+ let mut struct_constructors = Default :: default ( ) ;
575
+ let mut worklist = access_levels
568
576
. map
569
577
. iter ( )
570
578
. filter_map (
@@ -576,11 +584,20 @@ fn create_and_seed_worklist<'tcx>(
576
584
. chain ( tcx. entry_fn ( ( ) ) . and_then ( |( def_id, _) | def_id. as_local ( ) ) )
577
585
. collect :: < Vec < _ > > ( ) ;
578
586
579
- // Seed implemented trait items
580
- let mut life_seeder = LifeSeeder { worklist, tcx, struct_constructors : Default :: default ( ) } ;
581
- tcx. hir ( ) . visit_all_item_likes ( & mut life_seeder) ;
587
+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
588
+ for id in crate_items. items ( ) {
589
+ check_item ( tcx, & mut worklist, & mut struct_constructors, id) ;
590
+ }
591
+
592
+ for id in crate_items. trait_items ( ) {
593
+ check_trait_item ( tcx, & mut worklist, id) ;
594
+ }
595
+
596
+ for id in crate_items. foreign_items ( ) {
597
+ check_foreign_item ( tcx, & mut worklist, id) ;
598
+ }
582
599
583
- ( life_seeder . worklist , life_seeder . struct_constructors )
600
+ ( worklist, struct_constructors)
584
601
}
585
602
586
603
fn live_symbols_and_ignored_derived_traits < ' tcx > (
0 commit comments