mirror of https://github.com/rust-lang/rust.git
Rollup merge of #110277 - Ezrashaw:combine-assoc-fns-dlint, r=lcnr
dead-code-lint: de-dup multiple unused assoc functions Fixes #109600 Prior art: #97853
This commit is contained in:
commit
759d4e8651
|
@ -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();
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
| ^^^
|
||||
|
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue