Skip to content

Commit 559d82b

Browse files
committedAug 11, 2024·
Fix some review comments
1 parent 6f4b522 commit 559d82b

File tree

1 file changed

+55
-30
lines changed

1 file changed

+55
-30
lines changed
 

‎compiler/rustc_passes/src/dead.rs

+55-30
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
4343
)
4444
}
4545

46-
fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
46+
/// Returns the local def id and def kind of the adt,
47+
/// if the given ty refers to one local adt definition
48+
fn adt_def_of_ty<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
4749
match ty.kind {
4850
TyKind::Path(hir::QPath::Resolved(_, path)) => {
4951
if let Res::Def(def_kind, def_id) = path.res
@@ -54,8 +56,8 @@ fn adt_of<'tcx>(ty: &hir::Ty<'tcx>) -> Option<(LocalDefId, DefKind)> {
5456
None
5557
}
5658
}
57-
TyKind::Slice(ty) | TyKind::Array(ty, _) => adt_of(ty),
58-
TyKind::Ptr(ty) | TyKind::Ref(_, ty) => adt_of(ty.ty),
59+
TyKind::Slice(ty) | TyKind::Array(ty, _) => adt_def_of_ty(ty),
60+
TyKind::Ptr(ty) | TyKind::Ref(_, ty) => adt_def_of_ty(ty.ty),
5961
_ => None,
6062
}
6163
}
@@ -236,6 +238,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
236238
) {
237239
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
238240
ty::Adt(adt, _) => {
241+
// mark the adt live if its variant appears as the pattern
239242
self.check_def_id(adt.did());
240243
adt.variant_of_res(res)
241244
}
@@ -259,6 +262,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
259262
) {
260263
let variant = match self.typeck_results().node_type(lhs.hir_id).kind() {
261264
ty::Adt(adt, _) => {
265+
// mark the adt live if its variant appears as the pattern
262266
self.check_def_id(adt.did());
263267
adt.variant_of_res(res)
264268
}
@@ -494,25 +498,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
494498
}
495499
}
496500

