Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dead-code-lint: de-dup multiple unused assoc functions #110277

Merged
merged 4 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 42 additions & 20 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,13 @@ impl<'tcx> DeadVisitor<'tcx> {
.collect();

let descr = tcx.def_descr(first_id.to_def_id());
// `impl` blocks are "batched" and (unlike other batching) might
// contain different kinds of associated items.
let descr = if dead_codes.iter().any(|did| tcx.def_descr(did.to_def_id()) != descr) {
"associated item"
} else {
descr
};
let num = dead_codes.len();
let multiple = num > 6;
let name_list = names.into();
Expand All @@ -712,12 +719,12 @@ impl<'tcx> DeadVisitor<'tcx> {

let parent_info = if let Some(parent_item) = parent_item {
let parent_descr = tcx.def_descr(parent_item.to_def_id());
Some(ParentInfo {
num,
descr,
parent_descr,
span: tcx.def_ident_span(parent_item).unwrap(),
})
let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) {
tcx.def_span(parent_item)
} else {
tcx.def_ident_span(parent_item).unwrap()
};
Some(ParentInfo { num, descr, parent_descr, span })
} else {
None
};
Expand Down Expand Up @@ -800,16 +807,7 @@ impl<'tcx> DeadVisitor<'tcx> {
}

fn check_definition(&mut self, def_id: LocalDefId) {
if self.live_symbols.contains(&def_id) {
return;
}
if has_allow_dead_code_or_lang_attr(self.tcx, def_id) {
return;
}
let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
return
};
if name.as_str().starts_with('_') {
if self.is_live_code(def_id) {
return;
}
match self.tcx.def_kind(def_id) {
Expand All @@ -827,6 +825,18 @@ impl<'tcx> DeadVisitor<'tcx> {
_ => {}
}
}

fn is_live_code(&self, def_id: LocalDefId) -> bool {
// if we cannot get a name for the item, then we just assume that it is
// live. I mean, we can't really emit a lint.
let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
return true;
};

self.live_symbols.contains(&def_id)
|| has_allow_dead_code_or_lang_attr(self.tcx, def_id)
|| name.as_str().starts_with('_')
}
}

fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
Expand All @@ -836,6 +846,22 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
let module_items = tcx.hir_module_items(module);

