Skip to content

Commit 28d6722

Browse files
committed
Extend dead code analysis of impls and impl items to non-ADTs
1 parent ae2fc97 commit 28d6722

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

compiler/rustc_passes/src/dead.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_hir::{self as hir, ImplItem, ImplItemKind, Node, PatKind, QPath, TyKin
1818
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1919
use rustc_middle::middle::privacy::Level;
2020
use rustc_middle::query::Providers;
21-
use rustc_middle::ty::{self, TyCtxt};
21+
use rustc_middle::ty::{self, AssocItemContainer, TyCtxt};
2222
use rustc_middle::{bug, span_bug};
2323
use rustc_session::lint::builtin::DEAD_CODE;
2424
use rustc_session::lint::{self, LintExpectationId};
@@ -58,6 +58,8 @@ fn local_adt_def_of_ty<'tcx>(ty: &hir::Ty<'tcx>) -> Option<LocalDefId> {
5858
None
5959
}
6060
}
61+
TyKind::Slice(ty) | TyKind::Array(ty, _) => local_adt_def_of_ty(ty),
62+
TyKind::Ptr(ty) | TyKind::Ref(_, ty) => local_adt_def_of_ty(ty.ty),
6163
_ => None,
6264
}
6365
}
@@ -832,6 +834,19 @@ fn create_and_seed_worklist(
832834
effective_vis
833835
.is_public_at_level(Level::Reachable)
834836
.then_some(id)
837+
.filter(|&id| match tcx.def_kind(id) {
838+
// Check impls of trait and impl items of trait later in `check_impl_or_impl_item_live`,
839+
// because `Self` may be non-ADTs and refer to local ADTs.
840+
DefKind::Impl { of_trait } => !of_trait,
841+
DefKind::AssocFn => {
842+
let assoc_item = tcx.associated_item(id);
843+
// Add reachable trait items and impl items not of traits
844+
// into the worklist directly.
845+
matches!(assoc_item.container, AssocItemContainer::Trait)
846+
|| assoc_item.trait_item_def_id.is_none()
847+
}
848+
_ => true,
849+
})
835850
.map(|id| (id, ComesFromAllowExpect::No))
836851
})
837852
// Seed entry point
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#![deny(dead_code)]
2+
3+
struct Foo; //~ ERROR struct `Foo` is never constructed
4+
5+
trait Trait { //~ ERROR trait `Trait` is never used
6+
fn foo(&self) {}
7+
}
8+
9+
impl Trait for Foo {}
10+
11+
impl Trait for [Foo] {}
12+
impl<const N: usize> Trait for [Foo; N] {}
13+
14+
impl Trait for *const Foo {}
15+
impl Trait for *mut Foo {}
16+
17+
impl Trait for &Foo {}
18+
impl Trait for &&Foo {}
19+
impl Trait for &mut Foo {}
20+
21+
impl Trait for [&Foo] {}
22+
impl Trait for &[Foo] {}
23+
impl Trait for &*const Foo {}
24+
25+
pub trait Trait2 {
26+
fn foo(&self) {}
27+
}
28+
29+
impl Trait2 for Foo {}
30+
31+
impl Trait2 for [Foo] {}
32+
impl<const N: usize> Trait2 for [Foo; N] {}
33+
34+
impl Trait2 for *const Foo {}
35+
impl Trait2 for *mut Foo {}
36+
37+
impl Trait2 for &Foo {}
38+
impl Trait2 for &&Foo {}
39+
impl Trait2 for &mut Foo {}
40+
41+
impl Trait2 for [&Foo] {}
42+
impl Trait2 for &[Foo] {}
43+
impl Trait2 for &*const Foo {}
44+
45+
fn main() {}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: struct `Foo` is never constructed
2+
--> $DIR/unused-impl-for-non-adts.rs:3:8
3+
|
4+
LL | struct Foo;
5+
| ^^^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unused-impl-for-non-adts.rs:1:9
9+
|
10+
LL | #![deny(dead_code)]
11+
| ^^^^^^^^^
12+
13+
error: trait `Trait` is never used
14+
--> $DIR/unused-impl-for-non-adts.rs:5:7
15+
|
16+
LL | trait Trait {
17+
| ^^^^^
18+
19+
error: aborting due to 2 previous errors
20+

0 commit comments

Comments
 (0)