1
Fork 0

Rollup merge of #46103 - zackmdavis:dead_code_lint_should_say_never_constructed_for_variants, r=arielb1

dead code lint to say "never constructed" for variants

As reported in #19140, #44083, and #44565, some users were confused when
the dead-code lint reported an enum variant to be "unused" when it was
matched on (but not constructed). This wording change makes it clearer
that the lint is in fact checking for construction.

We continue to say "used" for all other items (it's tempting to say
"called" for functions and methods, but this turns out not to be
correct: functions can be passed as arguments and the dead-code lint
isn't special-casing that or anything).

Resolves #19140.

r? @pnkfelix
This commit is contained in:
kennytm 2017-11-22 01:13:00 +08:00 committed by GitHub
commit 7eb2e79ea8
5 changed files with 23 additions and 18 deletions

View file

@ -531,13 +531,15 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
id: ast::NodeId, id: ast::NodeId,
span: syntax_pos::Span, span: syntax_pos::Span,
name: ast::Name, name: ast::Name,
node_type: &str) { node_type: &str,
participle: &str) {
if !name.as_str().starts_with("_") { if !name.as_str().starts_with("_") {
self.tcx self.tcx
.lint_node(lint::builtin::DEAD_CODE, .lint_node(lint::builtin::DEAD_CODE,
id, id,
span, span,
&format!("{} is never used: `{}`", node_type, name)); &format!("{} is never {}: `{}`",
node_type, participle, name));
} }
} }
} }
@ -570,7 +572,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
item.id, item.id,
span, span,
item.name, item.name,
item.node.descriptive_variant() item.node.descriptive_variant(),
"used",
); );
} else { } else {
// Only continue if we didn't warn // Only continue if we didn't warn
@ -583,7 +586,8 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
g: &'tcx hir::Generics, g: &'tcx hir::Generics,
id: ast::NodeId) { id: ast::NodeId) {
if self.should_warn_about_variant(&variant.node) { if self.should_warn_about_variant(&variant.node) {
self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name, "variant"); self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name,
"variant", "constructed");
} else { } else {
intravisit::walk_variant(self, variant, g, id); intravisit::walk_variant(self, variant, g, id);
} }
@ -591,15 +595,15 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) { fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) {
if self.should_warn_about_foreign_item(fi) { if self.should_warn_about_foreign_item(fi) {
self.warn_dead_code(fi.id, fi.span, fi.name, fi.node.descriptive_variant()); self.warn_dead_code(fi.id, fi.span, fi.name,
fi.node.descriptive_variant(), "used");
} }
intravisit::walk_foreign_item(self, fi); intravisit::walk_foreign_item(self, fi);
} }
fn visit_struct_field(&mut self, field: &'tcx hir::StructField) { fn visit_struct_field(&mut self, field: &'tcx hir::StructField) {
if self.should_warn_about_field(&field) { if self.should_warn_about_field(&field) {
self.warn_dead_code(field.id, field.span, self.warn_dead_code(field.id, field.span, field.name, "field", "used");
field.name, "field");
} }
intravisit::walk_struct_field(self, field); intravisit::walk_struct_field(self, field);
} }
@ -611,14 +615,15 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
self.warn_dead_code(impl_item.id, self.warn_dead_code(impl_item.id,
impl_item.span, impl_item.span,
impl_item.name, impl_item.name,
"associated const"); "associated const",
"used");
} }
self.visit_nested_body(body_id) self.visit_nested_body(body_id)
} }
hir::ImplItemKind::Method(_, body_id) => { hir::ImplItemKind::Method(_, body_id) => {
if !self.symbol_is_live(impl_item.id, None) { if !self.symbol_is_live(impl_item.id, None) {
let span = self.tcx.sess.codemap().def_span(impl_item.span); let span = self.tcx.sess.codemap().def_span(impl_item.span);
self.warn_dead_code(impl_item.id, span, impl_item.name, "method"); self.warn_dead_code(impl_item.id, span, impl_item.name, "method", "used");
} }
self.visit_nested_body(body_id) self.visit_nested_body(body_id)
} }

View file

@ -74,7 +74,7 @@ pub enum pub_enum3 {
enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used
enum used_enum { enum used_enum {
foo3, foo3,
bar3 //~ ERROR variant is never used bar3 //~ ERROR variant is never constructed
} }
fn f<T>() {} fn f<T>() {}

View file

@ -22,8 +22,8 @@ fn field_read(f: Foo) -> usize {
} }
enum XYZ { enum XYZ {
X, //~ ERROR variant is never used X, //~ ERROR variant is never constructed
Y { //~ ERROR variant is never used Y { //~ ERROR variant is never constructed
a: String, a: String,
b: i32, b: i32,
c: i32, c: i32,
@ -43,13 +43,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 used I, //~ ERROR variant is never constructed
J { J {
a: String, a: String,
b: i32, //~ ERROR field is never used b: i32, //~ ERROR field is never used
c: i32, //~ ERROR field is never used c: i32, //~ ERROR field is never used
}, },
K //~ ERROR variant is never used K //~ ERROR variant is never constructed
} }

View file

@ -13,15 +13,15 @@
enum Enum1 { enum Enum1 {
Variant1(isize), Variant1(isize),
Variant2 //~ ERROR: variant is never used Variant2 //~ ERROR: variant 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 used: `Variant5` Variant5 { _x: isize }, //~ ERROR: variant is never constructed: `Variant5`
Variant6(isize), //~ ERROR: variant is never used: `Variant6` Variant6(isize), //~ ERROR: variant is never constructed: `Variant6`
_Variant7, _Variant7,
} }

View file

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