@@ -14,7 +14,7 @@ use rustc_errors::MultiSpan;
1414use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
1515use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
1616use 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 } ;
1818use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
1919use rustc_middle:: middle:: privacy:: Level ;
2020use rustc_middle:: query:: Providers ;
@@ -69,23 +69,6 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
6969 }
7070}
7171
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-
8972/// Determine if a work from the worklist is coming from a `#[allow]`
9073/// or a `#[expect]` of `dead_code`
9174#[ derive( Debug , Copy , Clone , Eq , PartialEq , Hash ) ]
@@ -499,24 +482,24 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
499482 /// `local_def_id` points to an impl or an impl item,
500483 /// both impl and impl item that may be passed to this function are of a trait,
501484 /// 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) {
508487 // 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+ ) ,
514495 // 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 ! ( ) ,
520503 } ;
521504
522505 if let Some ( trait_def_id) = trait_def_id
@@ -526,9 +509,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
526509 }
527510
528511 // 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 )
532515 {
533516 return false ;
534517 }
@@ -751,7 +734,7 @@ fn has_allow_dead_code_or_lang_attr(
751734fn check_item < ' tcx > (
752735 tcx : TyCtxt < ' tcx > ,
753736 worklist : & mut Vec < ( LocalDefId , ComesFromAllowExpect ) > ,
754- unsolved_items : & mut Vec < ( hir :: ItemId , LocalDefId ) > ,
737+ unsolved_items : & mut Vec < LocalDefId > ,
755738 id : hir:: ItemId ,
756739) {
757740 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>(
776759 {
777760 worklist. push ( ( id. owner_id . def_id , comes_from_allow) ) ;
778761 } else if of_trait {
779- unsolved_items. push ( ( id , id . owner_id . def_id ) ) ;
762+ unsolved_items. push ( id . owner_id . def_id ) ;
780763 }
781764
782765 for def_id in tcx. associated_item_def_ids ( id. owner_id ) {
@@ -791,7 +774,7 @@ fn check_item<'tcx>(
791774 // so we later mark them as live if their corresponding traits
792775 // or trait items and self types are both live,
793776 // 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) ;
795778 }
796779 }
797780 }
@@ -844,7 +827,7 @@ fn check_foreign_item(
844827
845828fn create_and_seed_worklist (
846829 tcx : TyCtxt < ' _ > ,
847- ) -> ( Vec < ( LocalDefId , ComesFromAllowExpect ) > , Vec < ( hir :: ItemId , LocalDefId ) > ) {
830+ ) -> ( Vec < ( LocalDefId , ComesFromAllowExpect ) > , Vec < LocalDefId > ) {
848831 let effective_visibilities = & tcx. effective_visibilities ( ( ) ) ;
849832 let mut unsolved_impl_item = Vec :: new ( ) ;
850833 let mut worklist = effective_visibilities
@@ -895,21 +878,24 @@ fn live_symbols_and_ignored_derived_traits(
895878 ignored_derived_traits : Default :: default ( ) ,
896879 } ;
897880 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 ( ) ;
903889
904890 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 ) ) ) ;
907894 symbol_visitor. mark_live_symbols ( ) ;
908895
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+ } ) ) ;
913899 }
914900
915901 ( symbol_visitor. live_symbols , symbol_visitor. ignored_derived_traits )
0 commit comments