summary refs log tree commit diff
path: root/src/test/ui/lint/dead-code
diff options
context:
space:
mode:
authorPi Lanningham <pi.lanningham@gmail.com>2019-10-25 00:42:05 -0400
committerPi Lanningham <pi.lanningham@gmail.com>2019-10-26 21:42:52 -0400
commite063ddb12e1e1d2ca0ab05b9976ee1d0b20a34e1 (patch)
treeb1a113ac15d254d72e491533fc53ba53eeb5e08b /src/test/ui/lint/dead-code
parent269d38413ce5f1e7ada5862b91e1d5a92f44857e (diff)
downloadrust-e063ddb12e1e1d2ca0ab05b9976ee1d0b20a34e1.tar.gz
rust-e063ddb12e1e1d2ca0ab05b9976ee1d0b20a34e1.zip
Move dead_code related tests to test/ui/dead-code
This helps organize the tests better.  I also renamed several of the tests to remove redundant dead-code in the path, and better match what they're testing
Diffstat (limited to 'src/test/ui/lint/dead-code')
-rw-r--r--src/test/ui/lint/dead-code/alias-in-pat.rs10
-rw-r--r--src/test/ui/lint/dead-code/associated-type.rs19
-rw-r--r--src/test/ui/lint/dead-code/basic.rs15
-rw-r--r--src/test/ui/lint/dead-code/basic.stderr14
-rw-r--r--src/test/ui/lint/dead-code/closure-bang.rs9
-rw-r--r--src/test/ui/lint/dead-code/const-and-self.rs35
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.rs5
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-enum.stderr15
-rw-r--r--src/test/ui/lint/dead-code/empty-unused-public-enum.rs6
-rw-r--r--src/test/ui/lint/dead-code/enum-variants.rs14
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.rs18
-rw-r--r--src/test/ui/lint/dead-code/impl-trait.stderr14
-rw-r--r--src/test/ui/lint/dead-code/leading-underscore.rs31
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.rs110
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-1.stderr68
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.rs41
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-2.stderr26
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.rs78
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-3.stderr38
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.rs83
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-4.stderr72
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.rs30
-rw-r--r--src/test/ui/lint/dead-code/lint-dead-code-5.stderr32
-rw-r--r--src/test/ui/lint/dead-code/tuple-struct-field.rs12
-rw-r--r--src/test/ui/lint/dead-code/type-alias.rs10
-rw-r--r--src/test/ui/lint/dead-code/type-alias.stderr14
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.rs11
-rw-r--r--src/test/ui/lint/dead-code/unused-enum.stderr27
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.rs13
-rw-r--r--src/test/ui/lint/dead-code/unused-struct-variant.stderr15
-rw-r--r--src/test/ui/lint/dead-code/unused-variant-pub.rs14
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.rs12
-rw-r--r--src/test/ui/lint/dead-code/unused-variant.stderr14
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.rs18
-rw-r--r--src/test/ui/lint/dead-code/with-core-crate.stderr14
-rw-r--r--src/test/ui/lint/dead-code/with-impl.rs17
36 files changed, 974 insertions, 0 deletions
diff --git a/src/test/ui/lint/dead-code/alias-in-pat.rs b/src/test/ui/lint/dead-code/alias-in-pat.rs
new file mode 100644
index 00000000000..69d455f3b60
--- /dev/null
+++ b/src/test/ui/lint/dead-code/alias-in-pat.rs
@@ -0,0 +1,10 @@
+// run-pass
+
+#![deny(dead_code)]
+
+fn main() {
+    struct Foo<T> { x: T }
+    type Bar = Foo<u32>;
+    let spam = |Bar { x }| x != 0;
+    println!("{}", spam(Foo { x: 10 }));
+}
diff --git a/src/test/ui/lint/dead-code/associated-type.rs b/src/test/ui/lint/dead-code/associated-type.rs
new file mode 100644
index 00000000000..1cf66e75a95
--- /dev/null
+++ b/src/test/ui/lint/dead-code/associated-type.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![deny(dead_code)]
+
+trait Foo {
+    type Bar;
+}
+
+struct Used;
+
+struct Ex;
+
+impl Foo for Ex {
+    type Bar = Used;
+}
+
+pub fn main() {
+    let _x = Ex;
+}
diff --git a/src/test/ui/lint/dead-code/basic.rs b/src/test/ui/lint/dead-code/basic.rs
new file mode 100644
index 00000000000..2b69985d33d
--- /dev/null
+++ b/src/test/ui/lint/dead-code/basic.rs
@@ -0,0 +1,15 @@
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+fn foo() { //~ ERROR function is never used
+
+    // none of these should have any dead_code exposed to the user
+    panic!();
+
+    panic!("foo");
+
+    panic!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/src/test/ui/lint/dead-code/basic.stderr b/src/test/ui/lint/dead-code/basic.stderr
new file mode 100644
index 00000000000..e5d1af12cf2
--- /dev/null
+++ b/src/test/ui/lint/dead-code/basic.stderr
@@ -0,0 +1,14 @@
+error: function is never used: `foo`
+  --> $DIR/basic.rs:4:1
+   |
+LL | fn foo() {
+   | ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/basic.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/closure-bang.rs b/src/test/ui/lint/dead-code/closure-bang.rs
new file mode 100644
index 00000000000..8e8636b1180
--- /dev/null
+++ b/src/test/ui/lint/dead-code/closure-bang.rs
@@ -0,0 +1,9 @@
+// ignore-test FIXME(#20574)
+
+#![deny(unreachable_code)]
+
+fn main() {
+    let x = || panic!();
+    x();
+    println!("Foo bar"); //~ ERROR: unreachable statement
+}
diff --git a/src/test/ui/lint/dead-code/const-and-self.rs b/src/test/ui/lint/dead-code/const-and-self.rs
new file mode 100644
index 00000000000..1a7b3f43cda
--- /dev/null
+++ b/src/test/ui/lint/dead-code/const-and-self.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![deny(dead_code)]
+
+const TLC: usize = 4;
+
+trait Tr { fn doit(&self); }
+
+impl Tr for [usize; TLC] {
+    fn doit(&self) {
+        println!("called 4");
+    }
+}
+
+struct X;
+struct Y;
+struct Z;
+
+trait Foo<T> {
+    type Ty;
+    fn foo() -> Self::Ty;
+}
+
+impl Foo<Y> for X {
+    type Ty = Z;
+    fn foo() -> Self::Ty {
+        unimplemented!()
+    }
+}
+
+fn main() {
+    let s = [0,1,2,3];
+    s.doit();
+    X::foo();
+}
diff --git a/src/test/ui/lint/dead-code/empty-unused-enum.rs b/src/test/ui/lint/dead-code/empty-unused-enum.rs
new file mode 100644
index 00000000000..834681d77e6
--- /dev/null
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.rs
@@ -0,0 +1,5 @@
+#![deny(unused)]
+
+enum E {} //~ ERROR enum is never used
+
+fn main() {}
diff --git a/src/test/ui/lint/dead-code/empty-unused-enum.stderr b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
new file mode 100644
index 00000000000..17bbdfc71a2
--- /dev/null
+++ b/src/test/ui/lint/dead-code/empty-unused-enum.stderr
@@ -0,0 +1,15 @@
+error: enum is never used: `E`
+  --> $DIR/empty-unused-enum.rs:3:1
+   |
+LL | enum E {}
+   | ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/empty-unused-enum.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/empty-unused-public-enum.rs b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
new file mode 100644
index 00000000000..15b04496ba7
--- /dev/null
+++ b/src/test/ui/lint/dead-code/empty-unused-public-enum.rs
@@ -0,0 +1,6 @@
+// build-pass
+#![deny(unused)]
+
+pub enum E {}
+
+fn main() {}
diff --git a/src/test/ui/lint/dead-code/enum-variants.rs b/src/test/ui/lint/dead-code/enum-variants.rs
new file mode 100644
index 00000000000..91c97232eed
--- /dev/null
+++ b/src/test/ui/lint/dead-code/enum-variants.rs
@@ -0,0 +1,14 @@
+// run-pass
+
+#![deny(dead_code)]
+
+enum Foo {
+    A,
+    B,
+}
+
+pub fn main() {
+    match Foo::A {
+        Foo::A | Foo::B => Foo::B
+    };
+}
diff --git a/src/test/ui/lint/dead-code/impl-trait.rs b/src/test/ui/lint/dead-code/impl-trait.rs
new file mode 100644
index 00000000000..a2736d97308
--- /dev/null
+++ b/src/test/ui/lint/dead-code/impl-trait.rs
@@ -0,0 +1,18 @@
+#![deny(dead_code)]
+
+trait Trait {
+    type Type;
+}
+
+impl Trait for () {
+    type Type = ();
+}
+
+type Used = ();
+type Unused = (); //~ ERROR type alias is never used
+
+fn foo() -> impl Trait<Type = Used> {}
+
+fn main() {
+    foo();
+}
diff --git a/src/test/ui/lint/dead-code/impl-trait.stderr b/src/test/ui/lint/dead-code/impl-trait.stderr
new file mode 100644
index 00000000000..f2a78cc65e2
--- /dev/null
+++ b/src/test/ui/lint/dead-code/impl-trait.stderr
@@ -0,0 +1,14 @@
+error: type alias is never used: `Unused`
+  --> $DIR/impl-trait.rs:12:1
+   |
+LL | type Unused = ();
+   | ^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/impl-trait.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/leading-underscore.rs b/src/test/ui/lint/dead-code/leading-underscore.rs
new file mode 100644
index 00000000000..1b6e03ab887
--- /dev/null
+++ b/src/test/ui/lint/dead-code/leading-underscore.rs
@@ -0,0 +1,31 @@
+// run-pass
+// pretty-expanded FIXME #23616
+
+#![deny(dead_code)]
+
+static _X: usize = 0;
+
+fn _foo() {}
+
+struct _Y {
+    _z: usize
+}
+
+enum _Z {}
+
+impl _Y {
+    fn _bar() {}
+}
+
+type _A = isize;
+
+mod _bar {
+    fn _qux() {}
+}
+
+extern {
+    #[link_name = "abort"]
+    fn _abort() -> !;
+}
+
+pub fn main() {}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.rs b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
new file mode 100644
index 00000000000..09977f8df51
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.rs
@@ -0,0 +1,110 @@
+#![no_std]
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+#![deny(dead_code)]
+
+#![crate_type="lib"]
+
+pub use foo2::Bar2;
+
+mod foo {
+    pub struct Bar; //~ ERROR: struct is never constructed
+}
+
+mod foo2 {
+    pub struct Bar2;
+}
+
+pub static pub_static: isize = 0;
+static priv_static: isize = 0; //~ ERROR: static item is never used
+const used_static: isize = 0;
+pub static used_static2: isize = used_static;
+const USED_STATIC: isize = 0;
+const STATIC_USED_IN_ENUM_DISCRIMINANT: isize = 10;
+
+pub const pub_const: isize = 0;
+const priv_const: isize = 0; //~ ERROR: constant item is never used
+const used_const: isize = 0;
+pub const used_const2: isize = used_const;
+const USED_CONST: isize = 1;
+const CONST_USED_IN_ENUM_DISCRIMINANT: isize = 11;
+
+pub type typ = *const UsedStruct4;
+pub struct PubStruct;
+struct PrivStruct; //~ ERROR: struct is never constructed
+struct UsedStruct1 {
+    #[allow(dead_code)]
+    x: isize
+}
+struct UsedStruct2(isize);
+struct UsedStruct3;
+pub struct UsedStruct4;
+// this struct is never used directly, but its method is, so we don't want
+// to warn it
+struct SemiUsedStruct;
+impl SemiUsedStruct {
+    fn la_la_la() {}
+}
+struct StructUsedAsField;
+pub struct StructUsedInEnum;
+struct StructUsedInGeneric;
+pub struct PubStruct2 {
+    #[allow(dead_code)]
+    struct_used_as_field: *const StructUsedAsField
+}
+
+pub enum pub_enum { foo1, bar1 }
+pub enum pub_enum2 { a(*const StructUsedInEnum) }
+pub enum pub_enum3 {
+    Foo = STATIC_USED_IN_ENUM_DISCRIMINANT,
+    Bar = CONST_USED_IN_ENUM_DISCRIMINANT,
+}
+
+enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used
+enum used_enum {
+    foo3,
+    bar3 //~ ERROR variant is never constructed
+}
+
+fn f<T>() {}
+
+pub fn pub_fn() {
+    used_fn();
+    let used_struct1 = UsedStruct1 { x: 1 };
+    let used_struct2 = UsedStruct2(1);
+    let used_struct3 = UsedStruct3;
+    let e = used_enum::foo3;
+    SemiUsedStruct::la_la_la();
+
+    let i = 1;
+    match i {
+        USED_STATIC => (),
+        USED_CONST => (),
+        _ => ()
+    }
+    f::<StructUsedInGeneric>();
+}
+fn priv_fn() { //~ ERROR: function is never used
+    let unused_struct = PrivStruct;
+}
+fn used_fn() {}
+
+fn foo() { //~ ERROR: function is never used
+    bar();
+    let unused_enum = priv_enum::foo2;
+}
+
+fn bar() { //~ ERROR: function is never used
+    foo();
+}
+
+fn baz() -> impl Copy { //~ ERROR: function is never used
+    "I'm unused, too"
+}
+
+// Code with #[allow(dead_code)] should be marked live (and thus anything it
+// calls is marked live)
+#[allow(dead_code)]
+fn g() { h(); }
+fn h() {}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-1.stderr b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
new file mode 100644
index 00000000000..be96c697d99
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-1.stderr
@@ -0,0 +1,68 @@
+error: struct is never constructed: `Bar`
+  --> $DIR/lint-dead-code-1.rs:12:5
+   |
+LL |     pub struct Bar;
+   |     ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-1.rs:5:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: static item is never used: `priv_static`
+  --> $DIR/lint-dead-code-1.rs:20:1
+   |
+LL | static priv_static: isize = 0;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: constant item is never used: `priv_const`
+  --> $DIR/lint-dead-code-1.rs:27:1
+   |
+LL | const priv_const: isize = 0;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: struct is never constructed: `PrivStruct`
+  --> $DIR/lint-dead-code-1.rs:35:1
+   |
+LL | struct PrivStruct;
+   | ^^^^^^^^^^^^^^^^^^
+
+error: enum is never used: `priv_enum`
+  --> $DIR/lint-dead-code-1.rs:64:1
+   |
+LL | enum priv_enum { foo2, bar2 }
+   | ^^^^^^^^^^^^^^
+
+error: variant is never constructed: `bar3`
+  --> $DIR/lint-dead-code-1.rs:67:5
+   |
+LL |     bar3
+   |     ^^^^
+
+error: function is never used: `priv_fn`
+  --> $DIR/lint-dead-code-1.rs:88:1
+   |
+LL | fn priv_fn() {
+   | ^^^^^^^^^^^^
+
+error: function is never used: `foo`
+  --> $DIR/lint-dead-code-1.rs:93:1
+   |
+LL | fn foo() {
+   | ^^^^^^^^
+
+error: function is never used: `bar`
+  --> $DIR/lint-dead-code-1.rs:98:1
+   |
+LL | fn bar() {
+   | ^^^^^^^^
+
+error: function is never used: `baz`
+  --> $DIR/lint-dead-code-1.rs:102:1
+   |
+LL | fn baz() -> impl Copy {
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-2.rs b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
new file mode 100644
index 00000000000..88db4f88c3f
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.rs
@@ -0,0 +1,41 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+#![feature(main, start)]
+
+struct Foo;
+
+trait Bar {
+    fn bar1(&self);
+    fn bar2(&self) {
+        self.bar1();
+    }
+}
+
+impl Bar for Foo {
+    fn bar1(&self) {
+        live_fn();
+    }
+}
+
+fn live_fn() {}
+
+fn dead_fn() {} //~ ERROR: function is never used
+
+#[main]
+fn dead_fn2() {} //~ ERROR: function is never used
+
+fn used_fn() {}
+
+#[start]
+fn start(_: isize, _: *const *const u8) -> isize {
+    used_fn();
+    let foo = Foo;
+    foo.bar2();
+    0
+}
+
+// this is not main
+fn main() { //~ ERROR: function is never used
+    dead_fn();
+    dead_fn2();
+}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-2.stderr b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
new file mode 100644
index 00000000000..1226f9823ac
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-2.stderr
@@ -0,0 +1,26 @@
+error: function is never used: `dead_fn`
+  --> $DIR/lint-dead-code-2.rs:22:1
+   |
+LL | fn dead_fn() {}
+   | ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-2.rs:2:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: function is never used: `dead_fn2`
+  --> $DIR/lint-dead-code-2.rs:25:1
+   |
+LL | fn dead_fn2() {}
+   | ^^^^^^^^^^^^^
+
+error: function is never used: `main`
+  --> $DIR/lint-dead-code-2.rs:38:1
+   |
+LL | fn main() {
+   | ^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.rs b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
new file mode 100644
index 00000000000..4397522f3f3
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.rs
@@ -0,0 +1,78 @@
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![deny(dead_code)]
+
+#![crate_type="lib"]
+
+
+pub use extern_foo as x;
+extern {
+    pub fn extern_foo();
+}
+
+struct Foo; //~ ERROR: struct is never constructed
+impl Foo {
+    fn foo(&self) { //~ ERROR: method is never used
+        bar()
+    }
+}
+
+fn bar() { //~ ERROR: function is never used
+    fn baz() {}
+
+    Foo.foo();
+    baz();
+}
+
+// no warning
+struct Foo2;
+impl Foo2 { fn foo2(&self) { bar2() } }
+fn bar2() {
+    fn baz2() {}
+
+    Foo2.foo2();
+    baz2();
+}
+
+pub fn pub_fn() {
+    let foo2_struct = Foo2;
+    foo2_struct.foo2();
+
+    blah::baz();
+}
+
+mod blah {
+    // not warned because it's used in the parameter of `free` and return of
+    // `malloc` below, which are also used.
+    enum c_void {}
+
+    extern {
+        fn free(p: *const c_void);
+        fn malloc(size: usize) -> *const c_void;
+    }
+
+    pub fn baz() {
+        unsafe { free(malloc(4)); }
+    }
+}
+
+enum c_void {} //~ ERROR: enum is never used
+extern {
+    fn free(p: *const c_void); //~ ERROR: foreign function is never used
+}
+
+// Check provided method
+mod inner {
+    pub trait Trait {
+        fn f(&self) { f(); }
+    }
+
+    impl Trait for isize {}
+
+    fn f() {}
+}
+
+pub fn foo() {
+    let a: &dyn inner::Trait = &1_isize;
+    a.f();
+}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-3.stderr b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
new file mode 100644
index 00000000000..2408da0af89
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -0,0 +1,38 @@
+error: struct is never constructed: `Foo`
+  --> $DIR/lint-dead-code-3.rs:13:1
+   |
+LL | struct Foo;
+   | ^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-3.rs:3:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: method is never used: `foo`
+  --> $DIR/lint-dead-code-3.rs:15:5
+   |
+LL |     fn foo(&self) {
+   |     ^^^^^^^^^^^^^
+
+error: function is never used: `bar`
+  --> $DIR/lint-dead-code-3.rs:20:1
+   |
+LL | fn bar() {
+   | ^^^^^^^^
+
+error: enum is never used: `c_void`
+  --> $DIR/lint-dead-code-3.rs:59:1
+   |
+LL | enum c_void {}
+   | ^^^^^^^^^^^
+
+error: foreign function is never used: `free`
+  --> $DIR/lint-dead-code-3.rs:61:5
+   |
+LL |     fn free(p: *const c_void);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-4.rs b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
new file mode 100644
index 00000000000..3f4a9e21040
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.rs
@@ -0,0 +1,83 @@
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![deny(dead_code)]
+
+struct Foo {
+    x: usize,
+    b: bool, //~ ERROR: field is never used
+}
+
+fn field_read(f: Foo) -> usize {
+    f.x.pow(2)
+}
+
+enum XYZ {
+    X, //~ ERROR variant is never constructed
+    Y { //~ ERROR variant is never constructed
+        a: String,
+        b: i32,
+        c: i32,
+    },
+    Z
+}
+
+enum ABC { //~ ERROR enum is never used
+    A,
+    B {
+        a: String,
+        b: i32,
+        c: i32,
+    },
+    C
+}
+
+// ensure struct variants get warning for their fields
+enum IJK {
+    I, //~ ERROR variant is never constructed
+    J {
+        a: String,
+        b: i32, //~ ERROR field is never used
+        c: i32, //~ ERROR field is never used
+    },
+    K //~ ERROR variant is never constructed
+
+}
+
+fn struct_variant_partial_use(b: IJK) -> String {
+    match b {
+        IJK::J { a, b: _, .. } => a,
+        _ => "".to_string()
+    }
+}
+
+fn field_match_in_patterns(b: XYZ) -> String {
+    match b {
+        XYZ::Y { a, b: _, .. } => a,
+        _ => "".to_string()
+    }
+}
+
+struct Bar {
+    x: usize, //~ ERROR: field is never used
+    b: bool,
+    c: bool, //~ ERROR: field is never used
+    _guard: ()
+}
+
+#[repr(C)]
+struct Baz {
+    x: u32,
+}
+
+fn field_match_in_let(f: Bar) -> bool {
+    let Bar { b, c: _, .. } = f;
+    b
+}
+
+fn main() {
+    field_read(Foo { x: 1, b: false });
+    field_match_in_patterns(XYZ::Z);
+    struct_variant_partial_use(IJK::J { a: "".into(), b: 1, c: -1 });
+    field_match_in_let(Bar { x: 42, b: true, c: false, _guard: () });
+    let _ = Baz { x: 0 };
+}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-4.stderr b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
new file mode 100644
index 00000000000..b7ceee99998
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-4.stderr
@@ -0,0 +1,72 @@
+error: field is never used: `b`
+  --> $DIR/lint-dead-code-4.rs:7:5
+   |
+LL |     b: bool,
+   |     ^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-4.rs:3:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: variant is never constructed: `X`
+  --> $DIR/lint-dead-code-4.rs:15:5
+   |
+LL |     X,
+   |     ^
+
+error: variant is never constructed: `Y`
+  --> $DIR/lint-dead-code-4.rs:16:5
+   |
+LL | /     Y {
+LL | |         a: String,
+LL | |         b: i32,
+LL | |         c: i32,
+LL | |     },
+   | |_____^
+
+error: enum is never used: `ABC`
+  --> $DIR/lint-dead-code-4.rs:24:1
+   |
+LL | enum ABC {
+   | ^^^^^^^^
+
+error: variant is never constructed: `I`
+  --> $DIR/lint-dead-code-4.rs:36:5
+   |
+LL |     I,
+   |     ^
+
+error: field is never used: `b`
+  --> $DIR/lint-dead-code-4.rs:39:9
+   |
+LL |         b: i32,
+   |         ^^^^^^
+
+error: field is never used: `c`
+  --> $DIR/lint-dead-code-4.rs:40:9
+   |
+LL |         c: i32,
+   |         ^^^^^^
+
+error: variant is never constructed: `K`
+  --> $DIR/lint-dead-code-4.rs:42:5
+   |
+LL |     K
+   |     ^
+
+error: field is never used: `x`
+  --> $DIR/lint-dead-code-4.rs:61:5
+   |
+LL |     x: usize,
+   |     ^^^^^^^^
+
+error: field is never used: `c`
+  --> $DIR/lint-dead-code-4.rs:63:5
+   |
+LL |     c: bool,
+   |     ^^^^^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-5.rs b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
new file mode 100644
index 00000000000..764a23e4e49
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.rs
@@ -0,0 +1,30 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+
+enum Enum1 {
+    Variant1(isize),
+    Variant2 //~ ERROR: variant is never constructed
+}
+
+enum Enum2 {
+    Variant3(bool),
+    #[allow(dead_code)]
+    Variant4(isize),
+    Variant5 { _x: isize }, //~ ERROR: variant is never constructed: `Variant5`
+    Variant6(isize), //~ ERROR: variant is never constructed: `Variant6`
+    _Variant7,
+}
+
+enum Enum3 { //~ ERROR: enum is never used
+    Variant8,
+    Variant9
+}
+
+fn main() {
+    let v = Enum1::Variant1(1);
+    match v {
+        Enum1::Variant1(_) => (),
+        Enum1::Variant2 => ()
+    }
+    let x = Enum2::Variant3(true);
+}
diff --git a/src/test/ui/lint/dead-code/lint-dead-code-5.stderr b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
new file mode 100644
index 00000000000..740cfde2c06
--- /dev/null
+++ b/src/test/ui/lint/dead-code/lint-dead-code-5.stderr
@@ -0,0 +1,32 @@
+error: variant is never constructed: `Variant2`
+  --> $DIR/lint-dead-code-5.rs:6:5
+   |
+LL |     Variant2
+   |     ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-5.rs:2:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: variant is never constructed: `Variant5`
+  --> $DIR/lint-dead-code-5.rs:13:5
+   |
+LL |     Variant5 { _x: isize },
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: variant is never constructed: `Variant6`
+  --> $DIR/lint-dead-code-5.rs:14:5
+   |
+LL |     Variant6(isize),
+   |     ^^^^^^^^^^^^^^^
+
+error: enum is never used: `Enum3`
+  --> $DIR/lint-dead-code-5.rs:18:1
+   |
+LL | enum Enum3 {
+   | ^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/lint/dead-code/tuple-struct-field.rs b/src/test/ui/lint/dead-code/tuple-struct-field.rs
new file mode 100644
index 00000000000..92a67950986
--- /dev/null
+++ b/src/test/ui/lint/dead-code/tuple-struct-field.rs
@@ -0,0 +1,12 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![deny(dead_code)]
+
+const LEN: usize = 4;
+
+#[derive(Debug)]
+struct Wrapper([u8; LEN]);
+
+fn main() {
+    println!("{:?}", Wrapper([0, 1, 2, 3]));
+}
diff --git a/src/test/ui/lint/dead-code/type-alias.rs b/src/test/ui/lint/dead-code/type-alias.rs
new file mode 100644
index 00000000000..86daf3ea04d
--- /dev/null
+++ b/src/test/ui/lint/dead-code/type-alias.rs
@@ -0,0 +1,10 @@
+#![deny(dead_code)]
+
+type Used = u8;
+type Unused = u8; //~ ERROR type alias is never used
+
+fn id(x: Used) -> Used { x }
+
+fn main() {
+    id(0);
+}
diff --git a/src/test/ui/lint/dead-code/type-alias.stderr b/src/test/ui/lint/dead-code/type-alias.stderr
new file mode 100644
index 00000000000..82df23bd944
--- /dev/null
+++ b/src/test/ui/lint/dead-code/type-alias.stderr
@@ -0,0 +1,14 @@
+error: type alias is never used: `Unused`
+  --> $DIR/type-alias.rs:4:1
+   |
+LL | type Unused = u8;
+   | ^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/type-alias.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/unused-enum.rs b/src/test/ui/lint/dead-code/unused-enum.rs
new file mode 100644
index 00000000000..e57fac259c5
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-enum.rs
@@ -0,0 +1,11 @@
+#![deny(unused)]
+
+struct F; //~ ERROR struct is never constructed
+struct B; //~ ERROR struct is never constructed
+
+enum E { //~ ERROR enum is never used
+    Foo(F),
+    Bar(B),
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/dead-code/unused-enum.stderr b/src/test/ui/lint/dead-code/unused-enum.stderr
new file mode 100644
index 00000000000..682dfcf5881
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-enum.stderr
@@ -0,0 +1,27 @@
+error: struct is never constructed: `F`
+  --> $DIR/unused-enum.rs:3:1
+   |
+LL | struct F;
+   | ^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unused-enum.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: struct is never constructed: `B`
+  --> $DIR/unused-enum.rs:4:1
+   |
+LL | struct B;
+   | ^^^^^^^^^
+
+error: enum is never used: `E`
+  --> $DIR/unused-enum.rs:6:1
+   |
+LL | enum E {
+   | ^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/lint/dead-code/unused-struct-variant.rs b/src/test/ui/lint/dead-code/unused-struct-variant.rs
new file mode 100644
index 00000000000..69ab29042e5
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.rs
@@ -0,0 +1,13 @@
+#![deny(unused)]
+
+struct F;
+struct B;
+
+enum E {
+    Foo(F),
+    Bar(B), //~ ERROR variant is never constructed
+}
+
+fn main() {
+    let _ = E::Foo(F);
+}
diff --git a/src/test/ui/lint/dead-code/unused-struct-variant.stderr b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
new file mode 100644
index 00000000000..0037592e3de
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-struct-variant.stderr
@@ -0,0 +1,15 @@
+error: variant is never constructed: `Bar`
+  --> $DIR/unused-struct-variant.rs:8:5
+   |
+LL |     Bar(B),
+   |     ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unused-struct-variant.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/unused-variant-pub.rs b/src/test/ui/lint/dead-code/unused-variant-pub.rs
new file mode 100644
index 00000000000..3a9061340eb
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-variant-pub.rs
@@ -0,0 +1,14 @@
+// build-pass
+#![deny(unused)]
+
+pub struct F;
+pub struct B;
+
+pub enum E {
+    Foo(F),
+    Bar(B),
+}
+
+fn main() {
+    let _ = E::Foo(F);
+}
diff --git a/src/test/ui/lint/dead-code/unused-variant.rs b/src/test/ui/lint/dead-code/unused-variant.rs
new file mode 100644
index 00000000000..295ed16d4cf
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-variant.rs
@@ -0,0 +1,12 @@
+#![deny(dead_code)]
+
+#[derive(Clone)]
+enum Enum {
+    Variant1, //~ ERROR: variant is never constructed
+    Variant2,
+}
+
+fn main() {
+    let e = Enum::Variant2;
+    e.clone();
+}
diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr
new file mode 100644
index 00000000000..2167b9d910d
--- /dev/null
+++ b/src/test/ui/lint/dead-code/unused-variant.stderr
@@ -0,0 +1,14 @@
+error: variant is never constructed: `Variant1`
+  --> $DIR/unused-variant.rs:5:5
+   |
+LL |     Variant1,
+   |     ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unused-variant.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/with-core-crate.rs b/src/test/ui/lint/dead-code/with-core-crate.rs
new file mode 100644
index 00000000000..bc74e807783
--- /dev/null
+++ b/src/test/ui/lint/dead-code/with-core-crate.rs
@@ -0,0 +1,18 @@
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+#[macro_use]
+extern crate core;
+
+fn foo() { //~ ERROR function is never used
+
+    // none of these should have any dead_code exposed to the user
+    panic!();
+
+    panic!("foo");
+
+    panic!("bar {}", "baz")
+}
+
+
+fn main() {}
diff --git a/src/test/ui/lint/dead-code/with-core-crate.stderr b/src/test/ui/lint/dead-code/with-core-crate.stderr
new file mode 100644
index 00000000000..30caac3cd01
--- /dev/null
+++ b/src/test/ui/lint/dead-code/with-core-crate.stderr
@@ -0,0 +1,14 @@
+error: function is never used: `foo`
+  --> $DIR/with-core-crate.rs:7:1
+   |
+LL | fn foo() {
+   | ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/with-core-crate.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/dead-code/with-impl.rs b/src/test/ui/lint/dead-code/with-impl.rs
new file mode 100644
index 00000000000..84829c98e57
--- /dev/null
+++ b/src/test/ui/lint/dead-code/with-impl.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![deny(dead_code)]
+
+pub struct GenericFoo<T>(T);
+
+type Foo = GenericFoo<u32>;
+
+impl Foo {
+    fn bar(self) -> u8 {
+        0
+    }
+}
+
+fn main() {
+    println!("{}", GenericFoo(0).bar());
+}