for item in module_items.items() {
if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind {
let mut dead_items = Vec::new();
for item in impl_item.items {
let did = item.id.owner_id.def_id;
if !visitor.is_live_code(did) {
dead_items.push(did)
}
}
visitor.warn_multiple_dead_codes(
&dead_items,
"used",
Some(item.owner_id.def_id),
false,
);
}

if !live_symbols.contains(&item.owner_id.def_id) {
let parent = tcx.local_parent(item.owner_id.def_id);
if parent != module && !live_symbols.contains(&parent) {
Expand Down Expand Up @@ -900,10 +926,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
}
}

for impl_item in module_items.impl_items() {
visitor.check_definition(impl_item.owner_id.def_id);
}

for foreign_item in module_items.foreign_items() {
visitor.check_definition(foreign_item.owner_id.def_id);
}
Expand Down
2 changes: 2 additions & 0 deletions tests/ui/associated-consts/associated-const-dead-code.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
error: associated constant `BAR` is never used
--> $DIR/associated-const-dead-code.rs:6:11
|
LL | impl MyFoo {
| ---------- associated constant in this implementation
LL | const BAR: u32 = 1;
| ^^^
|
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/lint/dead-code/issue-85255.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ struct Foo {
struct Bar;

impl Bar {
fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
fn a(&self) -> i32 { 5 } //~ WARNING: methods `a` and `b` are never used [dead_code]
pub fn b(&self) -> i32 { 6 }
}

pub(crate) struct Foo1 {
Expand All @@ -23,8 +23,8 @@ pub(crate) struct Foo1 {
pub(crate) struct Bar1;

impl Bar1 {
fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
fn a(&self) -> i32 { 5 } //~ WARNING: methods `a` and `b` are never used [dead_code]
pub fn b(&self) -> i32 { 6 }
}

pub(crate) struct Foo2 {
Expand All @@ -35,8 +35,8 @@ pub(crate) struct Foo2 {
pub(crate) struct Bar2;

impl Bar2 {
fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used
fn a(&self) -> i32 { 5 } //~ WARNING: methods `a` and `b` are never used [dead_code]
pub fn b(&self) -> i32 { 6 }
}


Expand Down
54 changes: 24 additions & 30 deletions tests/ui/lint/dead-code/issue-85255.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ note: the lint level is defined here
LL | #![warn(dead_code)]
| ^^^^^^^^^

warning: methods `a` and `b` are never used
--> $DIR/issue-85255.rs:14:8
|
LL | impl Bar {
| -------- methods in this implementation
LL | fn a(&self) -> i32 { 5 }
| ^
LL | pub fn b(&self) -> i32 { 6 }
| ^

warning: fields `a` and `b` are never read
--> $DIR/issue-85255.rs:19:5
|
Expand All @@ -24,6 +34,16 @@ LL | a: i32,
LL | pub b: i32,
| ^

warning: methods `a` and `b` are never used
--> $DIR/issue-85255.rs:26:8
|
LL | impl Bar1 {
| --------- methods in this implementation
LL | fn a(&self) -> i32 { 5 }
| ^
LL | pub fn b(&self) -> i32 { 6 }
| ^

warning: fields `a` and `b` are never read
--> $DIR/issue-85255.rs:31:5
|
Expand All @@ -34,41 +54,15 @@ LL | a: i32,
LL | pub b: i32,
| ^

warning: method `a` is never used
--> $DIR/issue-85255.rs:14:8
|
LL | fn a(&self) -> i32 { 5 }
| ^

warning: method `b` is never used
--> $DIR/issue-85255.rs:15:12
|
LL | pub fn b(&self) -> i32 { 6 }
| ^

warning: method `a` is never used
--> $DIR/issue-85255.rs:26:8
|
LL | fn a(&self) -> i32 { 5 }
| ^

warning: method `b` is never used
--> $DIR/issue-85255.rs:27:12
|
LL | pub fn b(&self) -> i32 { 6 }
| ^

warning: method `a` is never used
warning: methods `a` and `b` are never used
--> $DIR/issue-85255.rs:38:8
|
LL | impl Bar2 {
| --------- methods in this implementation
LL | fn a(&self) -> i32 { 5 }
| ^

warning: method `b` is never used
--> $DIR/issue-85255.rs:39:12
|
LL | pub fn b(&self) -> i32 { 6 }
| ^

warning: 9 warnings emitted
warning: 6 warnings emitted

14 changes: 8 additions & 6 deletions tests/ui/lint/dead-code/lint-dead-code-3.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ note: the lint level is defined here
LL | #![deny(dead_code)]
| ^^^^^^^^^

error: method `foo` is never used
--> $DIR/lint-dead-code-3.rs:16:8
|
LL | impl Foo {
| -------- method in this implementation
LL | fn foo(&self) {
| ^^^

error: function `bar` is never used
--> $DIR/lint-dead-code-3.rs:21:4
|
Expand All @@ -34,12 +42,6 @@ error: function `blah` is never used
LL | fn blah() {}
| ^^^^

error: method `foo` is never used
--> $DIR/lint-dead-code-3.rs:16:8
|
LL | fn foo(&self) {
| ^^^

error: function `free` is never used
--> $DIR/lint-dead-code-3.rs:62:8
|
Expand Down
9 changes: 4 additions & 5 deletions tests/ui/lint/dead-code/lint-dead-code-6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
impl UnusedStruct {
fn unused_impl_fn_1() { //~ ERROR associated function `unused_impl_fn_1` is never used
fn unused_impl_fn_1() {
//~^ ERROR associated functions `unused_impl_fn_1`, `unused_impl_fn_2`, and `unused_impl_fn_3` are never used [dead_code]
println!("blah");
}

fn unused_impl_fn_2(var: i32) { //~ ERROR associated function `unused_impl_fn_2` is never used
fn unused_impl_fn_2(var: i32) {
println!("foo {}", var);
}

fn unused_impl_fn_3( //~ ERROR associated function `unused_impl_fn_3` is never used
var: i32,
) {
fn unused_impl_fn_3(var: i32) {
println!("bar {}", var);
}
}
Expand Down
18 changes: 7 additions & 11 deletions tests/ui/lint/dead-code/lint-dead-code-6.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,19 @@ note: the lint level is defined here
LL | #![deny(dead_code)]
| ^^^^^^^^^

error: associated function `unused_impl_fn_1` is never used
error: associated functions `unused_impl_fn_1`, `unused_impl_fn_2`, and `unused_impl_fn_3` are never used
--> $DIR/lint-dead-code-6.rs:5:8
|
LL | impl UnusedStruct {
| ----------------- associated functions in this implementation
LL | fn unused_impl_fn_1() {
| ^^^^^^^^^^^^^^^^

error: associated function `unused_impl_fn_2` is never used
--> $DIR/lint-dead-code-6.rs:9:8
|
...
LL | fn unused_impl_fn_2(var: i32) {
| ^^^^^^^^^^^^^^^^

error: associated function `unused_impl_fn_3` is never used
--> $DIR/lint-dead-code-6.rs:13:8
|
LL | fn unused_impl_fn_3(
...
LL | fn unused_impl_fn_3(var: i32) {
| ^^^^^^^^^^^^^^^^

error: aborting due to 4 previous errors
error: aborting due to 2 previous errors

35 changes: 35 additions & 0 deletions tests/ui/lint/dead-code/unused-assoc-fns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![feature(inherent_associated_types)]
#![allow(incomplete_features)]
#![deny(unused)]

struct Foo;

impl Foo {
fn one() {}
//~^ ERROR associated items `one`, `two`, `CONSTANT`, `Type`, and `three` are never used [dead_code]

fn two(&self) {}

// seperation between items
// ...
// ...

fn used() {}

const CONSTANT: usize = 5;

// more seperation
// ...
// ...

type Type = usize;

fn three(&self) {
Foo::one();
// ...
}
}

fn main() {
Foo::used();
}
29 changes: 29 additions & 0 deletions tests/ui/lint/dead-code/unused-assoc-fns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error: associated items `one`, `two`, `CONSTANT`, `Type`, and `three` are never used
--> $DIR/unused-assoc-fns.rs:8:8
|
LL | impl Foo {
| -------- associated items in this implementation
LL | fn one() {}
| ^^^
...
LL | fn two(&self) {}
| ^^^
...
LL | const CONSTANT: usize = 5;
| ^^^^^^^^
...
LL | type Type = usize;
| ^^^^
LL |
LL | fn three(&self) {
| ^^^^^
|
note: the lint level is defined here
--> $DIR/unused-assoc-fns.rs:3:9
|
LL | #![deny(unused)]
| ^^^^^^
= note: `#[deny(dead_code)]` implied by `#[deny(unused)]`

error: aborting due to previous error