about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFabian Wolff <fabian.wolff@alumni.ethz.ch>2022-01-15 21:01:44 +0100
committerFabian Wolff <fabian.wolff@alumni.ethz.ch>2022-01-15 21:02:50 +0100
commit8b459dd73887732d4b2741b2459a2edd60a47229 (patch)
treedb918f15a68a88690016816d7589428d7b9118a3
parentbd1f09d417c8b0e460f90bcd23b9067d55f7f7dd (diff)
downloadrust-8b459dd73887732d4b2741b2459a2edd60a47229.tar.gz
rust-8b459dd73887732d4b2741b2459a2edd60a47229.zip
Use span of ignored impls for explanatory note
-rw-r--r--compiler/rustc_passes/src/dead.rs46
-rw-r--r--src/test/ui/derive-uninhabited-enum-38885.stderr9
-rw-r--r--src/test/ui/derives/clone-debug-dead-code.stderr27
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr9
4 files changed, 52 insertions, 39 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 9db9140f71e..3e4e9f205a4 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -16,6 +16,7 @@ use rustc_middle::middle::privacy;
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::lint;
 use rustc_span::symbol::{sym, Symbol};
+use rustc_span::Span;
 use std::mem;
 
 // Any local node that may call something in its body block should be
@@ -49,7 +50,9 @@ struct MarkSymbolVisitor<'tcx> {
     // maps from tuple struct constructors to tuple struct items
     struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
     // maps from ADTs to ignored derived traits (e.g. Debug and Clone)
