Skip to content

Commit 759d4e8

Browse files
authored
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
2 parents e86de74 + 2bafc0f commit 759d4e8

File tree

9 files changed

+157
-78
lines changed

9 files changed

+157
-78
lines changed

compiler/rustc_passes/src/dead.rs

+42-20
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,13 @@ impl<'tcx> DeadVisitor<'tcx> {
700700
.collect();
701701

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

713720
let parent_info = if let Some(parent_item) = parent_item {
714721
let parent_descr = tcx.def_descr(parent_item.to_def_id());
715-
Some(ParentInfo {
716-
num,
717-
descr,
718-
parent_descr,
719-
span: tcx.def_ident_span(parent_item).unwrap(),
720-
})
722+
let span = if let DefKind::Impl { .. } = tcx.def_kind(parent_item) {
723+
tcx.def_span(parent_item)
724+
} else {
725+
tcx.def_ident_span(parent_item).unwrap()
726+
};
727+
Some(ParentInfo { num, descr, parent_descr, span })
721728
} else {
722729
None
723730
};
@@ -800,16 +807,7 @@ impl<'tcx> DeadVisitor<'tcx> {
800807
}
801808

802809
fn check_definition(&mut self, def_id: LocalDefId) {
803-
if self.live_symbols.contains(&def_id) {
804-
return;
805-
}
806-
if has_allow_dead_code_or_lang_attr(self.tcx, def_id) {
807-
return;
808-
}
809-
let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
810-
return
811-
};
812-
if name.as_str().starts_with('_') {
810+
if self.is_live_code(def_id) {
813811
return;
814812
}
815813
match self.tcx.def_kind(def_id) {
@@ -827,6 +825,18 @@ impl<'tcx> DeadVisitor<'tcx> {
827825
_ => {}
828826
}
829827
}
828+
829+
fn is_live_code(&self, def_id: LocalDefId) -> bool {
830+
// if we cannot get a name for the item, then we just assume that it is
831+
// live. I mean, we can't really emit a lint.
832+
let Some(name) = self.tcx.opt_item_name(def_id.to_def_id()) else {
833+
return true;
834+
};
835+
836+
self.live_symbols.contains(&def_id)
837+
|| has_allow_dead_code_or_lang_attr(self.tcx, def_id)
838+
|| name.as_str().starts_with('_')
839+
}
830840
}
831841

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

838848
for item in module_items.items() {
849+
if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind {
850+
let mut dead_items = Vec::new();
851+
for item in impl_item.items {
852+
let did = item.id.owner_id.def_id;
853+
if !visitor.is_live_code(did) {
854+
dead_items.push(did)
855+
}
856+
}
857+
visitor.warn_multiple_dead_codes(
858+
&dead_items,
859+
"used",
860+
Some(item.owner_id.def_id),
861+
false,
862+
);
863+
}
864+
839865
if !live_symbols.contains(&item.owner_id.def_id) {
840866
let parent = tcx.local_parent(item.owner_id.def_id);
841867
if parent != module && !live_symbols.contains(&parent) {
@@ -900,10 +926,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
900926
}
901927
}
902928

903-
for impl_item in module_items.impl_items() {
904-
visitor.check_definition(impl_item.owner_id.def_id);
905-
}
906-
907929
for foreign_item in module_items.foreign_items() {
908930
visitor.check_definition(foreign_item.owner_id.def_id);
909931
}

tests/ui/associated-consts/associated-const-dead-code.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
error: associated constant `BAR` is never used
22
--> $DIR/associated-const-dead-code.rs:6:11
33
|
4+
LL | impl MyFoo {
5+
| ---------- associated constant in this implementation
46
LL | const BAR: u32 = 1;
57
| ^^^
68
|

tests/ui/lint/dead-code/issue-85255.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ struct Foo {
1111
struct Bar;
1212

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

1818
pub(crate) struct Foo1 {
@@ -23,8 +23,8 @@ pub(crate) struct Foo1 {
2323
pub(crate) struct Bar1;
2424

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

3030
pub(crate) struct Foo2 {
@@ -35,8 +35,8 @@ pub(crate) struct Foo2 {
3535
pub(crate) struct Bar2;
3636

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

4242

tests/ui/lint/dead-code/issue-85255.stderr

+24-30
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ note: the lint level is defined here
1414
LL | #![warn(dead_code)]
1515
| ^^^^^^^^^
1616

17+
warning: methods `a` and `b` are never used
18+
--> $DIR/issue-85255.rs:14:8
19+
|
20+
LL | impl Bar {
21+
| -------- methods in this implementation
22+
LL | fn a(&self) -> i32 { 5 }
23+
| ^
24+
LL | pub fn b(&self) -> i32 { 6 }
25+
| ^
26+
1727
warning: fields `a` and `b` are never read
1828
--> $DIR/issue-85255.rs:19:5
1929
|
@@ -24,6 +34,16 @@ LL | a: i32,
2434
LL | pub b: i32,
2535
| ^
2636

37+
warning: methods `a` and `b` are never used
38+
--> $DIR/issue-85255.rs:26:8
39+
|
40+
LL | impl Bar1 {
41+
| --------- methods in this implementation
42+
LL | fn a(&self) -> i32 { 5 }
43+
| ^
44+
LL | pub fn b(&self) -> i32 { 6 }
45+
| ^
46+
2747
warning: fields `a` and `b` are never read
2848
--> $DIR/issue-85255.rs:31:5
2949
|
@@ -34,41 +54,15 @@ LL | a: i32,
3454
LL | pub b: i32,
3555
| ^
3656

37-
warning: method `a` is never used
38-
--> $DIR/issue-85255.rs:14:8
39-
|
40-
LL | fn a(&self) -> i32 { 5 }
41-
| ^
42-
43-
warning: method `b` is never used
44-
--> $DIR/issue-85255.rs:15:12
45-
|
46-
LL | pub fn b(&self) -> i32 { 6 }
47-
| ^
48-
49-
warning: method `a` is never used
50-
--> $DIR/issue-85255.rs:26:8
51-
|
52-
LL | fn a(&self) -> i32 { 5 }
53-
| ^
54-
55-
warning: method `b` is never used
56-
--> $DIR/issue-85255.rs:27:12
57-
|
58-
LL | pub fn b(&self) -> i32 { 6 }
59-
| ^
60-
61-
warning: method `a` is never used
57+
warning: methods `a` and `b` are never used
6258
--> $DIR/issue-85255.rs:38:8
6359
|
60+
LL | impl Bar2 {
61+
| --------- methods in this implementation
6462
LL | fn a(&self) -> i32 { 5 }
6563
| ^
66-
67-
warning: method `b` is never used
68-
--> $DIR/issue-85255.rs:39:12
69-
|
7064
LL | pub fn b(&self) -> i32 { 6 }
7165
| ^
7266

73-
warning: 9 warnings emitted
67+
warning: 6 warnings emitted
7468

tests/ui/lint/dead-code/lint-dead-code-3.stderr

+8-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ note: the lint level is defined here
1010
LL | #![deny(dead_code)]
1111
| ^^^^^^^^^
1212

13+
error: method `foo` is never used
14+
--> $DIR/lint-dead-code-3.rs:16:8
15+
|
16+
LL | impl Foo {
17+
| -------- method in this implementation
18+
LL | fn foo(&self) {
19+
| ^^^
20+
1321
error: function `bar` is never used
1422
--> $DIR/lint-dead-code-3.rs:21:4
1523
|
@@ -34,12 +42,6 @@ error: function `blah` is never used
3442
LL | fn blah() {}
3543
| ^^^^
3644

37-
error: method `foo` is never used
38-
--> $DIR/lint-dead-code-3.rs:16:8
39-
|
40-
LL | fn foo(&self) {
41-
| ^^^
42-
4345
error: function `free` is never used
4446
--> $DIR/lint-dead-code-3.rs:62:8
4547
|

tests/ui/lint/dead-code/lint-dead-code-6.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@
22

33
struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
44
impl UnusedStruct {
5-
fn unused_impl_fn_1() { //~ ERROR associated function `unused_impl_fn_1` is never used
5+
fn unused_impl_fn_1() {
6+
//~^ ERROR associated functions `unused_impl_fn_1`, `unused_impl_fn_2`, and `unused_impl_fn_3` are never used [dead_code]
67
println!("blah");
78
}
89

9-
fn unused_impl_fn_2(var: i32) { //~ ERROR associated function `unused_impl_fn_2` is never used
10+
fn unused_impl_fn_2(var: i32) {
1011
println!("foo {}", var);
1112
}
1213

13-
fn unused_impl_fn_3( //~ ERROR associated function `unused_impl_fn_3` is never used
14-
var: i32,
15-
) {
14+
fn unused_impl_fn_3(var: i32) {
1615
println!("bar {}", var);
1716
}
1817
}

tests/ui/lint/dead-code/lint-dead-code-6.stderr

+7-11
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,19 @@ note: the lint level is defined here
1010
LL | #![deny(dead_code)]
1111
| ^^^^^^^^^
1212

13-
error: associated function `unused_impl_fn_1` is never used
13+
error: associated functions `unused_impl_fn_1`, `unused_impl_fn_2`, and `unused_impl_fn_3` are never used
1414
--> $DIR/lint-dead-code-6.rs:5:8
1515
|
16+
LL | impl UnusedStruct {
17+
| ----------------- associated functions in this implementation
1618
LL | fn unused_impl_fn_1() {
1719
| ^^^^^^^^^^^^^^^^
18-
19-
error: associated function `unused_impl_fn_2` is never used
20-
--> $DIR/lint-dead-code-6.rs:9:8
21-
|
20+
...
2221
LL | fn unused_impl_fn_2(var: i32) {
2322
| ^^^^^^^^^^^^^^^^
24-
25-
error: associated function `unused_impl_fn_3` is never used
26-
--> $DIR/lint-dead-code-6.rs:13:8
27-
|
28-
LL | fn unused_impl_fn_3(
23+
...
24+
LL | fn unused_impl_fn_3(var: i32) {
2925
| ^^^^^^^^^^^^^^^^
3026

31-
error: aborting due to 4 previous errors
27+
error: aborting due to 2 previous errors
3228

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(inherent_associated_types)]
2+
#![allow(incomplete_features)]
3+
#![deny(unused)]
4+
5+
struct Foo;
6+
7+
impl Foo {
8+
fn one() {}
9+
//~^ ERROR associated items `one`, `two`, `CONSTANT`, `Type`, and `three` are never used [dead_code]
10+
11+
fn two(&self) {}
12+
13+
// seperation between items
14+
// ...
15+
// ...
16+
17+
fn used() {}
18+
19+
const CONSTANT: usize = 5;
20+
21+
// more seperation
22+
// ...
23+
// ...
24+
25+
type Type = usize;
26+
27+
fn three(&self) {
28+
Foo::one();
29+
// ...
30+
}
31+
}
32+
33+
fn main() {
34+
Foo::used();
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error: associated items `one`, `two`, `CONSTANT`, `Type`, and `three` are never used
2+
--> $DIR/unused-assoc-fns.rs:8:8
3+
|
4+
LL | impl Foo {
5+
| -------- associated items in this implementation
6+
LL | fn one() {}
7+
| ^^^
8+
...
9+
LL | fn two(&self) {}
10+
| ^^^
11+
...
12+
LL | const CONSTANT: usize = 5;
13+
| ^^^^^^^^
14+
...
15+
LL | type Type = usize;
16+
| ^^^^
17+
LL |
18+
LL | fn three(&self) {
19+
| ^^^^^
20+
|
21+
note: the lint level is defined here
22+
--> $DIR/unused-assoc-fns.rs:3:9
23+
|
24+
LL | #![deny(unused)]
25+
| ^^^^^^
26+
= note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
27+
28+
error: aborting due to previous error
29+

0 commit comments

Comments
 (0)