Use ident instead of def_span in dead-code pass

According to @estebank, def_span scans forward on the line until it finds a {,
and if it can't find one, fallse back to the span for the whole item.  This
was apparently written before the identifier span was explicitly tracked on
each node.

This means that if an unused function signature spans multiple lines, the
entire function (potentially hundreds of lines) gets flagged as dead code.
This could, for example, cause IDEs to add error squiggly's to the whole
function.

By using the span from the ident instead, we narrow the scope of this in
most cases.  In a wider sense, it's probably safe to use ident.span
instead of def_span in most locations throughout the whole code base,
but since this is my first contribution, I kept it small.

Some interesting points that came up while I was working on this:
 - I reorganized the tests a bit to bring some of the dead code ones all
   into the same location
 - A few tests were for things unrelated to dead code (like the
   path-lookahead for parens), so I added #![allow(dead_code)] and
   cleaned up the stderr file to reduce noise in the future
 - The same fix doesn't apply to const and static declarations.  I tried
   adding these cases to the match expression, but that created a much
   wider change to tests and error messages, so I left it off until I
   could get some code review to validate the approach.
This commit is contained in:
Pi Lanningham 2019-10-25 14:46:07 -04:00
parent e063ddb12e
commit 7985510e37
21 changed files with 114 additions and 98 deletions

View File

@ -578,7 +578,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) |
hir::ItemKind::Trait(..) |
hir::ItemKind::Impl(..) => self.tcx.sess.source_map().def_span(item.span),
hir::ItemKind::Impl(..) => item.ident.span,
_ => item.span,
};
let participle = match item.kind {

View File

@ -7,10 +7,10 @@ LL | #![plugin(lint_plugin_test)]
= note: `#[warn(deprecated)]` on by default
warning: function is never used: `lintme`
--> $DIR/lint-plugin-cmdline-allow.rs:10:1
--> $DIR/lint-plugin-cmdline-allow.rs:10:4
|
LL | fn lintme() { }
| ^^^^^^^^^^^
| ^^^^^^
|
note: lint level defined here
--> $DIR/lint-plugin-cmdline-allow.rs:7:9

View File

@ -19,10 +19,10 @@ LL | fn lintme() {}
= note: `#[warn(clippy::test_lint)]` on by default
warning: function is never used: `lintme`
--> $DIR/lint-tool-cmdline-allow.rs:10:1
--> $DIR/lint-tool-cmdline-allow.rs:10:4
|
LL | fn lintme() {}
| ^^^^^^^^^^^
| ^^^^^^
|
note: lint level defined here
--> $DIR/lint-tool-cmdline-allow.rs:7:9

View File

@ -1,8 +1,8 @@
error: function is never used: `foo`
--> $DIR/basic.rs:4:1
--> $DIR/basic.rs:4:4
|
LL | fn foo() {
| ^^^^^^^^
| ^^^
|
note: lint level defined here
--> $DIR/basic.rs:1:9

View File

@ -1,8 +1,8 @@
error: enum is never used: `E`
--> $DIR/empty-unused-enum.rs:3:1
--> $DIR/empty-unused-enum.rs:3:6
|
LL | enum E {}
| ^^^^^^
| ^
|
note: lint level defined here
--> $DIR/empty-unused-enum.rs:1:9

View File

@ -1,8 +1,8 @@
error: struct is never constructed: `Bar`
--> $DIR/lint-dead-code-1.rs:12:5
--> $DIR/lint-dead-code-1.rs:12:16
|
LL | pub struct Bar;
| ^^^^^^^^^^^^^^^
| ^^^
|
note: lint level defined here
--> $DIR/lint-dead-code-1.rs:5:9
@ -23,16 +23,16 @@ LL | const priv_const: isize = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: struct is never constructed: `PrivStruct`
--> $DIR/lint-dead-code-1.rs:35:1
--> $DIR/lint-dead-code-1.rs:35:8
|
LL | struct PrivStruct;
| ^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^
error: enum is never used: `priv_enum`
--> $DIR/lint-dead-code-1.rs:64:1
--> $DIR/lint-dead-code-1.rs:64:6
|
LL | enum priv_enum { foo2, bar2 }
| ^^^^^^^^^^^^^^
| ^^^^^^^^^
error: variant is never constructed: `bar3`
--> $DIR/lint-dead-code-1.rs:67:5
@ -41,28 +41,28 @@ LL | bar3
| ^^^^
error: function is never used: `priv_fn`
--> $DIR/lint-dead-code-1.rs:88:1
--> $DIR/lint-dead-code-1.rs:88:4
|
LL | fn priv_fn() {
| ^^^^^^^^^^^^
| ^^^^^^^
error: function is never used: `foo`
--> $DIR/lint-dead-code-1.rs:93:1
--> $DIR/lint-dead-code-1.rs:93:4
|
LL | fn foo() {
| ^^^^^^^^
| ^^^
error: function is never used: `bar`
--> $DIR/lint-dead-code-1.rs:98:1
--> $DIR/lint-dead-code-1.rs:98:4
|
LL | fn bar() {
| ^^^^^^^^
| ^^^
error: function is never used: `baz`
--> $DIR/lint-dead-code-1.rs:102:1
--> $DIR/lint-dead-code-1.rs:102:4
|
LL | fn baz() -> impl Copy {
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^
error: aborting due to 10 previous errors

View File

@ -1,8 +1,8 @@
error: function is never used: `dead_fn`
--> $DIR/lint-dead-code-2.rs:22:1
--> $DIR/lint-dead-code-2.rs:22:4
|
LL | fn dead_fn() {}
| ^^^^^^^^^^^^
| ^^^^^^^
|
note: lint level defined here
--> $DIR/lint-dead-code-2.rs:2:9
@ -11,16 +11,16 @@ LL | #![deny(dead_code)]
| ^^^^^^^^^
error: function is never used: `dead_fn2`
--> $DIR/lint-dead-code-2.rs:25:1
--> $DIR/lint-dead-code-2.rs:25:4
|
LL | fn dead_fn2() {}
| ^^^^^^^^^^^^^
| ^^^^^^^^
error: function is never used: `main`
--> $DIR/lint-dead-code-2.rs:38:1
--> $DIR/lint-dead-code-2.rs:38:4
|
LL | fn main() {
| ^^^^^^^^^
| ^^^^
error: aborting due to 3 previous errors

View File

@ -1,8 +1,8 @@
error: struct is never constructed: `Foo`
--> $DIR/lint-dead-code-3.rs:13:1
--> $DIR/lint-dead-code-3.rs:13:8
|
LL | struct Foo;
| ^^^^^^^^^^^
| ^^^
|
note: lint level defined here
--> $DIR/lint-dead-code-3.rs:3:9
@ -17,16 +17,16 @@ LL | fn foo(&self) {
| ^^^^^^^^^^^^^
error: function is never used: `bar`
--> $DIR/lint-dead-code-3.rs:20:1
--> $DIR/lint-dead-code-3.rs:20:4
|
LL | fn bar() {
| ^^^^^^^^
| ^^^
error: enum is never used: `c_void`
--> $DIR/lint-dead-code-3.rs:59:1
--> $DIR/lint-dead-code-3.rs:59:6
|
LL | enum c_void {}
| ^^^^^^^^^^^
| ^^^^^^
error: foreign function is never used: `free`
--> $DIR/lint-dead-code-3.rs:61:5

View File

@ -27,10 +27,10 @@ LL | | },
| |_____^
error: enum is never used: `ABC`
--> $DIR/lint-dead-code-4.rs:24:1
--> $DIR/lint-dead-code-4.rs:24:6
|
LL | enum ABC {
| ^^^^^^^^
| ^^^
error: variant is never constructed: `I`
--> $DIR/lint-dead-code-4.rs:36:5

View File

@ -23,10 +23,10 @@ LL | Variant6(isize),
| ^^^^^^^^^^^^^^^
error: enum is never used: `Enum3`
--> $DIR/lint-dead-code-5.rs:18:1
--> $DIR/lint-dead-code-5.rs:18:6
|
LL | enum Enum3 {
| ^^^^^^^^^^
| ^^^^^
error: aborting due to 4 previous errors

View File

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

View File

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

View File

@ -1,8 +1,8 @@
error: struct is never constructed: `F`
--> $DIR/unused-enum.rs:3:1
--> $DIR/unused-enum.rs:3:8
|
LL | struct F;
| ^^^^^^^^^
| ^
|
note: lint level defined here
--> $DIR/unused-enum.rs:1:9
@ -12,16 +12,16 @@ LL | #![deny(unused)]
= note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
error: struct is never constructed: `B`
--> $DIR/unused-enum.rs:4:1
--> $DIR/unused-enum.rs:4:8
|
LL | struct B;
| ^^^^^^^^^
| ^
error: enum is never used: `E`
--> $DIR/unused-enum.rs:6:1
--> $DIR/unused-enum.rs:6:6
|
LL | enum E {
| ^^^^^^
| ^
error: aborting due to 3 previous errors

View File

@ -1,8 +1,8 @@
error: function is never used: `foo`
--> $DIR/with-core-crate.rs:7:1
--> $DIR/with-core-crate.rs:7:4
|
LL | fn foo() {
| ^^^^^^^^
| ^^^
|
note: lint level defined here
--> $DIR/with-core-crate.rs:1:9

View File

@ -1,14 +1,14 @@
// run-pass
#![warn(unused)]
#![allow(dead_code)]
#![warn(unused_parens)]
// Parser test for #37765
fn with_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `with_parens`
fn with_parens<T: ToString>(arg: T) -> String {
return (<T as ToString>::to_string(&arg)); //~WARN unnecessary parentheses around `return` value
}
fn no_parens<T: ToString>(arg: T) -> String { //~WARN function is never used: `no_parens`
fn no_parens<T: ToString>(arg: T) -> String {
return <T as ToString>::to_string(&arg);
}

View File

@ -7,26 +7,6 @@ LL | return (<T as ToString>::to_string(&arg));
note: lint level defined here
--> $DIR/path-lookahead.rs:3:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(unused_parens)]` implied by `#[warn(unused)]`
warning: function is never used: `with_parens`
--> $DIR/path-lookahead.rs:7:1
|
LL | fn with_parens<T: ToString>(arg: T) -> String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lint level defined here
--> $DIR/path-lookahead.rs:3:9
|
LL | #![warn(unused)]
| ^^^^^^
= note: `#[warn(dead_code)]` implied by `#[warn(unused)]`
warning: function is never used: `no_parens`
--> $DIR/path-lookahead.rs:11:1
|
LL | fn no_parens<T: ToString>(arg: T) -> String {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | #![warn(unused_parens)]
| ^^^^^^^^^^^^^

View File

@ -1,11 +1,8 @@
warning: struct is never constructed: `S`
--> $DIR/macro-span-replacement.rs:7:14
--> $DIR/macro-span-replacement.rs:7:12
|
LL | $b $a;
| ^
...
LL | m!(S struct);
| ------------- in this macro invocation
| ^^
|
note: lint level defined here
--> $DIR/macro-span-replacement.rs:3:9

View File

@ -20,8 +20,8 @@ fn func() -> usize { //~ WARN function is never used
3
}
fn //~ WARN function is never used
func_complete_span()
fn
func_complete_span() //~ WARN function is never used
-> usize
{
3

View File

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

View File

@ -1,8 +1,8 @@
error: function is never used: `dead`
--> $DIR/test-warns-dead-code.rs:5:1
--> $DIR/test-warns-dead-code.rs:5:4
|
LL | fn dead() {}
| ^^^^^^^^^
| ^^^^
|
note: lint level defined here
--> $DIR/test-warns-dead-code.rs:3:9

View File

@ -1,5 +1,4 @@
// run-pass
#![no_std]
extern crate std;