Skip to content

Commit 6c39b30

Browse files
committed
Simplify handling of unsolved items.
1 parent 99ee623 commit 6c39b30

File tree

1 file changed

+38
-52
lines changed

1 file changed

+38
-52
lines changed

compiler/rustc_passes/src/dead.rs

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_errors::MultiSpan;
1414
use rustc_hir::def::{CtorOf, DefKind, Res};
1515
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
1616
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};
1818
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1919
use rustc_middle::middle::privacy::Level;
2020
use 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(
751734
fn 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

845828
fn 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

Comments
 (0)