1
Fork 0

Auto merge of #97853 - TaKO8Ki:emit-only-one-note-per-unused-struct-field, r=estebank

Collapse multiple dead code warnings into a single diagnostic

closes #97643
This commit is contained in:
bors 2022-06-22 02:51:55 +00:00
commit 3d829a0922
76 changed files with 606 additions and 319 deletions

View file

@ -4287,6 +4287,7 @@ dependencies = [
name = "rustc_passes" name = "rustc_passes"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"itertools",
"rustc_ast", "rustc_ast",
"rustc_ast_pretty", "rustc_ast_pretty",
"rustc_attr", "rustc_attr",

View file

@ -5,6 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
tracing = "0.1" tracing = "0.1"
itertools = "0.10.1"
rustc_middle = { path = "../rustc_middle" } rustc_middle = { path = "../rustc_middle" }
rustc_attr = { path = "../rustc_attr" } rustc_attr = { path = "../rustc_attr" }
rustc_data_structures = { path = "../rustc_data_structures" } rustc_data_structures = { path = "../rustc_data_structures" }

View file

@ -2,8 +2,9 @@
// closely. The idea is that all reachable symbols are live, codes called // closely. The idea is that all reachable symbols are live, codes called
// from live codes are live, and everything else is dead. // from live codes are live, and everything else is dead.
use itertools::Itertools;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::pluralize; use rustc_errors::{pluralize, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
@ -183,10 +184,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
} }
} }
if let hir::ExprKind::Assign(lhs, rhs, _) = assign.kind { if let hir::ExprKind::Assign(lhs, rhs, _) = assign.kind
if check_for_self_assign_helper(self.typeck_results(), lhs, rhs) && check_for_self_assign_helper(self.typeck_results(), lhs, rhs)
&& !assign.span.from_expansion() && !assign.span.from_expansion()
{ {
let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..)); let is_field_assign = matches!(lhs.kind, hir::ExprKind::Field(..));
self.tcx.struct_span_lint_hir( self.tcx.struct_span_lint_hir(
lint::builtin::DEAD_CODE, lint::builtin::DEAD_CODE,
@ -201,7 +202,6 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
.emit(); .emit();
}, },
) )
}
} }
} }
@ -251,19 +251,19 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
return false; return false;
} }
if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of) { if let Some(trait_of) = self.tcx.trait_id_of_impl(impl_of)
if self.tcx.has_attr(trait_of, sym::rustc_trivial_field_reads) { && 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 trait_ref = self.tcx.impl_trait_ref(impl_of).unwrap();
if let Some(adt_def_id) = adt_def.did().as_local() { if let ty::Adt(adt_def, _) = trait_ref.self_ty().kind()
self.ignored_derived_traits && let Some(adt_def_id) = adt_def.did().as_local()
.entry(adt_def_id) {
.or_default() self.ignored_derived_traits
.push((trait_of, impl_of)); .entry(adt_def_id)
} .or_default()
} .push((trait_of, impl_of));
return true;
} }
return true;
} }
} }
@ -271,13 +271,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
} }
fn visit_node(&mut self, node: Node<'tcx>) { fn visit_node(&mut self, node: Node<'tcx>) {
if let Some(item_def_id) = match node { if let Node::ImplItem(hir::ImplItem { def_id, .. }) = node
Node::ImplItem(hir::ImplItem { def_id, .. }) => Some(def_id.to_def_id()), && self.should_ignore_item(def_id.to_def_id())
_ => None, {
} { return;
if self.should_ignore_item(item_def_id) {
return;
}
} }
let had_repr_c = self.repr_has_repr_c; let had_repr_c = self.repr_has_repr_c;
@ -534,10 +531,10 @@ fn check_item<'tcx>(
} }
DefKind::Struct => { DefKind::Struct => {
let item = tcx.hir().item(id); let item = tcx.hir().item(id);
if let hir::ItemKind::Struct(ref variant_data, _) = item.kind { if let hir::ItemKind::Struct(ref variant_data, _) = item.kind
if let Some(ctor_hir_id) = variant_data.ctor_hir_id() { && let Some(ctor_hir_id) = variant_data.ctor_hir_id()
struct_constructors.insert(tcx.hir().local_def_id(ctor_hir_id), item.def_id); {
} struct_constructors.insert(tcx.hir().local_def_id(ctor_hir_id), item.def_id);
} }
} }
DefKind::GlobalAsm => { DefKind::GlobalAsm => {
@ -626,6 +623,13 @@ fn live_symbols_and_ignored_derived_traits<'tcx>(
(symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits) (symbol_visitor.live_symbols, symbol_visitor.ignored_derived_traits)
} }
struct DeadVariant {
hir_id: hir::HirId,
span: Span,
name: Symbol,
level: lint::Level,
}
struct DeadVisitor<'tcx> { struct DeadVisitor<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
live_symbols: &'tcx FxHashSet<LocalDefId>, live_symbols: &'tcx FxHashSet<LocalDefId>,
@ -677,16 +681,121 @@ impl<'tcx> DeadVisitor<'tcx> {
let inherent_impls = self.tcx.inherent_impls(def_id); let inherent_impls = self.tcx.inherent_impls(def_id);
for &impl_did in inherent_impls.iter() { for &impl_did in inherent_impls.iter() {
for item_did in self.tcx.associated_item_def_ids(impl_did) { for item_did in self.tcx.associated_item_def_ids(impl_did) {
if let Some(def_id) = item_did.as_local() { if let Some(def_id) = item_did.as_local()
if self.live_symbols.contains(&def_id) { && self.live_symbols.contains(&def_id)
return true; {
} return true;
} }
} }
} }
false false
} }
fn warn_multiple_dead_codes(
&self,
dead_codes: &[(hir::HirId, Span, Symbol)],
participle: &str,
parent_hir_id: Option<hir::HirId>,
) {
if let Some((id, _, name)) = dead_codes.first()
&& !name.as_str().starts_with('_')
{
self.tcx.struct_span_lint_hir(
lint::builtin::DEAD_CODE,
*id,
MultiSpan::from_spans(
dead_codes.iter().map(|(_, span, _)| *span).collect(),
),
|lint| {
let def_id = self.tcx.hir().local_def_id(*id);
let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
let span_len = dead_codes.len();
let names = match &dead_codes.iter().map(|(_, _, n)| n.to_string()).collect::<Vec<_>>()[..]
{
_ if span_len > 6 => String::new(),
[name] => format!("`{name}` "),
[names @ .., last] => {
format!("{} and `{last}` ", names.iter().map(|name| format!("`{name}`")).join(", "))
}
[] => unreachable!(),
};
let mut err = lint.build(&format!(
"{these}{descr}{s} {names}{are} never {participle}",
these = if span_len > 6 { "multiple " } else { "" },
s = pluralize!(span_len),
are = pluralize!("is", span_len),
));
let hir = self.tcx.hir();
if let Some(parent_hir_id) = parent_hir_id
&& let Some(parent_node) = hir.find(parent_hir_id)
&& let Node::Item(item) = parent_node
{
let def_id = self.tcx.hir().local_def_id(parent_hir_id);
let parent_descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
err.span_label(
item.ident.span,
format!(
"{descr}{s} in this {parent_descr}",
s = pluralize!(span_len)
),
);
}
if let Some(encl_scope) = hir.get_enclosing_scope(*id)
&& let Some(encl_def_id) = hir.opt_local_def_id(encl_scope)
&& let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id)
{
let traits_str = ign_traits
.iter()
.map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id)))
.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 {} \
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
);
err.note(&msg);
}
err.emit();
},
);
}
}
fn warn_dead_fields_and_variants(
&self,
hir_id: hir::HirId,
participle: &str,
dead_codes: Vec<DeadVariant>,
) {
let mut dead_codes = dead_codes
.iter()
.filter(|v| !v.name.as_str().starts_with('_'))
.map(|v| v)
.collect::<Vec<&DeadVariant>>();
if dead_codes.is_empty() {
return;
}
dead_codes.sort_by_key(|v| v.level);
for (_, group) in &dead_codes.into_iter().group_by(|v| v.level) {
self.warn_multiple_dead_codes(
&group
.map(|v| (v.hir_id, v.span, v.name))
.collect::<Vec<(hir::HirId, Span, Symbol)>>(),
participle,
Some(hir_id),
);
}
}
fn warn_dead_code( fn warn_dead_code(
&mut self, &mut self,
id: hir::HirId, id: hir::HirId,
@ -694,39 +803,7 @@ impl<'tcx> DeadVisitor<'tcx> {
name: Symbol, name: Symbol,
participle: &str, participle: &str,
) { ) {
if !name.as_str().starts_with('_') { self.warn_multiple_dead_codes(&[(id, span, name)], participle, None);
self.tcx.struct_span_lint_hir(lint::builtin::DEAD_CODE, id, span, |lint| {
let def_id = self.tcx.hir().local_def_id(id);
let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
let mut err = lint.build(&format!("{} is never {}: `{}`", descr, participle, name));
let hir = self.tcx.hir();
if let Some(encl_scope) = hir.get_enclosing_scope(id)
&& let Some(encl_def_id) = hir.opt_local_def_id(encl_scope)
&& let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id)
{
let traits_str = ign_traits
.iter()
.map(|(trait_id, _)| format!("`{}`", self.tcx.item_name(*trait_id)))
.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 {} \
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
);
err.note(&msg);
}
err.emit();
});
}
} }
} }
@ -780,15 +857,40 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
// This visitor should only visit a single module at a time. // This visitor should only visit a single module at a time.
fn visit_mod(&mut self, _: &'tcx hir::Mod<'tcx>, _: Span, _: hir::HirId) {} fn visit_mod(&mut self, _: &'tcx hir::Mod<'tcx>, _: Span, _: hir::HirId) {}
fn visit_enum_def(
&mut self,
enum_definition: &'tcx hir::EnumDef<'tcx>,
generics: &'tcx hir::Generics<'tcx>,
item_id: hir::HirId,
_: Span,
) {
intravisit::walk_enum_def(self, enum_definition, generics, item_id);
let dead_variants = enum_definition
.variants
.iter()
.filter_map(|variant| {
if self.should_warn_about_variant(&variant) {
Some(DeadVariant {
hir_id: variant.id,
span: variant.span,
name: variant.ident.name,
level: self.tcx.lint_level_at_node(lint::builtin::DEAD_CODE, variant.id).0,
})
} else {
None
}
})
.collect();
self.warn_dead_fields_and_variants(item_id, "constructed", dead_variants)
}
fn visit_variant( fn visit_variant(
&mut self, &mut self,
variant: &'tcx hir::Variant<'tcx>, variant: &'tcx hir::Variant<'tcx>,
g: &'tcx hir::Generics<'tcx>, g: &'tcx hir::Generics<'tcx>,
id: hir::HirId, id: hir::HirId,
) { ) {
if self.should_warn_about_variant(&variant) { if !self.should_warn_about_variant(&variant) {
self.warn_dead_code(variant.id, variant.span, variant.ident.name, "constructed");
} else {
intravisit::walk_variant(self, variant, g, id); intravisit::walk_variant(self, variant, g, id);
} }
} }
@ -800,11 +902,35 @@ impl<'tcx> Visitor<'tcx> for DeadVisitor<'tcx> {
intravisit::walk_foreign_item(self, fi); intravisit::walk_foreign_item(self, fi);
} }
fn visit_field_def(&mut self, field: &'tcx hir::FieldDef<'tcx>) { fn visit_variant_data(
if self.should_warn_about_field(&field) { &mut self,
self.warn_dead_code(field.hir_id, field.span, field.ident.name, "read"); def: &'tcx hir::VariantData<'tcx>,
} _: Symbol,
intravisit::walk_field_def(self, field); _: &hir::Generics<'_>,
id: hir::HirId,
_: rustc_span::Span,
) {
intravisit::walk_struct_def(self, def);
let dead_fields = def
.fields()
.iter()
.filter_map(|field| {
if self.should_warn_about_field(&field) {
Some(DeadVariant {
hir_id: field.hir_id,
span: field.span,
name: field.ident.name,
level: self
.tcx
.lint_level_at_node(lint::builtin::DEAD_CODE, field.hir_id)
.0,
})
} else {
None
}
})
.collect();
self.warn_dead_fields_and_variants(id, "read", dead_fields)
} }
fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {

View file

@ -24,7 +24,7 @@ warning: unused variable: `x`
LL | fn foo(x: &dyn std::fmt::Display) {} LL | fn foo(x: &dyn std::fmt::Display) {}
| ^ help: if this is intentional, prefix it with an underscore: `_x` | ^ help: if this is intentional, prefix it with an underscore: `_x`
warning: function is never used: `foo` warning: function `foo` is never used
--> $DIR/display-output.rs:13:4 --> $DIR/display-output.rs:13:4
| |
LL | fn foo(x: &dyn std::fmt::Display) {} LL | fn foo(x: &dyn std::fmt::Display) {}

View file

@ -4,7 +4,7 @@ struct MyFoo;
impl MyFoo { impl MyFoo {
const BAR: u32 = 1; const BAR: u32 = 1;
//~^ ERROR associated constant is never used: `BAR` //~^ ERROR associated constant `BAR` is never used
} }
fn main() { fn main() {

View file

@ -1,4 +1,4 @@
error: associated constant is never used: `BAR` error: associated constant `BAR` is never used
--> $DIR/associated-const-dead-code.rs:6:5 --> $DIR/associated-const-dead-code.rs:6:5
| |
LL | const BAR: u32 = 1; LL | const BAR: u32 = 1;

View file

@ -2,16 +2,13 @@
// edition:2021 // edition:2021
struct Props { struct Props {
field_1: u32, //~ WARNING: field is never read: `field_1` field_1: u32, //~ WARNING: fields `field_1` and `field_2` are never read
field_2: u32, //~ WARNING: field is never read: `field_2` field_2: u32,
} }
fn main() { fn main() {
// Test 1 // Test 1
let props_2 = Props { let props_2 = Props { field_1: 1, field_2: 1 };
field_1: 1,
field_2: 1,
};
let _ = || { let _ = || {
let _: Props = props_2; let _: Props = props_2;
@ -23,7 +20,7 @@ fn main() {
let mref = &mut arr; let mref = &mut arr;
let _c = || match arr { let _c = || match arr {
[_, _, _, _] => println!("A") [_, _, _, _] => println!("A"),
}; };
println!("{:#?}", mref); println!("{:#?}", mref);

View file

@ -1,16 +1,14 @@
warning: field is never read: `field_1` warning: fields `field_1` and `field_2` are never read
--> $DIR/issue-87987.rs:5:5 --> $DIR/issue-87987.rs:5:5
| |
LL | struct Props {
| ----- fields in this struct
LL | field_1: u32, LL | field_1: u32,
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
LL | field_2: u32,
| ^^^^^^^^^^^^
| |
= note: `#[warn(dead_code)]` on by default = note: `#[warn(dead_code)]` on by default
warning: field is never read: `field_2` warning: 1 warning emitted
--> $DIR/issue-87987.rs:6:5
|
LL | field_2: u32,
| ^^^^^^^^^^^^
warning: 2 warnings emitted

View file

@ -3,7 +3,7 @@
enum Variant { enum Variant {
A, A,
B, //~ WARNING: variant is never constructed: `B` B, //~ WARNING: variant `B` is never constructed
} }
struct A { struct A {

View file

@ -1,6 +1,9 @@
warning: variant is never constructed: `B` warning: variant `B` is never constructed
--> $DIR/issue-87097.rs:6:5 --> $DIR/issue-87097.rs:6:5
| |
LL | enum Variant {
| ------- variant in this enum
LL | A,
LL | B, LL | B,
| ^ | ^
| |

View file

@ -10,7 +10,7 @@ enum Void {}
#[derive(Debug)] #[derive(Debug)]
enum Foo { enum Foo {
Bar(u8), Bar(u8),
Void(Void), //~ WARN never constructed Void(Void), //~ WARN variant `Void` is never constructed
} }
fn main() { fn main() {

View file

@ -1,6 +1,9 @@
warning: variant is never constructed: `Void` warning: variant `Void` is never constructed
--> $DIR/derive-uninhabited-enum-38885.rs:13:5 --> $DIR/derive-uninhabited-enum-38885.rs:13:5
| |
LL | enum Foo {
| --- variant in this enum
LL | Bar(u8),
LL | Void(Void), LL | Void(Void),
| ^^^^^^^^^^ | ^^^^^^^^^^
| |

View file

@ -0,0 +1,12 @@
#![forbid(dead_code)]
#[derive(Debug)]
pub struct Whatever {
pub field0: (),
field1: (), //~ ERROR fields `field1`, `field2`, `field3` and `field4` are never read
field2: (),
field3: (),
field4: (),
}
fn main() {}

View file

@ -0,0 +1,24 @@
error: fields `field1`, `field2`, `field3` and `field4` are never read
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5
|
LL | pub struct Whatever {
| -------- fields in this struct
LL | pub field0: (),
LL | field1: (),
| ^^^^^^^^^^
LL | field2: (),
| ^^^^^^^^^^
LL | field3: (),
| ^^^^^^^^^^
LL | field4: (),
| ^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
|
LL | #![forbid(dead_code)]
| ^^^^^^^^^
= note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
error: aborting due to previous error

View file

@ -4,22 +4,22 @@
#![forbid(dead_code)] #![forbid(dead_code)]
struct A { f: () } struct A { f: () }
//~^ ERROR: field is never read: `f` //~^ ERROR: field `f` is never read
#[derive(Clone)] #[derive(Clone)]
struct B { f: () } struct B { f: () }
//~^ ERROR: field is never read: `f` //~^ ERROR: field `f` is never read
#[derive(Debug)] #[derive(Debug)]
struct C { f: () } struct C { f: () }
//~^ ERROR: field is never read: `f` //~^ ERROR: field `f` is never read
#[derive(Debug,Clone)] #[derive(Debug,Clone)]
struct D { f: () } struct D { f: () }
//~^ ERROR: field is never read: `f` //~^ ERROR: field `f` is never read
struct E { f: () } struct E { f: () }
//~^ ERROR: field is never read: `f` //~^ ERROR: field `f` is never read
// Custom impl, still doesn't read f // Custom impl, still doesn't read f
impl Clone for E { impl Clone for E {
fn clone(&self) -> Self { fn clone(&self) -> Self {

View file

@ -1,8 +1,10 @@
error: field is never read: `f` error: field `f` is never read
--> $DIR/clone-debug-dead-code.rs:6:12 --> $DIR/clone-debug-dead-code.rs:6:12
| |
LL | struct A { f: () } LL | struct A { f: () }
| ^^^^^ | - ^^^^^
| |
| field in this struct
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/clone-debug-dead-code.rs:4:11 --> $DIR/clone-debug-dead-code.rs:4:11
@ -10,35 +12,43 @@ note: the lint level is defined here
LL | #![forbid(dead_code)] LL | #![forbid(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: field is never read: `f` error: field `f` is never read
--> $DIR/clone-debug-dead-code.rs:10:12 --> $DIR/clone-debug-dead-code.rs:10:12
| |
LL | struct B { f: () } LL | struct B { f: () }
| ^^^^^ | - ^^^^^
| |
| field in this struct
| |
= note: `B` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis = note: `B` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
error: field is never read: `f` error: field `f` is never read
--> $DIR/clone-debug-dead-code.rs:14:12 --> $DIR/clone-debug-dead-code.rs:14:12
| |
LL | struct C { f: () } LL | struct C { f: () }
| ^^^^^ | - ^^^^^
| |
| field in this struct
| |
= note: `C` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis = note: `C` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
error: field is never read: `f` error: field `f` is never read
--> $DIR/clone-debug-dead-code.rs:18:12 --> $DIR/clone-debug-dead-code.rs:18:12
| |
LL | struct D { f: () } LL | struct D { f: () }
| ^^^^^ | - ^^^^^
| |
| field in this struct
| |
= note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis = note: `D` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
error: field is never read: `f` error: field `f` is never read
--> $DIR/clone-debug-dead-code.rs:21:12 --> $DIR/clone-debug-dead-code.rs:21:12
| |
LL | struct E { f: () } LL | struct E { f: () }
| ^^^^^ | - ^^^^^
| |
| field in this struct
error: aborting due to 5 previous errors error: aborting due to 5 previous errors

View file

@ -3,6 +3,6 @@
#![warn(unused)] #![warn(unused)]
type Z = dyn for<'x> Send; type Z = dyn for<'x> Send;
//~^ WARN type alias is never used //~^ WARN type alias `Z` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
warning: type alias is never used: `Z` warning: type alias `Z` is never used
--> $DIR/issue-37515.rs:5:1 --> $DIR/issue-37515.rs:5:1
| |
LL | type Z = dyn for<'x> Send; LL | type Z = dyn for<'x> Send;

View file

@ -1,7 +1,7 @@
#![deny(dead_code)] #![deny(dead_code)]
#![allow(unreachable_code)] #![allow(unreachable_code)]
fn foo() { //~ ERROR function is never used fn foo() { //~ ERROR function `foo` is never used
// none of these should have any dead_code exposed to the user // none of these should have any dead_code exposed to the user
panic!(); panic!();

View file

@ -1,4 +1,4 @@
error: function is never used: `foo` error: function `foo` is never used
--> $DIR/basic.rs:4:4 --> $DIR/basic.rs:4:4
| |
LL | fn foo() { LL | fn foo() {

View file

@ -30,8 +30,8 @@ impl Foo<Y> for X {
enum E { enum E {
A, A,
B, //~ WARN variant is never constructed: `B` B, //~ WARN variants `B` and `C` are never constructed
C, //~ WARN variant is never constructed: `C` C,
} }
type F = E; type F = E;

View file

@ -1,8 +1,13 @@
warning: variant is never constructed: `B` warning: variants `B` and `C` are never constructed
--> $DIR/const-and-self.rs:33:5 --> $DIR/const-and-self.rs:33:5
| |
LL | enum E {
| - variants in this enum
LL | A,
LL | B, LL | B,
| ^ | ^
LL | C,
| ^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/const-and-self.rs:3:9 --> $DIR/const-and-self.rs:3:9
@ -10,11 +15,5 @@ note: the lint level is defined here
LL | #![warn(dead_code)] LL | #![warn(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
warning: variant is never constructed: `C` warning: 1 warning emitted
--> $DIR/const-and-self.rs:34:5
|
LL | C,
| ^
warning: 2 warnings emitted

View file

@ -1,5 +1,5 @@
#![deny(unused)] #![deny(unused)]
enum E {} //~ ERROR enum is never used enum E {} //~ ERROR enum `E` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: enum is never used: `E` error: enum `E` is never used
--> $DIR/empty-unused-enum.rs:3:6 --> $DIR/empty-unused-enum.rs:3:6
| |
LL | enum E {} LL | enum E {}

View file

@ -9,7 +9,7 @@ impl Trait for () {
} }
type Used = (); type Used = ();
type Unused = (); //~ ERROR type alias is never used type Unused = (); //~ ERROR type alias `Unused` is never used
fn foo() -> impl Trait<Type = Used> {} fn foo() -> impl Trait<Type = Used> {}

View file

@ -1,4 +1,4 @@
error: type alias is never used: `Unused` error: type alias `Unused` is never used
--> $DIR/impl-trait.rs:12:1 --> $DIR/impl-trait.rs:12:1
| |
LL | type Unused = (); LL | type Unused = ();

View file

@ -4,39 +4,39 @@
#![warn(dead_code)] #![warn(dead_code)]
struct Foo { struct Foo {
a: i32, //~ WARNING: field is never read a: i32, //~ WARNING: fields `a` and `b` are never read
pub b: i32, //~ WARNING: field is never read pub b: i32,
} }
struct Bar; struct Bar;
impl Bar { impl Bar {
fn a(&self) -> i32 { 5 } //~ WARNING: associated function is never used fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function is never used pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
} }
pub(crate) struct Foo1 { pub(crate) struct Foo1 {
a: i32, //~ WARNING: field is never read a: i32, //~ WARNING: fields `a` and `b` are never read
pub b: i32, //~ WARNING: field is never read pub b: i32,
} }
pub(crate) struct Bar1; pub(crate) struct Bar1;
impl Bar1 { impl Bar1 {
fn a(&self) -> i32 { 5 } //~ WARNING: associated function is never used fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function is never used pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
} }
pub(crate) struct Foo2 { pub(crate) struct Foo2 {
a: i32, //~ WARNING: field is never read a: i32, //~ WARNING: fields `a` and `b` are never read
pub b: i32, //~ WARNING: field is never read pub b: i32,
} }
pub(crate) struct Bar2; pub(crate) struct Bar2;
impl Bar2 { impl Bar2 {
fn a(&self) -> i32 { 5 } //~ WARNING: associated function is never used fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function is never used pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
} }

View file

@ -1,8 +1,12 @@
warning: field is never read: `a` warning: fields `a` and `b` are never read
--> $DIR/issue-85255.rs:7:5 --> $DIR/issue-85255.rs:7:5
| |
LL | struct Foo {
| --- fields in this struct
LL | a: i32, LL | a: i32,
| ^^^^^^ | ^^^^^^
LL | pub b: i32,
| ^^^^^^^^^^
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/issue-85255.rs:4:9 --> $DIR/issue-85255.rs:4:9
@ -10,71 +14,61 @@ note: the lint level is defined here
LL | #![warn(dead_code)] LL | #![warn(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
warning: field is never read: `b` warning: associated function `a` is never used
--> $DIR/issue-85255.rs:8:5
|
LL | pub b: i32,
| ^^^^^^^^^^
warning: associated function is never used: `a`
--> $DIR/issue-85255.rs:14:8 --> $DIR/issue-85255.rs:14:8
| |
LL | fn a(&self) -> i32 { 5 } LL | fn a(&self) -> i32 { 5 }
| ^ | ^
warning: associated function is never used: `b` warning: associated function `b` is never used
--> $DIR/issue-85255.rs:15:12 --> $DIR/issue-85255.rs:15:12
| |
LL | pub fn b(&self) -> i32 { 6 } LL | pub fn b(&self) -> i32 { 6 }
| ^ | ^
warning: field is never read: `a` warning: fields `a` and `b` are never read
--> $DIR/issue-85255.rs:19:5 --> $DIR/issue-85255.rs:19:5
| |
LL | pub(crate) struct Foo1 {
| ---- fields in this struct
LL | a: i32, LL | a: i32,
| ^^^^^^ | ^^^^^^
warning: field is never read: `b`
--> $DIR/issue-85255.rs:20:5
|
LL | pub b: i32, LL | pub b: i32,
| ^^^^^^^^^^ | ^^^^^^^^^^
warning: associated function is never used: `a` warning: associated function `a` is never used
--> $DIR/issue-85255.rs:26:8 --> $DIR/issue-85255.rs:26:8
| |
LL | fn a(&self) -> i32 { 5 } LL | fn a(&self) -> i32 { 5 }
| ^ | ^
warning: associated function is never used: `b` warning: associated function `b` is never used
--> $DIR/issue-85255.rs:27:12 --> $DIR/issue-85255.rs:27:12
| |
LL | pub fn b(&self) -> i32 { 6 } LL | pub fn b(&self) -> i32 { 6 }
| ^ | ^
warning: field is never read: `a` warning: fields `a` and `b` are never read
--> $DIR/issue-85255.rs:31:5 --> $DIR/issue-85255.rs:31:5
| |
LL | pub(crate) struct Foo2 {
| ---- fields in this struct
LL | a: i32, LL | a: i32,
| ^^^^^^ | ^^^^^^
warning: field is never read: `b`
--> $DIR/issue-85255.rs:32:5
|
LL | pub b: i32, LL | pub b: i32,
| ^^^^^^^^^^ | ^^^^^^^^^^
warning: associated function is never used: `a` warning: associated function `a` is never used
--> $DIR/issue-85255.rs:38:8 --> $DIR/issue-85255.rs:38:8
| |
LL | fn a(&self) -> i32 { 5 } LL | fn a(&self) -> i32 { 5 }
| ^ | ^
warning: associated function is never used: `b` warning: associated function `b` is never used
--> $DIR/issue-85255.rs:39:12 --> $DIR/issue-85255.rs:39:12
| |
LL | pub fn b(&self) -> i32 { 6 } LL | pub fn b(&self) -> i32 { 6 }
| ^ | ^
warning: 12 warnings emitted warning: 9 warnings emitted

View file

@ -9,7 +9,7 @@
pub use foo2::Bar2; pub use foo2::Bar2;
mod foo { mod foo {
pub struct Bar; //~ ERROR: struct is never constructed pub struct Bar; //~ ERROR: struct `Bar` is never constructed
} }
mod foo2 { mod foo2 {
@ -17,14 +17,14 @@ mod foo2 {
} }
pub static pub_static: isize = 0; pub static pub_static: isize = 0;
static priv_static: isize = 0; //~ ERROR: static is never used static priv_static: isize = 0; //~ ERROR: static `priv_static` is never used
const used_static: isize = 0; const used_static: isize = 0;
pub static used_static2: isize = used_static; pub static used_static2: isize = used_static;
const USED_STATIC: isize = 0; const USED_STATIC: isize = 0;
const STATIC_USED_IN_ENUM_DISCRIMINANT: isize = 10; const STATIC_USED_IN_ENUM_DISCRIMINANT: isize = 10;
pub const pub_const: isize = 0; pub const pub_const: isize = 0;
const priv_const: isize = 0; //~ ERROR: constant is never used const priv_const: isize = 0; //~ ERROR: constant `priv_const` is never used
const used_const: isize = 0; const used_const: isize = 0;
pub const used_const2: isize = used_const; pub const used_const2: isize = used_const;
const USED_CONST: isize = 1; const USED_CONST: isize = 1;
@ -32,7 +32,7 @@ const CONST_USED_IN_ENUM_DISCRIMINANT: isize = 11;
pub type typ = *const UsedStruct4; pub type typ = *const UsedStruct4;
pub struct PubStruct; pub struct PubStruct;
struct PrivStruct; //~ ERROR: struct is never constructed struct PrivStruct; //~ ERROR: struct `PrivStruct` is never constructed
struct UsedStruct1 { struct UsedStruct1 {
#[allow(dead_code)] #[allow(dead_code)]
x: isize x: isize
@ -61,10 +61,10 @@ pub enum pub_enum3 {
Bar = CONST_USED_IN_ENUM_DISCRIMINANT, Bar = CONST_USED_IN_ENUM_DISCRIMINANT,
} }
enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used enum priv_enum { foo2, bar2 } //~ ERROR: enum `priv_enum` is never used
enum used_enum { enum used_enum {
foo3, foo3,
bar3 //~ ERROR variant is never constructed bar3 //~ ERROR variant `bar3` is never constructed
} }
fn f<T>() {} fn f<T>() {}
@ -85,21 +85,21 @@ pub fn pub_fn() {
} }
f::<StructUsedInGeneric>(); f::<StructUsedInGeneric>();
} }
fn priv_fn() { //~ ERROR: function is never used fn priv_fn() { //~ ERROR: function `priv_fn` is never used
let unused_struct = PrivStruct; let unused_struct = PrivStruct;
} }
fn used_fn() {} fn used_fn() {}
fn foo() { //~ ERROR: function is never used fn foo() { //~ ERROR: function `foo` is never used
bar(); bar();
let unused_enum = priv_enum::foo2; let unused_enum = priv_enum::foo2;
} }
fn bar() { //~ ERROR: function is never used fn bar() { //~ ERROR: function `bar` is never used
foo(); foo();
} }
fn baz() -> impl Copy { //~ ERROR: function is never used fn baz() -> impl Copy { //~ ERROR: function `baz` is never used
"I'm unused, too" "I'm unused, too"
} }

View file

@ -1,4 +1,4 @@
error: static is never used: `priv_static` error: static `priv_static` is never used
--> $DIR/lint-dead-code-1.rs:20:1 --> $DIR/lint-dead-code-1.rs:20:1
| |
LL | static priv_static: isize = 0; LL | static priv_static: isize = 0;
@ -10,55 +10,58 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: constant is never used: `priv_const` error: constant `priv_const` is never used
--> $DIR/lint-dead-code-1.rs:27:1 --> $DIR/lint-dead-code-1.rs:27:1
| |
LL | const priv_const: isize = 0; LL | const priv_const: isize = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: struct is never constructed: `PrivStruct` error: struct `PrivStruct` is never constructed
--> $DIR/lint-dead-code-1.rs:35:8 --> $DIR/lint-dead-code-1.rs:35:8
| |
LL | struct PrivStruct; LL | struct PrivStruct;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: enum is never used: `priv_enum` error: enum `priv_enum` is never used
--> $DIR/lint-dead-code-1.rs:64:6 --> $DIR/lint-dead-code-1.rs:64:6
| |
LL | enum priv_enum { foo2, bar2 } LL | enum priv_enum { foo2, bar2 }
| ^^^^^^^^^ | ^^^^^^^^^
error: variant is never constructed: `bar3` error: variant `bar3` is never constructed
--> $DIR/lint-dead-code-1.rs:67:5 --> $DIR/lint-dead-code-1.rs:67:5
| |
LL | enum used_enum {
| --------- variant in this enum
LL | foo3,
LL | bar3 LL | bar3
| ^^^^ | ^^^^
error: function is never used: `priv_fn` error: function `priv_fn` is never used
--> $DIR/lint-dead-code-1.rs:88:4 --> $DIR/lint-dead-code-1.rs:88:4
| |
LL | fn priv_fn() { LL | fn priv_fn() {
| ^^^^^^^ | ^^^^^^^
error: function is never used: `foo` error: function `foo` is never used
--> $DIR/lint-dead-code-1.rs:93:4 --> $DIR/lint-dead-code-1.rs:93:4
| |
LL | fn foo() { LL | fn foo() {
| ^^^ | ^^^
error: function is never used: `bar` error: function `bar` is never used
--> $DIR/lint-dead-code-1.rs:98:4 --> $DIR/lint-dead-code-1.rs:98:4
| |
LL | fn bar() { LL | fn bar() {
| ^^^ | ^^^
error: function is never used: `baz` error: function `baz` is never used
--> $DIR/lint-dead-code-1.rs:102:4 --> $DIR/lint-dead-code-1.rs:102:4
| |
LL | fn baz() -> impl Copy { LL | fn baz() -> impl Copy {
| ^^^ | ^^^
error: struct is never constructed: `Bar` error: struct `Bar` is never constructed
--> $DIR/lint-dead-code-1.rs:12:16 --> $DIR/lint-dead-code-1.rs:12:16
| |
LL | pub struct Bar; LL | pub struct Bar;

View file

@ -19,10 +19,10 @@ impl Bar for Foo {
fn live_fn() {} fn live_fn() {}
fn dead_fn() {} //~ ERROR: function is never used fn dead_fn() {} //~ ERROR: function `dead_fn` is never used
#[rustc_main] #[rustc_main]
fn dead_fn2() {} //~ ERROR: function is never used fn dead_fn2() {} //~ ERROR: function `dead_fn2` is never used
fn used_fn() {} fn used_fn() {}
@ -35,7 +35,7 @@ fn start(_: isize, _: *const *const u8) -> isize {
} }
// this is not main // this is not main
fn main() { //~ ERROR: function is never used fn main() { //~ ERROR: function `main` is never used
dead_fn(); dead_fn();
dead_fn2(); dead_fn2();
} }

View file

@ -1,4 +1,4 @@
error: function is never used: `dead_fn` error: function `dead_fn` is never used
--> $DIR/lint-dead-code-2.rs:22:4 --> $DIR/lint-dead-code-2.rs:22:4
| |
LL | fn dead_fn() {} LL | fn dead_fn() {}
@ -10,13 +10,13 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: function is never used: `dead_fn2` error: function `dead_fn2` is never used
--> $DIR/lint-dead-code-2.rs:25:4 --> $DIR/lint-dead-code-2.rs:25:4
| |
LL | fn dead_fn2() {} LL | fn dead_fn2() {}
| ^^^^^^^^ | ^^^^^^^^
error: function is never used: `main` error: function `main` is never used
--> $DIR/lint-dead-code-2.rs:38:4 --> $DIR/lint-dead-code-2.rs:38:4
| |
LL | fn main() { LL | fn main() {

View file

@ -11,14 +11,14 @@ extern "C" {
pub fn extern_foo(); pub fn extern_foo();
} }
struct Foo; //~ ERROR: struct is never constructed struct Foo; //~ ERROR: struct `Foo` is never constructed
impl Foo { impl Foo {
fn foo(&self) { //~ ERROR: associated function is never used fn foo(&self) { //~ ERROR: associated function `foo` is never used
bar() bar()
} }
} }
fn bar() { //~ ERROR: function is never used fn bar() { //~ ERROR: function `bar` is never used
fn baz() {} fn baz() {}
Foo.foo(); Foo.foo();
@ -57,9 +57,9 @@ mod blah {
} }
} }
enum c_void {} //~ ERROR: enum is never used enum c_void {} //~ ERROR: enum `c_void` is never used
extern "C" { extern "C" {
fn free(p: *const c_void); //~ ERROR: function is never used fn free(p: *const c_void); //~ ERROR: function `free` is never used
} }
// Check provided method // Check provided method

View file

@ -1,4 +1,4 @@
error: struct is never constructed: `Foo` error: struct `Foo` is never constructed
--> $DIR/lint-dead-code-3.rs:14:8 --> $DIR/lint-dead-code-3.rs:14:8
| |
LL | struct Foo; LL | struct Foo;
@ -10,25 +10,25 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: associated function is never used: `foo` error: associated function `foo` is never used
--> $DIR/lint-dead-code-3.rs:16:8 --> $DIR/lint-dead-code-3.rs:16:8
| |
LL | fn foo(&self) { LL | fn foo(&self) {
| ^^^ | ^^^
error: function is never used: `bar` error: function `bar` is never used
--> $DIR/lint-dead-code-3.rs:21:4 --> $DIR/lint-dead-code-3.rs:21:4
| |
LL | fn bar() { LL | fn bar() {
| ^^^ | ^^^
error: enum is never used: `c_void` error: enum `c_void` is never used
--> $DIR/lint-dead-code-3.rs:60:6 --> $DIR/lint-dead-code-3.rs:60:6
| |
LL | enum c_void {} LL | enum c_void {}
| ^^^^^^ | ^^^^^^
error: function is never used: `free` error: function `free` is never used
--> $DIR/lint-dead-code-3.rs:62:5 --> $DIR/lint-dead-code-3.rs:62:5
| |
LL | fn free(p: *const c_void); LL | fn free(p: *const c_void);

View file

@ -4,7 +4,7 @@
struct Foo { struct Foo {
x: usize, x: usize,
b: bool, //~ ERROR: field is never read b: bool, //~ ERROR: field `b` is never read
} }
fn field_read(f: Foo) -> usize { fn field_read(f: Foo) -> usize {
@ -12,8 +12,8 @@ fn field_read(f: Foo) -> usize {
} }
enum XYZ { enum XYZ {
X, //~ ERROR variant is never constructed X, //~ ERROR variants `X` and `Y` are never constructed
Y { //~ ERROR variant is never constructed Y {
a: String, a: String,
b: i32, b: i32,
c: i32, c: i32,
@ -21,7 +21,7 @@ enum XYZ {
Z Z
} }
enum ABC { //~ ERROR enum is never used enum ABC { //~ ERROR enum `ABC` is never used
A, A,
B { B {
a: String, a: String,
@ -33,13 +33,13 @@ enum ABC { //~ ERROR enum is never used
// ensure struct variants get warning for their fields // ensure struct variants get warning for their fields
enum IJK { enum IJK {
I, //~ ERROR variant is never constructed I, //~ ERROR variants `I` and `K` are never constructed
J { J {
a: String, a: String,
b: i32, //~ ERROR field is never read b: i32, //~ ERROR fields `b` and `c` are never read
c: i32, //~ ERROR field is never read c: i32,
}, },
K //~ ERROR variant is never constructed K
} }
@ -58,9 +58,9 @@ fn field_match_in_patterns(b: XYZ) -> String {
} }
struct Bar { struct Bar {
x: usize, //~ ERROR: field is never read x: usize, //~ ERROR: fields `x` and `c` are never read
b: bool, b: bool,
c: bool, //~ ERROR: field is never read c: bool,
_guard: () _guard: ()
} }

View file

@ -1,6 +1,9 @@
error: field is never read: `b` error: field `b` is never read
--> $DIR/lint-dead-code-4.rs:7:5 --> $DIR/lint-dead-code-4.rs:7:5
| |
LL | struct Foo {
| --- field in this struct
LL | x: usize,
LL | b: bool, LL | b: bool,
| ^^^^^^^ | ^^^^^^^
| |
@ -10,15 +13,13 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: variant is never constructed: `X` error: variants `X` and `Y` are never constructed
--> $DIR/lint-dead-code-4.rs:15:5 --> $DIR/lint-dead-code-4.rs:15:5
| |
LL | X, LL | enum XYZ {
| ^ | --- variants in this enum
LL | X,
error: variant is never constructed: `Y` | ^
--> $DIR/lint-dead-code-4.rs:16:5
|
LL | / Y { LL | / Y {
LL | | a: String, LL | | a: String,
LL | | b: i32, LL | | b: i32,
@ -26,47 +27,44 @@ LL | | c: i32,
LL | | }, LL | | },
| |_____^ | |_____^
error: enum is never used: `ABC` error: enum `ABC` is never used
--> $DIR/lint-dead-code-4.rs:24:6 --> $DIR/lint-dead-code-4.rs:24:6
| |
LL | enum ABC { LL | enum ABC {
| ^^^ | ^^^
error: variant is never constructed: `I` error: fields `b` and `c` are never read
--> $DIR/lint-dead-code-4.rs:36:5
|
LL | I,
| ^
error: field is never read: `b`
--> $DIR/lint-dead-code-4.rs:39:9 --> $DIR/lint-dead-code-4.rs:39:9
| |
LL | enum IJK {
| --- fields in this enum
...
LL | b: i32, LL | b: i32,
| ^^^^^^ | ^^^^^^
error: field is never read: `c`
--> $DIR/lint-dead-code-4.rs:40:9
|
LL | c: i32, LL | c: i32,
| ^^^^^^ | ^^^^^^
error: variant is never constructed: `K` error: variants `I` and `K` are never constructed
--> $DIR/lint-dead-code-4.rs:42:5 --> $DIR/lint-dead-code-4.rs:36:5
| |
LL | enum IJK {
| --- variants in this enum
LL | I,
| ^
...
LL | K LL | K
| ^ | ^
error: field is never read: `x` error: fields `x` and `c` are never read
--> $DIR/lint-dead-code-4.rs:61:5 --> $DIR/lint-dead-code-4.rs:61:5
| |
LL | struct Bar {
| --- fields in this struct
LL | x: usize, LL | x: usize,
| ^^^^^^^^ | ^^^^^^^^
LL | b: bool,
error: field is never read: `c`
--> $DIR/lint-dead-code-4.rs:63:5
|
LL | c: bool, LL | c: bool,
| ^^^^^^^ | ^^^^^^^
error: aborting due to 10 previous errors error: aborting due to 6 previous errors

View file

@ -3,15 +3,15 @@
enum Enum1 { enum Enum1 {
Variant1(isize), Variant1(isize),
Variant2 //~ ERROR: variant is never constructed Variant2 //~ ERROR: variant `Variant2` is never constructed
} }
enum Enum2 { enum Enum2 {
Variant3(bool), Variant3(bool),
#[allow(dead_code)] #[allow(dead_code)]
Variant4(isize), Variant4(isize),
Variant5 { _x: isize }, //~ ERROR: variant is never constructed: `Variant5` Variant5 { _x: isize }, //~ ERROR: variants `Variant5` and `Variant6` are never constructed
Variant6(isize), //~ ERROR: variant is never constructed: `Variant6` Variant6(isize),
_Variant7, _Variant7,
Variant8 { _field: bool }, Variant8 { _field: bool },
Variant9, Variant9,
@ -32,7 +32,7 @@ impl Enum2 {
} }
} }
enum Enum3 { //~ ERROR: enum is never used enum Enum3 { //~ ERROR: enum `Enum3` is never used
Variant8, Variant8,
Variant9 Variant9
} }

View file

@ -1,6 +1,9 @@
error: variant is never constructed: `Variant2` error: variant `Variant2` is never constructed
--> $DIR/lint-dead-code-5.rs:6:5 --> $DIR/lint-dead-code-5.rs:6:5
| |
LL | enum Enum1 {
| ----- variant in this enum
LL | Variant1(isize),
LL | Variant2 LL | Variant2
| ^^^^^^^^ | ^^^^^^^^
| |
@ -10,23 +13,22 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: variant is never constructed: `Variant5` error: variants `Variant5` and `Variant6` are never constructed
--> $DIR/lint-dead-code-5.rs:13:5 --> $DIR/lint-dead-code-5.rs:13:5
| |
LL | enum Enum2 {
| ----- variants in this enum
...
LL | Variant5 { _x: isize }, LL | Variant5 { _x: isize },
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
error: variant is never constructed: `Variant6`
--> $DIR/lint-dead-code-5.rs:14:5
|
LL | Variant6(isize), LL | Variant6(isize),
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: enum is never used: `Enum3` error: enum `Enum3` is never used
--> $DIR/lint-dead-code-5.rs:35:6 --> $DIR/lint-dead-code-5.rs:35:6
| |
LL | enum Enum3 { LL | enum Enum3 {
| ^^^^^ | ^^^^^
error: aborting due to 4 previous errors error: aborting due to 3 previous errors

View file

@ -1,16 +1,16 @@
#![deny(dead_code)] #![deny(dead_code)]
struct UnusedStruct; //~ ERROR struct is never constructed: `UnusedStruct` struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
impl UnusedStruct { impl UnusedStruct {
fn unused_impl_fn_1() { //~ ERROR associated function is never used: `unused_impl_fn_1` fn unused_impl_fn_1() { //~ ERROR associated function `unused_impl_fn_1` is never used
println!("blah"); println!("blah");
} }
fn unused_impl_fn_2(var: i32) { //~ ERROR associated function is never used: `unused_impl_fn_2` fn unused_impl_fn_2(var: i32) { //~ ERROR associated function `unused_impl_fn_2` is never used
println!("foo {}", var); println!("foo {}", var);
} }
fn unused_impl_fn_3( //~ ERROR associated function is never used: `unused_impl_fn_3` fn unused_impl_fn_3( //~ ERROR associated function `unused_impl_fn_3` is never used
var: i32, var: i32,
) { ) {
println!("bar {}", var); println!("bar {}", var);

View file

@ -1,4 +1,4 @@
error: struct is never constructed: `UnusedStruct` error: struct `UnusedStruct` is never constructed
--> $DIR/lint-dead-code-6.rs:3:8 --> $DIR/lint-dead-code-6.rs:3:8
| |
LL | struct UnusedStruct; LL | struct UnusedStruct;
@ -10,19 +10,19 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: associated function is never used: `unused_impl_fn_1` error: associated function `unused_impl_fn_1` is never used
--> $DIR/lint-dead-code-6.rs:5:8 --> $DIR/lint-dead-code-6.rs:5:8
| |
LL | fn unused_impl_fn_1() { LL | fn unused_impl_fn_1() {
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: associated function is never used: `unused_impl_fn_2` error: associated function `unused_impl_fn_2` is never used
--> $DIR/lint-dead-code-6.rs:9:8 --> $DIR/lint-dead-code-6.rs:9:8
| |
LL | fn unused_impl_fn_2(var: i32) { LL | fn unused_impl_fn_2(var: i32) {
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: associated function is never used: `unused_impl_fn_3` error: associated function `unused_impl_fn_3` is never used
--> $DIR/lint-dead-code-6.rs:13:8 --> $DIR/lint-dead-code-6.rs:13:8
| |
LL | fn unused_impl_fn_3( LL | fn unused_impl_fn_3(

View file

@ -0,0 +1,29 @@
#![warn(dead_code)]
struct Bar {
#[allow(dead_code)]
a: usize,
#[forbid(dead_code)]
b: usize, //~ ERROR field `b` is never read
#[deny(dead_code)]
c: usize, //~ ERROR fields `c` and `e` are never read
d: usize, //~ WARN fields `d`, `f` and `g` are never read
#[deny(dead_code)]
e: usize,
f: usize,
g: usize,
_h: usize,
}
fn main() {
Bar {
a: 1,
b: 1,
c: 1,
d: 1,
e: 1,
f: 1,
g: 1,
_h: 1,
};
}

View file

@ -0,0 +1,55 @@
warning: fields `d`, `f` and `g` are never read
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:10:5
|
LL | struct Bar {
| --- fields in this struct
...
LL | d: usize,
| ^^^^^^^^
...
LL | f: usize,
| ^^^^^^^^
LL | g: usize,
| ^^^^^^^^
|
note: the lint level is defined here
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:1:9
|
LL | #![warn(dead_code)]
| ^^^^^^^^^
error: fields `c` and `e` are never read
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:9:5
|
LL | struct Bar {
| --- fields in this struct
...
LL | c: usize,
| ^^^^^^^^
...
LL | e: usize,
| ^^^^^^^^
|
note: the lint level is defined here
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:8:12
|
LL | #[deny(dead_code)]
| ^^^^^^^^^
error: field `b` is never read
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:7:5
|
LL | struct Bar {
| --- field in this struct
...
LL | b: usize,
| ^^^^^^^^
|
note: the lint level is defined here
--> $DIR/multiple-dead-codes-in-the-same-struct.rs:6:14
|
LL | #[forbid(dead_code)]
| ^^^^^^^^^
error: aborting due to 2 previous errors; 1 warning emitted

View file

@ -1,14 +1,14 @@
#![deny(dead_code)] #![deny(dead_code)]
fn unused() { //~ error: function is never used: fn unused() { //~ error: function `unused` is never used
println!("blah"); println!("blah");
} }
fn unused2(var: i32) { //~ error: function is never used: fn unused2(var: i32) { //~ error: function `unused2` is never used
println!("foo {}", var); println!("foo {}", var);
} }
fn unused3( //~ error: function is never used: fn unused3( //~ error: function `unused3` is never used
var: i32, var: i32,
) { ) {
println!("bar {}", var); println!("bar {}", var);

View file

@ -1,4 +1,4 @@
error: function is never used: `unused` error: function `unused` is never used
--> $DIR/newline-span.rs:3:4 --> $DIR/newline-span.rs:3:4
| |
LL | fn unused() { LL | fn unused() {
@ -10,13 +10,13 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: function is never used: `unused2` error: function `unused2` is never used
--> $DIR/newline-span.rs:7:4 --> $DIR/newline-span.rs:7:4
| |
LL | fn unused2(var: i32) { LL | fn unused2(var: i32) {
| ^^^^^^^ | ^^^^^^^
error: function is never used: `unused3` error: function `unused3` is never used
--> $DIR/newline-span.rs:11:4 --> $DIR/newline-span.rs:11:4
| |
LL | fn unused3( LL | fn unused3(

View file

@ -1,7 +1,7 @@
#![deny(dead_code)] #![deny(dead_code)]
type Used = u8; type Used = u8;
type Unused = u8; //~ ERROR type alias is never used type Unused = u8; //~ ERROR type alias `Unused` is never used
fn id(x: Used) -> Used { x } fn id(x: Used) -> Used { x }

View file

@ -1,4 +1,4 @@
error: type alias is never used: `Unused` error: type alias `Unused` is never used
--> $DIR/type-alias.rs:4:1 --> $DIR/type-alias.rs:4:1
| |
LL | type Unused = u8; LL | type Unused = u8;

View file

@ -1,9 +1,10 @@
#![deny(unused)] #![deny(unused)]
struct F; //~ ERROR struct is never constructed struct F; //~ ERROR struct `F` is never constructed
struct B; //~ ERROR struct is never constructed struct B; //~ ERROR struct `B` is never constructed
enum E { //~ ERROR enum is never used enum E {
//~^ ERROR enum `E` is never used
Foo(F), Foo(F),
Bar(B), Bar(B),
} }

View file

@ -1,4 +1,4 @@
error: struct is never constructed: `F` error: struct `F` is never constructed
--> $DIR/unused-enum.rs:3:8 --> $DIR/unused-enum.rs:3:8
| |
LL | struct F; LL | struct F;
@ -11,13 +11,13 @@ LL | #![deny(unused)]
| ^^^^^^ | ^^^^^^
= note: `#[deny(dead_code)]` implied by `#[deny(unused)]` = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
error: struct is never constructed: `B` error: struct `B` is never constructed
--> $DIR/unused-enum.rs:4:8 --> $DIR/unused-enum.rs:4:8
| |
LL | struct B; LL | struct B;
| ^ | ^
error: enum is never used: `E` error: enum `E` is never used
--> $DIR/unused-enum.rs:6:6 --> $DIR/unused-enum.rs:6:6
| |
LL | enum E { LL | enum E {

View file

@ -5,7 +5,7 @@ struct B;
enum E { enum E {
Foo(F), Foo(F),
Bar(B), //~ ERROR variant is never constructed Bar(B), //~ ERROR variant `Bar` is never constructed
} }
fn main() { fn main() {

View file

@ -1,6 +1,9 @@
error: variant is never constructed: `Bar` error: variant `Bar` is never constructed
--> $DIR/unused-struct-variant.rs:8:5 --> $DIR/unused-struct-variant.rs:8:5
| |
LL | enum E {
| - variant in this enum
LL | Foo(F),
LL | Bar(B), LL | Bar(B),
| ^^^^^^ | ^^^^^^
| |

View file

@ -2,7 +2,7 @@
#[derive(Clone)] #[derive(Clone)]
enum Enum { enum Enum {
Variant1, //~ ERROR: variant is never constructed Variant1, //~ ERROR: variant `Variant1` is never constructed
Variant2, Variant2,
} }

View file

@ -1,6 +1,8 @@
error: variant is never constructed: `Variant1` error: variant `Variant1` is never constructed
--> $DIR/unused-variant.rs:5:5 --> $DIR/unused-variant.rs:5:5
| |
LL | enum Enum {
| ---- variant in this enum
LL | Variant1, LL | Variant1,
| ^^^^^^^^ | ^^^^^^^^
| |

View file

@ -4,7 +4,7 @@
#[macro_use] #[macro_use]
extern crate core; extern crate core;
fn foo() { //~ ERROR function is never used fn foo() { //~ ERROR function `foo` is never used
// none of these should have any dead_code exposed to the user // none of these should have any dead_code exposed to the user
panic!(); panic!();

View file

@ -1,4 +1,4 @@
error: function is never used: `foo` error: function `foo` is never used
--> $DIR/with-core-crate.rs:7:4 --> $DIR/with-core-crate.rs:7:4
| |
LL | fn foo() { LL | fn foo() {

View file

@ -6,6 +6,6 @@
#![allow(warnings)] #![allow(warnings)]
fn dead_function() {} fn dead_function() {}
//~^ WARN function is never used //~^ WARN function `dead_function` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
warning: function is never used: `dead_function` warning: function `dead_function` is never used
--> $DIR/allow-warnings.rs:8:4 --> $DIR/allow-warnings.rs:8:4
| |
LL | fn dead_function() {} LL | fn dead_function() {}

View file

@ -6,6 +6,6 @@
#![allow(dead_code)] #![allow(dead_code)]
fn dead_function() {} fn dead_function() {}
//~^ WARN function is never used //~^ WARN function `dead_function` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
warning: function is never used: `dead_function` warning: function `dead_function` is never used
--> $DIR/allowed-warn-by-default-lint.rs:8:4 --> $DIR/allowed-warn-by-default-lint.rs:8:4
| |
LL | fn dead_function() {} LL | fn dead_function() {}

View file

@ -7,12 +7,12 @@ mod one {
#![allow(dead_code)] #![allow(dead_code)]
fn dead_function() {} fn dead_function() {}
//~^ WARN function is never used //~^ WARN function `dead_function` is never used
} }
mod two { mod two {
fn dead_function() {} fn dead_function() {}
//~^ WARN function is never used //~^ WARN function `dead_function` is never used
} }
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
warning: function is never used: `dead_function` warning: function `dead_function` is never used
--> $DIR/warn-by-default-lint-two-modules.rs:9:8 --> $DIR/warn-by-default-lint-two-modules.rs:9:8
| |
LL | fn dead_function() {} LL | fn dead_function() {}
@ -6,7 +6,7 @@ LL | fn dead_function() {}
| |
= note: requested on the command line with `--force-warn dead-code` = note: requested on the command line with `--force-warn dead-code`
warning: function is never used: `dead_function` warning: function `dead_function` is never used
--> $DIR/warn-by-default-lint-two-modules.rs:14:8 --> $DIR/warn-by-default-lint-two-modules.rs:14:8
| |
LL | fn dead_function() {} LL | fn dead_function() {}

View file

@ -3,6 +3,6 @@
const foo: isize = 3; const foo: isize = 3;
//~^ ERROR: should have an upper case name //~^ ERROR: should have an upper case name
//~^^ ERROR: constant is never used //~^^ ERROR: constant `foo` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: constant is never used: `foo` error: constant `foo` is never used
--> $DIR/issue-17718-const-naming.rs:4:1 --> $DIR/issue-17718-const-naming.rs:4:1
| |
LL | const foo: isize = 3; LL | const foo: isize = 3;

View file

@ -4,7 +4,7 @@
macro_rules! m { macro_rules! m {
($a:tt $b:tt) => { ($a:tt $b:tt) => {
$b $a; //~ WARN struct is never constructed $b $a; //~ WARN struct `S` is never constructed
} }
} }

View file

@ -1,4 +1,4 @@
warning: struct is never constructed: `S` warning: struct `S` is never constructed
--> $DIR/macro-span-replacement.rs:7:14 --> $DIR/macro-span-replacement.rs:7:14
| |
LL | $b $a; LL | $b $a;

View file

@ -2,26 +2,26 @@
#![warn(unused)] #![warn(unused)]
enum Enum { //~ WARN enum is never used enum Enum { //~ WARN enum `Enum` is never used
A, A,
B, B,
C, C,
D, D,
} }
struct Struct { //~ WARN struct is never constructed struct Struct { //~ WARN struct `Struct` is never constructed
a: usize, a: usize,
b: usize, b: usize,
c: usize, c: usize,
d: usize, d: usize,
} }
fn func() -> usize { //~ WARN function is never used fn func() -> usize { //~ WARN function `func` is never used
3 3
} }
fn fn
func_complete_span() //~ WARN function is never used func_complete_span() //~ WARN function `func_complete_span` is never used
-> usize -> usize
{ {
3 3

View file

@ -1,4 +1,4 @@
warning: enum is never used: `Enum` warning: enum `Enum` is never used
--> $DIR/unused-warning-point-at-identifier.rs:5:6 --> $DIR/unused-warning-point-at-identifier.rs:5:6
| |
LL | enum Enum { LL | enum Enum {
@ -11,19 +11,19 @@ LL | #![warn(unused)]
| ^^^^^^ | ^^^^^^
= note: `#[warn(dead_code)]` implied by `#[warn(unused)]` = note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
warning: struct is never constructed: `Struct` warning: struct `Struct` is never constructed
--> $DIR/unused-warning-point-at-identifier.rs:12:8 --> $DIR/unused-warning-point-at-identifier.rs:12:8
| |
LL | struct Struct { LL | struct Struct {
| ^^^^^^ | ^^^^^^
warning: function is never used: `func` warning: function `func` is never used
--> $DIR/unused-warning-point-at-identifier.rs:19:4 --> $DIR/unused-warning-point-at-identifier.rs:19:4
| |
LL | fn func() -> usize { LL | fn func() -> usize {
| ^^^^ | ^^^^
warning: function is never used: `func_complete_span` warning: function `func_complete_span` is never used
--> $DIR/unused-warning-point-at-identifier.rs:24:1 --> $DIR/unused-warning-point-at-identifier.rs:24:1
| |
LL | func_complete_span() LL | func_complete_span()

View file

@ -2,6 +2,6 @@
#![deny(dead_code)] #![deny(dead_code)]
fn dead() {} //~ error: function is never used: `dead` fn dead() {} //~ error: function `dead` is never used
fn main() {} fn main() {}

View file

@ -1,4 +1,4 @@
error: function is never used: `dead` error: function `dead` is never used
--> $DIR/test-warns-dead-code.rs:5:4 --> $DIR/test-warns-dead-code.rs:5:4
| |
LL | fn dead() {} LL | fn dead() {}

View file

@ -1,6 +1,9 @@
error: field is never read: `c` error: field `c` is never read
--> $DIR/union-fields-1.rs:9:5 --> $DIR/union-fields-1.rs:9:5
| |
LL | union U1 {
| -- field in this union
...
LL | c: u8, LL | c: u8,
| ^^^^^ | ^^^^^
| |
@ -10,21 +13,28 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: field is never read: `a` error: field `a` is never read
--> $DIR/union-fields-1.rs:12:5 --> $DIR/union-fields-1.rs:12:5
| |
LL | union U2 {
| -- field in this union
LL | a: u8, LL | a: u8,
| ^^^^^ | ^^^^^
error: field is never read: `a` error: field `a` is never read
--> $DIR/union-fields-1.rs:16:20 --> $DIR/union-fields-1.rs:16:20
| |
LL | union NoDropLike { a: u8 } LL | union NoDropLike { a: u8 }
| ^^^^^ | ---------- ^^^^^
| |
| field in this union
error: field is never read: `c` error: field `c` is never read
--> $DIR/union-fields-1.rs:21:5 --> $DIR/union-fields-1.rs:21:5
| |
LL | union U {
| - field in this union
...
LL | c: u8, LL | c: u8,
| ^^^^^ | ^^^^^

View file

@ -6,19 +6,19 @@
union U1 { union U1 {
a: u8, // should not be reported a: u8, // should not be reported
b: u8, // should not be reported b: u8, // should not be reported
c: u8, //~ ERROR field is never read c: u8, //~ ERROR field `c` is never read
} }
union U2 { union U2 {
a: u8, //~ ERROR field is never read a: u8, //~ ERROR field `a` is never read
b: u8, // should not be reported b: u8, // should not be reported
c: u8, // should not be reported c: u8, // should not be reported
} }
union NoDropLike { a: u8 } //~ ERROR field is never read union NoDropLike { a: u8 } //~ ERROR field `a` is never read
union U { union U {
a: u8, // should not be reported a: u8, // should not be reported
b: u8, // should not be reported b: u8, // should not be reported
c: u8, //~ ERROR field is never read c: u8, //~ ERROR field `c` is never read
} }
type A = U; type A = U;

View file

@ -1,6 +1,9 @@
error: field is never read: `c` error: field `c` is never read
--> $DIR/union-fields-1.rs:9:5 --> $DIR/union-fields-1.rs:9:5
| |
LL | union U1 {
| -- field in this union
...
LL | c: u8, LL | c: u8,
| ^^^^^ | ^^^^^
| |
@ -10,21 +13,28 @@ note: the lint level is defined here
LL | #![deny(dead_code)] LL | #![deny(dead_code)]
| ^^^^^^^^^ | ^^^^^^^^^
error: field is never read: `a` error: field `a` is never read
--> $DIR/union-fields-1.rs:12:5 --> $DIR/union-fields-1.rs:12:5
| |
LL | union U2 {
| -- field in this union
LL | a: u8, LL | a: u8,
| ^^^^^ | ^^^^^
error: field is never read: `a` error: field `a` is never read
--> $DIR/union-fields-1.rs:16:20 --> $DIR/union-fields-1.rs:16:20
| |
LL | union NoDropLike { a: u8 } LL | union NoDropLike { a: u8 }
| ^^^^^ | ---------- ^^^^^
| |
| field in this union
error: field is never read: `c` error: field `c` is never read
--> $DIR/union-fields-1.rs:21:5 --> $DIR/union-fields-1.rs:21:5
| |
LL | union U {
| - field in this union
...
LL | c: u8, LL | c: u8,
| ^^^^^ | ^^^^^

View file

@ -1,6 +1,9 @@
error: field is never read: `b` error: field `b` is never read
--> $DIR/union-lint-dead-code.rs:8:5 --> $DIR/union-lint-dead-code.rs:8:5
| |
LL | union Foo {
| --- field in this union
LL | x: usize,
LL | b: bool, LL | b: bool,
| ^^^^^^^ | ^^^^^^^
| |

View file

@ -5,7 +5,7 @@
union Foo { union Foo {
x: usize, x: usize,
b: bool, //~ ERROR: field is never read b: bool, //~ ERROR: field `b` is never read
_unused: u16, _unused: u16,
} }

View file

@ -1,6 +1,9 @@
error: field is never read: `b` error: field `b` is never read
--> $DIR/union-lint-dead-code.rs:8:5 --> $DIR/union-lint-dead-code.rs:8:5
| |
LL | union Foo {
| --- field in this union
LL | x: usize,
LL | b: bool, LL | b: bool,
| ^^^^^^^ | ^^^^^^^
| |

@ -1 +1 @@
Subproject commit 8d42b0e8794ce3787c9f7d6d88b02ae80ebe8d19 Subproject commit 03a849043e25104e8b7ad0d4a96c525787b69379

@ -1 +1 @@
Subproject commit 7241c6cc45badc0e30cefd6c123a539f82c50cd3 Subproject commit 27f4044df03d15c7c38a483c3e4635cf4f51807d