Improve dead code analysis
This commit is contained in:
parent
bae813a265
commit
0adb82528f
21 changed files with 173 additions and 69 deletions
|
|
@ -17,18 +17,21 @@ mod submod {
|
|||
// if any of these are implemented without global calls for any
|
||||
// function calls, then being in a submodule will (correctly)
|
||||
// cause errors about unrecognised module `std` (or `extra`)
|
||||
#[allow(dead_code)]
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
|
||||
enum A {
|
||||
A1(usize),
|
||||
A2(isize),
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
|
||||
struct B {
|
||||
x: usize,
|
||||
y: isize,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone, Debug, Encodable, Decodable)]
|
||||
struct C(usize, isize);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ pub const s: u8 = 1;
|
|||
pub const state: u8 = 1;
|
||||
pub const cmp: u8 = 1;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Ord, Eq, PartialOrd, PartialEq, Debug, Decodable, Encodable, Hash)]
|
||||
struct Foo {}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ pub trait Foo {
|
|||
fn foo() where [(); Self::ASSOC_C]:;
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Bar<const N: &'static ()>;
|
||||
impl<const N: &'static ()> Foo for Bar<N> {
|
||||
const ASSOC_C: usize = 3;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#![feature(adt_const_params, generic_const_exprs)]
|
||||
#![allow(incomplete_features, unused_variables)]
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct F<const S: &'static str>;
|
||||
impl<const S: &'static str> X for F<{ S }> {
|
||||
const W: usize = 3;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct S<T>(T);
|
||||
#[allow(dead_code)]
|
||||
struct S2;
|
||||
|
||||
impl<T: Default> Default for S<T> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct S<T>(T);
|
||||
#[allow(dead_code)]
|
||||
struct S2;
|
||||
|
||||
impl<T: Default> impl Default for S<T> {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
error: unexpected `impl` keyword
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:6:18
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:8:18
|
||||
|
|
||||
LL | impl<T: Default> impl Default for S<T> {
|
||||
| ^^^^^ help: remove the extra `impl`
|
||||
|
|
||||
note: this is parsed as an `impl Trait` type, but a trait is expected at this position
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:6:18
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:8:18
|
||||
|
|
||||
LL | impl<T: Default> impl Default for S<T> {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: unexpected `impl` keyword
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:12:6
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:14:6
|
||||
|
|
||||
LL | impl impl Default for S2 {
|
||||
| ^^^^^ help: remove the extra `impl`
|
||||
|
|
||||
note: this is parsed as an `impl Trait` type, but a trait is expected at this position
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:12:6
|
||||
--> $DIR/extra-impl-in-trait-impl.rs:14:6
|
||||
|
|
||||
LL | impl impl Default for S2 {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#![deny(dead_code)]
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo {
|
||||
#[allow(dead_code)]
|
||||
inner: u32,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
#![deny(dead_code)]
|
||||
|
||||
struct Foo(u8); //~ ERROR struct `Foo` is never constructed
|
||||
|
||||
enum Bar { //~ ERROR enum `Bar` is never used
|
||||
Var1(u8),
|
||||
Var2(u8),
|
||||
}
|
||||
|
||||
pub trait Tr1 {
|
||||
fn f1() -> Self;
|
||||
}
|
||||
|
||||
impl Tr1 for Foo {
|
||||
fn f1() -> Foo {
|
||||
let f = Foo(0);
|
||||
let Foo(tag) = f;
|
||||
Foo(tag)
|
||||
}
|
||||
}
|
||||
|
||||
impl Tr1 for Bar {
|
||||
fn f1() -> Bar {
|
||||
let b = Bar::Var1(0);
|
||||
let b = if let Bar::Var1(_) = b {
|
||||
Bar::Var1(0)
|
||||
} else {
|
||||
Bar::Var2(0)
|
||||
};
|
||||
match b {
|
||||
Bar::Var1(_) => Bar::Var2(0),
|
||||
Bar::Var2(_) => Bar::Var1(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
error: struct `Foo` is never constructed
|
||||
--> $DIR/lint-unused-adt-appeared-in-pattern.rs:3:8
|
||||
|
|
||||
LL | struct Foo(u8);
|
||||
| ^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-unused-adt-appeared-in-pattern.rs:1:9
|
||||
|
|
||||
LL | #![deny(dead_code)]
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: enum `Bar` is never used
|
||||
--> $DIR/lint-unused-adt-appeared-in-pattern.rs:5:6
|
||||
|
|
||||
LL | enum Bar {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
//@ check-pass
|
||||
|
||||
#![deny(dead_code)]
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum RecordField {
|
||||
Target = 1,
|
||||
Level,
|
||||
Module,
|
||||
File,
|
||||
Line,
|
||||
NumArgs,
|
||||
}
|
||||
|
||||
unsafe trait Pod {}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct RecordFieldWrapper(RecordField);
|
||||
|
||||
unsafe impl Pod for RecordFieldWrapper {}
|
||||
|
||||
fn try_read<T: Pod>(buf: &[u8]) -> T {
|
||||
unsafe { std::ptr::read_unaligned(buf.as_ptr() as *const T) }
|
||||
}
|
||||
|
||||
pub fn foo(buf: &[u8]) -> RecordField {
|
||||
let RecordFieldWrapper(tag) = try_read(buf);
|
||||
tag
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
#![deny(dead_code)]
|
||||
|
||||
struct T1; //~ ERROR struct `T1` is never constructed
|
||||
pub struct T2(i32); //~ ERROR struct `T2` is never constructed
|
||||
struct T3;
|
||||
struct T2; //~ ERROR struct `T2` is never constructed
|
||||
pub struct T3(i32); //~ ERROR struct `T3` is never constructed
|
||||
pub struct T4(i32); //~ ERROR field `0` is never read
|
||||
|
||||
trait Trait1 { //~ ERROR trait `Trait1` is never used
|
||||
const UNUSED: i32;
|
||||
|
|
@ -11,13 +12,13 @@ trait Trait1 { //~ ERROR trait `Trait1` is never used
|
|||
}
|
||||
|
||||
pub trait Trait2 {
|
||||
const USED: i32;
|
||||
fn used(&self) {}
|
||||
const MAY_USED: i32;
|
||||
fn may_used(&self) {}
|
||||
}
|
||||
|
||||
pub trait Trait3 {
|
||||
const USED: i32;
|
||||
fn construct_self() -> Self;
|
||||
const MAY_USED: i32;
|
||||
fn may_used() -> Self;
|
||||
}
|
||||
|
||||
impl Trait1 for T1 {
|
||||
|
|
@ -29,24 +30,35 @@ impl Trait1 for T1 {
|
|||
|
||||
impl Trait1 for T2 {
|
||||
const UNUSED: i32 = 0;
|
||||
fn construct_self() -> Self {
|
||||
T2(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait2 for T1 {
|
||||
const USED: i32 = 0;
|
||||
}
|
||||
|
||||
impl Trait2 for T2 {
|
||||
const USED: i32 = 0;
|
||||
}
|
||||
|
||||
impl Trait3 for T3 {
|
||||
const USED: i32 = 0;
|
||||
fn construct_self() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait2 for T1 {
|
||||
const MAY_USED: i32 = 0;
|
||||
}
|
||||
|
||||
impl Trait2 for T2 {
|
||||
const MAY_USED: i32 = 0;
|
||||
}
|
||||
|
||||
impl Trait2 for T3 {
|
||||
const MAY_USED: i32 = 0;
|
||||
}
|
||||
|
||||
impl Trait3 for T2 {
|
||||
const MAY_USED: i32 = 0;
|
||||
fn may_used() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait3 for T4 {
|
||||
const MAY_USED: i32 = 0;
|
||||
fn may_used() -> Self {
|
||||
T4(0)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -11,16 +11,32 @@ LL | #![deny(dead_code)]
|
|||
| ^^^^^^^^^
|
||||
|
||||
error: struct `T2` is never constructed
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:12
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:4:8
|
||||
|
|
||||
LL | pub struct T2(i32);
|
||||
LL | struct T2;
|
||||
| ^^
|
||||
|
||||
error: struct `T3` is never constructed
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:5:12
|
||||
|
|
||||
LL | pub struct T3(i32);
|
||||
| ^^
|
||||
|
||||
error: field `0` is never read
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:6:15
|
||||
|
|
||||
LL | pub struct T4(i32);
|
||||
| -- ^^^
|
||||
| |
|
||||
| field in this struct
|
||||
|
|
||||
= help: consider removing this field
|
||||
|
||||
error: trait `Trait1` is never used
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:7:7
|
||||
--> $DIR/unused-adt-impl-pub-trait-with-assoc-const.rs:8:7
|
||||
|
|
||||
LL | trait Trait1 {
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ pub struct T2 {
|
|||
|
||||
fn main() {
|
||||
let _x: Used = Default::default();
|
||||
let _e: E = Default::default();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ error: struct `T` is never constructed
|
|||
LL | struct T;
|
||||
| ^
|
||||
|
|
||||
= note: `T` has a derived impl for the trait `Default`, but this is intentionally ignored during dead code analysis
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unused-struct-derive-default.rs:1:9
|
||||
|
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo;
|
||||
|
||||
impl From<i32> for Foo {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//@ run-rustfix
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo;
|
||||
|
||||
fn From<i32> for Foo {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: you might have meant to write `impl` instead of `fn`
|
||||
--> $DIR/issue-105366.rs:5:1
|
||||
--> $DIR/issue-105366.rs:6:1
|
||||
|
|
||||
LL | fn From<i32> for Foo {
|
||||
| ^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue