@@ -14,7 +14,7 @@ use rustc_errors::MultiSpan;
14
14
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
15
15
use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
16
16
use rustc_hir:: intravisit:: { self , Visitor } ;
17
- use rustc_hir:: { self as hir, ImplItem , ImplItemKind , Node , PatKind , QPath , TyKind } ;
17
+ use rustc_hir:: { self as hir, ImplItem , ImplItemKind , Node , PatKind , QPath } ;
18
18
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
19
19
use rustc_middle:: middle:: privacy:: Level ;
20
20
use rustc_middle:: query:: Providers ;
@@ -69,23 +69,6 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
69
69
}
70
70
}
71
71
72
- /// Returns the local def id of the ADT if the given ty refers to a local one.
73
- fn local_adt_def_of_ty < ' tcx > ( ty : & hir:: Ty < ' tcx > ) -> Option < LocalDefId > {
74
- match ty. kind {
75
- TyKind :: Path ( QPath :: Resolved ( _, path) ) => {
76
- if let Res :: Def ( def_kind, def_id) = path. res
77
- && let Some ( local_def_id) = def_id. as_local ( )
78
- && matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
79
- {
80
- Some ( local_def_id)
81
- } else {
82
- None
83
- }
84
- }
85
- _ => None ,
86
- }
87
- }
88
-
89
72
/// Determine if a work from the worklist is coming from a `#[allow]`
90
73
/// or a `#[expect]` of `dead_code`
91
74
#[ derive( Debug , Copy , Clone , Eq , PartialEq , Hash ) ]
@@ -499,24 +482,24 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
499
482
/// `local_def_id` points to an impl or an impl item,
500
483
/// both impl and impl item that may be passed to this function are of a trait,
501
484
/// and added into the unsolved_items during `create_and_seed_worklist`
502
- fn check_impl_or_impl_item_live (
503
- & mut self ,
504
- impl_id : hir:: ItemId ,
505
- local_def_id : LocalDefId ,
506
- ) -> bool {
507
- let trait_def_id = match self . tcx . def_kind ( local_def_id) {
485
+ fn check_impl_or_impl_item_live ( & mut self , local_def_id : LocalDefId ) -> bool {
486
+ let ( impl_block_id, trait_def_id) = match self . tcx . def_kind ( local_def_id) {
508
487
// assoc impl items of traits are live if the corresponding trait items are live
509
- DefKind :: AssocConst | DefKind :: AssocTy | DefKind :: AssocFn => self
510
- . tcx
511
- . associated_item ( local_def_id)
512
- . trait_item_def_id
513
- . and_then ( |def_id| def_id. as_local ( ) ) ,
488
+ DefKind :: AssocConst | DefKind :: AssocTy | DefKind :: AssocFn => (
489
+ self . tcx . local_parent ( local_def_id) ,
490
+ self . tcx
491
+ . associated_item ( local_def_id)
492
+ . trait_item_def_id
493
+ . and_then ( |def_id| def_id. as_local ( ) ) ,
494
+ ) ,
514
495
// impl items are live if the corresponding traits are live
515
- DefKind :: Impl { of_trait : true } => self
516
- . tcx
517
- . impl_trait_ref ( impl_id. owner_id . def_id )
518
- . and_then ( |trait_ref| trait_ref. skip_binder ( ) . def_id . as_local ( ) ) ,
519
- _ => None ,
496
+ DefKind :: Impl { of_trait : true } => (
497
+ local_def_id,
498
+ self . tcx
499
+ . impl_trait_ref ( local_def_id)
500
+ . and_then ( |trait_ref| trait_ref. skip_binder ( ) . def_id . as_local ( ) ) ,
501
+ ) ,
502
+ _ => bug ! ( ) ,
520
503
} ;
521
504
522
505
if let Some ( trait_def_id) = trait_def_id
@@ -526,9 +509,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
526
509
}
527
510
528
511
// The impl or impl item is used if the corresponding trait or trait item is used and the ty is used.
529
- if let Some ( local_def_id ) =
530
- local_adt_def_of_ty ( self . tcx . hir_item ( impl_id ) . expect_impl ( ) . self_ty )
531
- && !self . live_symbols . contains ( & local_def_id )
512
+ if let ty :: Adt ( adt , _ ) = self . tcx . type_of ( impl_block_id ) . instantiate_identity ( ) . kind ( )
513
+ && let Some ( adt_def_id ) = adt . did ( ) . as_local ( )
514
+ && !self . live_symbols . contains ( & adt_def_id )
532
515
{
533
516
return false ;
534
517
}
@@ -751,7 +734,7 @@ fn has_allow_dead_code_or_lang_attr(
751
734
fn check_item < ' tcx > (
752
735
tcx : TyCtxt < ' tcx > ,
753
736
worklist : & mut Vec < ( LocalDefId , ComesFromAllowExpect ) > ,
754
- unsolved_items : & mut Vec < ( hir :: ItemId , LocalDefId ) > ,
737
+ unsolved_items : & mut Vec < LocalDefId > ,
755
738
id : hir:: ItemId ,
756
739
) {
757
740
let allow_dead_code = has_allow_dead_code_or_lang_attr ( tcx, id. owner_id . def_id ) ;
@@ -776,7 +759,7 @@ fn check_item<'tcx>(
776
759
{
777
760
worklist. push ( ( id. owner_id . def_id , comes_from_allow) ) ;
778
761
} else if of_trait {
779
- unsolved_items. push ( ( id , id . owner_id . def_id ) ) ;
762
+ unsolved_items. push ( id . owner_id . def_id ) ;
780
763
}
781
764
782
765
for def_id in tcx. associated_item_def_ids ( id. owner_id ) {
@@ -791,7 +774,7 @@ fn check_item<'tcx>(
791
774
// so we later mark them as live if their corresponding traits
792
775
// or trait items and self types are both live,
793
776
// but inherent associated items can be visited and marked directly.
794
- unsolved_items. push ( ( id , local_def_id) ) ;
777
+ unsolved_items. push ( local_def_id) ;
795
778
}
796
779
}
797
780
}
@@ -844,7 +827,7 @@ fn check_foreign_item(
844
827
845
828
fn create_and_seed_worklist (
846
829
tcx : TyCtxt < ' _ > ,
847
- ) -> ( Vec < ( LocalDefId , ComesFromAllowExpect ) > , Vec < ( hir :: ItemId , LocalDefId ) > ) {
830
+ ) -> ( Vec < ( LocalDefId , ComesFromAllowExpect ) > , Vec < LocalDefId > ) {
848
831
let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
849
832
let mut unsolved_impl_item = Vec :: new ( ) ;
850
833
let mut worklist = effective_visibilities
@@ -895,21 +878,24 @@ fn live_symbols_and_ignored_derived_traits(
895
878
ignored_derived_traits : Default :: default ( ) ,
896
879
} ;
897
880
symbol_visitor. mark_live_symbols ( ) ;
898
- let mut items_to_check;
899
- ( items_to_check, unsolved_items) =
900
- unsolved_items. into_iter ( ) . partition ( |& ( impl_id, local_def_id) | {
901
- symbol_visitor. check_impl_or_impl_item_live ( impl_id, local_def_id)
902
- } ) ;
881
+
882
+ // We have marked the primary seeds as live. We now need to process unsolved items from traits
883
+ // and trait impls: add them to the work list if the trait or the implemented type is live.
884
+ let mut items_to_check: Vec < _ > = unsolved_items
885
+ . extract_if ( .., |& mut local_def_id| {
886
+ symbol_visitor. check_impl_or_impl_item_live ( local_def_id)
887
+ } )
888
+ . collect ( ) ;
903
889
904
890
while !items_to_check. is_empty ( ) {
905
- symbol_visitor. worklist =
906
- items_to_check. into_iter ( ) . map ( |( _, id) | ( id, ComesFromAllowExpect :: No ) ) . collect ( ) ;
891
+ symbol_visitor
892
+ . worklist
893
+ . extend ( items_to_check. drain ( ..) . map ( |id| ( id, ComesFromAllowExpect :: No ) ) ) ;
907
894
symbol_visitor. mark_live_symbols ( ) ;
908
895
909
- ( items_to_check, unsolved_items) =
910
- unsolved_items. into_iter ( ) . partition ( |& ( impl_id, local_def_id) | {
911
- symbol_visitor. check_impl_or_impl_item_live ( impl_id, local_def_id)
912
- } ) ;
896
+ items_to_check. extend ( unsolved_items. extract_if ( .., |& mut local_def_id| {
897
+ symbol_visitor. check_impl_or_impl_item_live ( local_def_id)
898
+ } ) ) ;
913
899
}
914
900
915
901
( symbol_visitor. live_symbols , symbol_visitor. ignored_derived_traits )
0 commit comments