497-
fn solve_rest_items(&mut self, mut unsolved_items: Vec<(hir::ItemId, LocalDefId)>) {
498-
let mut ready;
499-
(ready, unsolved_items) =
500-
unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
501-
self.item_should_be_checked(impl_id, local_def_id)
502-
});
503-
504-
while !ready.is_empty() {
505-
self.worklist =
506-
ready.into_iter().map(|(_, id)| (id, ComesFromAllowExpect::No)).collect();
507-
self.mark_live_symbols();
508-
509-
(ready, unsolved_items) =
510-
unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
511-
self.item_should_be_checked(impl_id, local_def_id)
512-
});
513-
}
514-
}
515-
501+
/// Returns an impl or impl item should be checked or not
502+
/// `impl_id` is the `ItemId` of the impl or the impl item belongs to,
503+
/// `local_def_id` may point to the impl or the impl item,
504+
/// both impl and impl item that may pass to this function are of trait,
505+
/// and added into the unsolved_items during `create_and_seed_worklist`
516506
fn item_should_be_checked(&mut self, impl_id: hir::ItemId, local_def_id: LocalDefId) -> bool {
517507
let trait_def_id = match self.tcx.def_kind(local_def_id) {
518508
// for assoc impl items of traits, we concern the corresponding trait items are used or not
@@ -529,20 +519,28 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
529519
_ => None,
530520
};
531521

532-
if !trait_def_id.map(|def_id| self.live_symbols.contains(&def_id)).unwrap_or(true) {
522+
if let Some(def_id) = trait_def_id
523+
&& !self.live_symbols.contains(&def_id)
524+
{
533525
return false;
534526
}
535527

536528
// we only check the ty is used or not for ADTs defined locally
537-
let ty_def_id = adt_of(self.tcx.hir().item(impl_id).expect_impl().self_ty).and_then(
529+
let ty_def_id = adt_def_of_ty(self.tcx.hir().item(impl_id).expect_impl().self_ty).and_then(
538530
|(local_def_id, def_kind)| {
539531
matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
540532
.then_some(local_def_id)
541533
},
542534
);
543535

544536
// the impl/impl item is used if the trait/trait item is used and the ty is used
545-
ty_def_id.map(|def_id| self.live_symbols.contains(&def_id)).unwrap_or(true)
537+
if let Some(def_id) = ty_def_id
538+
&& !self.live_symbols.contains(&def_id)
539+
{
540+
return false;
541+
}
542+
543+
true
546544
}
547545

548546
fn visit_middle_ty(&mut self, ty: Ty<'tcx>) {
@@ -848,7 +846,7 @@ fn check_item<'tcx>(
848846
}
849847
DefKind::Impl { of_trait } => {
850848
// get DefIds from another query
851-
let local_def_ids = tcx
849+
let associated_item_def_ids = tcx
852850
.associated_item_def_ids(id.owner_id)
853851
.iter()
854852
.filter_map(|def_id| def_id.as_local());
@@ -862,11 +860,16 @@ fn check_item<'tcx>(
862860
}
863861

864862
// And we access the Map here to get HirId from LocalDefId
865-
for local_def_id in local_def_ids {
863+
for local_def_id in associated_item_def_ids {
866864
if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, local_def_id)
867865
{
868866
worklist.push((local_def_id, comes_from_allow));
869867
} else if of_trait {
868+
// we only care about assoc items of trait,
869+
// because they cannot be visited directly
870+
// so we mark them based on the trait/trait item
871+
// and self ty are checked first and both live,
872+
// but inherent assoc items can be visited and marked directly
870873
unsolved_items.push((id, local_def_id));
871874
}
872875
}
@@ -977,7 +980,7 @@ fn live_symbols_and_ignored_derived_traits(
977980
tcx: TyCtxt<'_>,
978981
(): (),
979982
) -> (LocalDefIdSet, LocalDefIdMap<Vec<(DefId, DefId)>>) {
980-
let (worklist, struct_constructors, unsolved_items) = create_and_seed_worklist(tcx);
983+
let (worklist, struct_constructors, mut unsolved_items) = create_and_seed_worklist(tcx);
981984
let mut symbol_visitor = MarkSymbolVisitor {
982985
worklist,
983986
tcx,
@@ -990,8 +993,26 @@ fn live_symbols_and_ignored_derived_traits(
990993
struct_constructors,
991994
ignored_derived_traits: Default::default(),
992995
};
996+
993997
symbol_visitor.mark_live_symbols();
994-
symbol_visitor.solve_rest_items(unsolved_items);
998+
let mut rest_items_should_be_checked;
999+
(rest_items_should_be_checked, unsolved_items) =
1000+
unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
1001+
symbol_visitor.item_should_be_checked(impl_id, local_def_id)
1002+
});
1003+
1004+
while !rest_items_should_be_checked.is_empty() {
1005+
symbol_visitor.worklist = rest_items_should_be_checked
1006+
.into_iter()
1007+
.map(|(_, id)| (id, ComesFromAllowExpect::No))
1008+
.collect();
1009+
symbol_visitor.mark_live_symbols();
1010+
1011+
(rest_items_should_be_checked, unsolved_items) =
1012+
unsolved_items.into_iter().partition(|&(impl_id, local_def_id)| {
1013+
symbol_visitor.item_should_be_checked(impl_id, local_def_id)
1014+
});
1015+
}
9951016

9961017
(symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)
9971018
}
@@ -1268,7 +1289,11 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
12681289
let def_kind = tcx.def_kind(item.owner_id);
12691290

12701291
let mut dead_codes = Vec::new();
1271-
// if we have diagnosed the trait, do not diagnose unused assoc items
1292+
// only diagnose unused assoc items for inherient impl and used trait
1293+
// for unused assoc items in impls of trait,
1294+
// we have diagnosed them in the trait if they are unused,
1295+
// for unused assoc items in unused trait,
1296+
// we have diagnosed the unused trait
12721297
if matches!(def_kind, DefKind::Impl { of_trait: false })
12731298
|| (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
12741299
{

0 commit comments

Comments
 (0)