Skip to content

Commit 7e29893

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

File tree

4 files changed

+128
-3
lines changed

4 files changed

+128
-3
lines changed

compiler/rustc_passes/src/dead.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

compiler/rustc_privacy/src/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,17 +699,31 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
699699
// `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
700700
// can be usable from other crates (#57264). So we skip args when calculating
701701
// reachability and consider an impl reachable if its "shallow" type and trait are
702-
// reachable.
702+
// reachable if there were no private types.
703703
//
704704
// The assumption we make here is that type-inference won't let you use an impl
705705
// without knowing both "shallow" version of its self type and "shallow" version of
706706
// its trait if it exists (which require reaching the `DefId`s in them).
707-
let item_ev = EffectiveVisibility::of_impl::<true>(
707+
let impl_vis = ty::Visibility::of_impl::<false>(
708708
item.owner_id.def_id,
709709
self.tcx,
710-
&self.effective_visibilities,
710+
&Default::default(),
711711
);
712712

713+
let item_ev = if impl_vis.is_public() {
714+
EffectiveVisibility::of_impl::<true>(
715+
item.owner_id.def_id,
716+
self.tcx,
717+
&self.effective_visibilities,
718+
)
719+
} else {
720+
EffectiveVisibility::of_impl::<false>(
721+
item.owner_id.def_id,
722+
self.tcx,
723+
&self.effective_visibilities,
724+
)
725+
};
726+
713727
self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
714728

715729
self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
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+
fn foo(&self) {}
11+
}
12+
13+
impl Trait for [Foo] {
14+
fn foo(&self) {}
15+
}
16+
impl<const N: usize> Trait for [Foo; N] {
17+
fn foo(&self) {}
18+
}
19+
20+
impl Trait for *const Foo {
21+
fn foo(&self) {}
22+
}
23+
impl Trait for *mut Foo {
24+
fn foo(&self) {}
25+
}
26+
27+
impl Trait for &Foo {
28+
fn foo(&self) {}
29+
}
30+
impl Trait for &&Foo {
31+
fn foo(&self) {}
32+
}
33+
impl Trait for &mut Foo {
34+
fn foo(&self) {}
35+
}
36+
37+
impl Trait for [&Foo] {
38+
fn foo(&self) {}
39+
}
40+
impl Trait for &[Foo] {
41+
fn foo(&self) {}
42+
}
43+
impl Trait for &*const Foo {
44+
fn foo(&self) {}
45+
}
46+
47+
pub trait Trait2 {
48+
fn foo(&self);
49+
}
50+
51+
impl Trait2 for Foo {
52+
fn foo(&self) {}
53+
}
54+
55+
impl Trait2 for [Foo] {
56+
fn foo(&self) {}
57+
}
58+
impl<const N: usize> Trait2 for [Foo; N] {
59+
fn foo(&self) {}
60+
}
61+
62+
impl Trait2 for *const Foo {
63+
fn foo(&self) {}
64+
}
65+
impl Trait2 for *mut Foo {
66+
fn foo(&self) {}
67+
}
68+
69+
impl Trait2 for &Foo {
70+
fn foo(&self) {}
71+
}
72+
impl Trait2 for &&Foo {
73+
fn foo(&self) {}
74+
}
75+
impl Trait2 for &mut Foo {
76+
fn foo(&self) {}
77+
}
78+
79+
impl Trait2 for [&Foo] {
80+
fn foo(&self) {}
81+
}
82+
impl Trait2 for &[Foo] {
83+
fn foo(&self) {}
84+
}
85+
impl Trait2 for &*const Foo {
86+
fn foo(&self) {}
87+
}
88+
89+
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)