about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEzra Shaw <ezrasure@outlook.com>2023-04-13 22:42:47 +1200
committerEzra Shaw <ezrasure@outlook.com>2023-04-13 22:42:47 +1200
commitc41dcac8e869160184fc2d80f643bc74601a45ef (patch)
tree72960db856ef92ccc695c49fb3fa1b86786e8372
parent03cf0e949fc1537f4a626eb0a925f23cb9010cb3 (diff)
downloadrust-c41dcac8e869160184fc2d80f643bc74601a45ef.tar.gz
rust-c41dcac8e869160184fc2d80f643bc74601a45ef.zip
dead-code-lint: de-dup multiple unused assoc fns
-rw-r--r--compiler/rustc_passes/src/dead.rs54
-rw-r--r--tests/ui/lint/dead-code/issue-85255.rs12
-rw-r--r--tests/ui/lint/dead-code/issue-85255.stderr26
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.stderr2
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.rs9
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.stderr18
-rw-r--r--tests/ui/lint/dead-code/unused-assoc-fns.rs4
-rw-r--r--tests/ui/lint/dead-code/unused-assoc-fns.stderr24
8 files changed, 77 insertions, 72 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d08dc4055ec..fc7755d3df8 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -712,12 +712,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 +800,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 +818,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) {
@@ -837,9 +840,26 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalDefId) {
 
     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 {
-                visitor.check_definition(item.id.owner_id.def_id);
+                match item.kind {
+                    hir::AssocItemKind::Const | hir::AssocItemKind::Type => {
+                        visitor.check_definition(item.id.owner_id.def_id)
+                    }
+                    hir::AssocItemKind::Fn { .. } => {
+                        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,
+            );
             continue;
         }
 
diff --git a/tests/ui/lint/dead-code/issue-85255.rs b/tests/ui/lint/dead-code/issue-85255.rs
index 1978bd4e824..d75a8e2dd41 100644
--- a/tests/ui/lint/dead-code/issue-85255.rs
+++ b/tests/ui/lint/dead-code/issue-85255.rs
@@ -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 }
 }
 
 
diff --git a/tests/ui/lint/dead-code/issue-85255.stderr b/tests/ui/lint/dead-code/issue-85255.stderr
index dec6f174628..d981085a4fa 100644
--- a/tests/ui/lint/dead-code/issue-85255.stderr
+++ b/tests/ui/lint/dead-code/issue-85255.stderr
@@ -14,15 +14,13 @@ note: the lint level is defined here
 LL | #![warn(dead_code)]
    |         ^^^^^^^^^
 
-warning: method `a` is never used
+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 }
    |        ^
-
-warning: method `b` is never used
-  --> $DIR/issue-85255.rs:15:12
-   |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
@@ -36,15 +34,13 @@ LL |     a: i32,
 LL |     pub b: i32,
    |         ^
 
-warning: method `a` is never used
+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 }
    |        ^
-
-warning: method `b` is never used
-  --> $DIR/issue-85255.rs:27:12
-   |
 LL |     pub fn b(&self) -> i32 { 6 }
    |            ^
 
@@ -58,17 +54,15 @@ LL |     a: i32,
 LL |     pub b: i32,
    |         ^
 
-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
 
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.stderr b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
index 9314f8be82a..5c68cf0e18b 100644
--- a/tests/ui/lint/dead-code/lint-dead-code-3.stderr
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -13,6 +13,8 @@ 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) {
    |        ^^^
 
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.rs b/tests/ui/lint/dead-code/lint-dead-code-6.rs
index e3074acf129..5b2b76b76ec 100644
--- a/tests/ui/lint/dead-code/lint-dead-code-6.rs
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.rs
@@ -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);
     }
 }
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.stderr b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
index f9d83308a3d..ce41100866a 100644
--- a/tests/ui/lint/dead-code/lint-dead-code-6.stderr
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
@@ -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
 
diff --git a/tests/ui/lint/dead-code/unused-assoc-fns.rs b/tests/ui/lint/dead-code/unused-assoc-fns.rs
index 11bdbca821b..9e3ad85390a 100644
--- a/tests/ui/lint/dead-code/unused-assoc-fns.rs
+++ b/tests/ui/lint/dead-code/unused-assoc-fns.rs
@@ -4,10 +4,9 @@ struct Foo;
 
 impl Foo {
     fn one() {}
-    //~^ ERROR associated function `one` is never used [dead_code]
+    //~^ ERROR associated functions `one`, `two`, and `three` are never used [dead_code]
 
     fn two(&self) {}
-    //~^ ERROR method `two` is never used [dead_code]
 
     // seperation between functions
     // ...
@@ -16,7 +15,6 @@ impl Foo {
     fn used() {}
 
     fn three(&self) {
-    //~^ ERROR method `three` is never used [dead_code]
         Foo::one();
         // ...
     }
diff --git a/tests/ui/lint/dead-code/unused-assoc-fns.stderr b/tests/ui/lint/dead-code/unused-assoc-fns.stderr
index 2b8ea88c609..71174a1c3de 100644
--- a/tests/ui/lint/dead-code/unused-assoc-fns.stderr
+++ b/tests/ui/lint/dead-code/unused-assoc-fns.stderr
@@ -1,8 +1,16 @@
-error: associated function `one` is never used
+error: associated functions `one`, `two`, and `three` are never used
   --> $DIR/unused-assoc-fns.rs:6:8
    |
+LL | impl Foo {
+   | -------- associated functions in this implementation
 LL |     fn one() {}
    |        ^^^
+...
+LL |     fn two(&self) {}
+   |        ^^^
+...
+LL |     fn three(&self) {
+   |        ^^^^^
    |
 note: the lint level is defined here
   --> $DIR/unused-assoc-fns.rs:1:9
@@ -11,17 +19,5 @@ LL | #![deny(unused)]
    |         ^^^^^^
    = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
 
-error: method `two` is never used
-  --> $DIR/unused-assoc-fns.rs:9:8
-   |
-LL |     fn two(&self) {}
-   |        ^^^
-
-error: method `three` is never used
-  --> $DIR/unused-assoc-fns.rs:18:8
-   |
-LL |     fn three(&self) {
-   |        ^^^^^
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error