mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Use span of ignored impls for explanatory note
This commit is contained in:
parent
bd1f09d417
commit
8b459dd738
@ -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",
|
||||
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);
|
||||
if let Some(span) = self.tcx.def_ident_span(encl_def_id) {
|
||||
err.span_note(span, &msg);
|
||||
} else {
|
||||
err.note(&msg);
|
||||
}
|
||||
is_are
|
||||
);
|
||||
let multispan = ign_traits.iter().map(|(s, _)| *s).collect::<Vec<_>>();
|
||||
err.span_note(multispan, &msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user