-    ignored_derived_traits: FxHashMap<DefId, Vec<DefId>>,
+    // and the span of their respective impl (i.e., part of the derive
+    // macro)
+    ignored_derived_traits: FxHashMap<DefId, Vec<(Span, DefId)>>,
 }
 
 impl<'tcx> MarkSymbolVisitor<'tcx> {
@@ -255,10 +258,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                 if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) {
                     let trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap();
                     if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind() {
+                        let impl_span = self.tcx.def_span(impl_of);
                         if let Some(v) = self.ignored_derived_traits.get_mut(&adt_def.did) {
-                            v.push(trait_of);
+                            v.push((impl_span, trait_of));
                         } else {
-                            self.ignored_derived_traits.insert(adt_def.did, vec![trait_of]);
+                            self.ignored_derived_traits
+                                .insert(adt_def.did, vec![(impl_span, trait_of)]);
                         }
                     }
                     return true;
@@ -588,7 +593,7 @@ fn create_and_seed_worklist<'tcx>(
 fn find_live<'tcx>(
     tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
-) -> (FxHashSet<LocalDefId>, FxHashMap<DefId, Vec<DefId>>) {
+) -> (FxHashSet<LocalDefId>, FxHashMap<DefId, Vec<(Span, DefId)>>) {
     let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels);
     let mut symbol_visitor = MarkSymbolVisitor {
         worklist,
@@ -610,7 +615,7 @@ fn find_live<'tcx>(
 struct DeadVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
     live_symbols: FxHashSet<LocalDefId>,
-    ignored_derived_traits: FxHashMap<DefId, Vec<DefId>>,
+    ignored_derived_traits: FxHashMap<DefId, Vec<(Span, DefId)>>,
 }
 
 impl<'tcx> DeadVisitor<'tcx> {
@@ -683,26 +688,29 @@ impl<'tcx> DeadVisitor<'tcx> {
                 let hir = self.tcx.hir();
                 if let Some(encl_scope) = hir.get_enclosing_scope(id) {
                     if let Some(encl_def_id) = hir.opt_local_def_id(encl_scope) {
-                        if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id.to_def_id()) {
+                        if let Some(ign_traits) =
+                            self.ignored_derived_traits.get(&encl_def_id.to_def_id())
+                        {
                             let traits_str = ign_traits
                                 .iter()
-                                .map(|t| format!("`{}`", self.tcx.item_name(*t))).collect::<Vec<_>>()
+                                .map(|(_, t)| format!("`{}`", self.tcx.item_name(*t)))
+                                .collect::<Vec<_>>()
                                 .join(" and ");
                             let plural_s = pluralize!(ign_traits.len());
                             let article = if ign_traits.len() > 1 { "" } else { "a " };
                             let is_are = if ign_traits.len() > 1 { "these are" } else { "this is" };
-                            let msg = format!("`{}` has {}derived impl{} for the trait{} {}, but {} ignored during dead code analysis",
-                                              self.tcx.item_name(encl_def_id.to_def_id()),
-                                              article,
-                                              plural_s,
-                                              plural_s,
-                                              traits_str,
-                                              is_are);
-                            if let Some(span) = self.tcx.def_ident_span(encl_def_id) {
-                                err.span_note(span, &msg);
-                            } else {
-                                err.note(&msg);
-                            }
+                            let msg = format!(
+                                "`{}` has {}derived impl{} for the trait{} {}, but {} \
+                                 intentionally ignored during dead code analysis",
+                                self.tcx.item_name(encl_def_id.to_def_id()),
+                                article,
+                                plural_s,
+                                plural_s,
+                                traits_str,
+                                is_are
+                            );
+                            let multispan = ign_traits.iter().map(|(s, _)| *s).collect::<Vec<_>>();
+                            err.span_note(multispan, &msg);
                         }
                     }
                 }
diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr
index feaadd201b3..2a44e56a330 100644
--- a/src/test/ui/derive-uninhabited-enum-38885.stderr
+++ b/src/test/ui/derive-uninhabited-enum-38885.stderr
@@ -5,11 +5,12 @@ LL |     Void(Void),
    |     ^^^^^^^^^^
    |
    = note: `-W dead-code` implied by `-W unused`
-note: `Foo` has a derived impl for the trait `Debug`, but this is ignored during dead code analysis
-  --> $DIR/derive-uninhabited-enum-38885.rs:11:6
+note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+  --> $DIR/derive-uninhabited-enum-38885.rs:10:10
    |
-LL | enum Foo {
-   |      ^^^
+LL | #[derive(Debug)]
+   |          ^^^^^
+   = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: 1 warning emitted
 
diff --git a/src/test/ui/derives/clone-debug-dead-code.stderr b/src/test/ui/derives/clone-debug-dead-code.stderr
index d7cab0815b8..67bb574315a 100644
--- a/src/test/ui/derives/clone-debug-dead-code.stderr
+++ b/src/test/ui/derives/clone-debug-dead-code.stderr
@@ -16,11 +16,12 @@ error: field is never read: `f`
 LL | struct B { f: () }
    |            ^^^^^
    |
-note: `B` has a derived impl for the trait `Clone`, but this is ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:10:8
+note: `B` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
+  --> $DIR/clone-debug-dead-code.rs:9:10
    |
-LL | struct B { f: () }
-   |        ^
+LL | #[derive(Clone)]
+   |          ^^^^^
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:14:12
@@ -28,11 +29,12 @@ error: field is never read: `f`
 LL | struct C { f: () }
    |            ^^^^^
    |
-note: `C` has a derived impl for the trait `Debug`, but this is ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:14:8
+note: `C` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+  --> $DIR/clone-debug-dead-code.rs:13:10
    |
-LL | struct C { f: () }
-   |        ^
+LL | #[derive(Debug)]
+   |          ^^^^^
+   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:18:12
@@ -40,11 +42,12 @@ error: field is never read: `f`
 LL | struct D { f: () }
    |            ^^^^^
    |
-note: `D` has derived impls for the traits `Clone` and `Debug`, but these are ignored during dead code analysis
-  --> $DIR/clone-debug-dead-code.rs:18:8
+note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
+  --> $DIR/clone-debug-dead-code.rs:17:10
    |
-LL | struct D { f: () }
-   |        ^
+LL | #[derive(Debug,Clone)]
+   |          ^^^^^ ^^^^^
+   = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: field is never read: `f`
   --> $DIR/clone-debug-dead-code.rs:21:12
diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
index abac1f29ce2..3b5683a7748 100644
--- a/src/test/ui/lint/dead-code/unused-variant.stderr
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -9,11 +9,12 @@ note: the lint level is defined here
    |
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
-note: `Enum` has a derived impl for the trait `Clone`, but this is ignored during dead code analysis
-  --> $DIR/unused-variant.rs:4:6
+note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
+  --> $DIR/unused-variant.rs:3:10
    |
-LL | enum Enum {
-   |      ^^^^
+LL | #[derive(Clone)]
+   |          ^^^^^
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error