summaryrefslogtreecommitdiffstats
path: root/tests/ui/lint/dead-code
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /tests/ui/lint/dead-code
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/lint/dead-code')
-rw-r--r--tests/ui/lint/dead-code/alias-in-pat.rs10
-rw-r--r--tests/ui/lint/dead-code/anon-const-in-pat.rs45
-rw-r--r--tests/ui/lint/dead-code/associated-type.rs19
-rw-r--r--tests/ui/lint/dead-code/basic.rs15
-rw-r--r--tests/ui/lint/dead-code/basic.stderr14
-rw-r--r--tests/ui/lint/dead-code/closure-bang.rs9
-rw-r--r--tests/ui/lint/dead-code/const-and-self.rs54
-rw-r--r--tests/ui/lint/dead-code/const-and-self.stderr19
-rw-r--r--tests/ui/lint/dead-code/empty-unused-enum.rs5
-rw-r--r--tests/ui/lint/dead-code/empty-unused-enum.stderr15
-rw-r--r--tests/ui/lint/dead-code/empty-unused-public-enum.rs6
-rw-r--r--tests/ui/lint/dead-code/enum-variants.rs14
-rw-r--r--tests/ui/lint/dead-code/impl-trait.rs18
-rw-r--r--tests/ui/lint/dead-code/impl-trait.stderr14
-rw-r--r--tests/ui/lint/dead-code/issue-68408-false-positive.rs22
-rw-r--r--tests/ui/lint/dead-code/issue-85071-2.rs22
-rw-r--r--tests/ui/lint/dead-code/issue-85071-2.stderr34
-rw-r--r--tests/ui/lint/dead-code/issue-85071.rs19
-rw-r--r--tests/ui/lint/dead-code/issue-85071.stderr34
-rw-r--r--tests/ui/lint/dead-code/issue-85255.rs50
-rw-r--r--tests/ui/lint/dead-code/issue-85255.stderr74
-rw-r--r--tests/ui/lint/dead-code/leading-underscore.rs31
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-1.rs110
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-1.stderr71
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-2.rs41
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-2.stderr26
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.rs90
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-3.stderr50
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-4.rs83
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-4.stderr66
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-5.rs50
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-5.stderr34
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.rs20
-rw-r--r--tests/ui/lint/dead-code/lint-dead-code-6.stderr32
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs29
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr55
-rw-r--r--tests/ui/lint/dead-code/newline-span.rs19
-rw-r--r--tests/ui/lint/dead-code/newline-span.stderr26
-rw-r--r--tests/ui/lint/dead-code/self-assign.rs52
-rw-r--r--tests/ui/lint/dead-code/self-assign.stderr44
-rw-r--r--tests/ui/lint/dead-code/trait-impl.rs19
-rw-r--r--tests/ui/lint/dead-code/tuple-struct-field.rs37
-rw-r--r--tests/ui/lint/dead-code/tuple-struct-field.stderr33
-rw-r--r--tests/ui/lint/dead-code/type-alias.rs10
-rw-r--r--tests/ui/lint/dead-code/type-alias.stderr14
-rw-r--r--tests/ui/lint/dead-code/type-in-foreign.rs19
-rw-r--r--tests/ui/lint/dead-code/unused-enum.rs12
-rw-r--r--tests/ui/lint/dead-code/unused-enum.stderr27
-rw-r--r--tests/ui/lint/dead-code/unused-struct-variant.rs13
-rw-r--r--tests/ui/lint/dead-code/unused-struct-variant.stderr18
-rw-r--r--tests/ui/lint/dead-code/unused-variant-pub.rs14
-rw-r--r--tests/ui/lint/dead-code/unused-variant.rs12
-rw-r--r--tests/ui/lint/dead-code/unused-variant.stderr17
-rw-r--r--tests/ui/lint/dead-code/with-core-crate.rs18
-rw-r--r--tests/ui/lint/dead-code/with-core-crate.stderr14
-rw-r--r--tests/ui/lint/dead-code/with-impl.rs17
56 files changed, 1735 insertions, 0 deletions
diff --git a/tests/ui/lint/dead-code/alias-in-pat.rs b/tests/ui/lint/dead-code/alias-in-pat.rs
new file mode 100644
index 000000000..69d455f3b
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/anon-const-in-pat.rs b/tests/ui/lint/dead-code/anon-const-in-pat.rs
new file mode 100644
index 000000000..d3e39c0de
--- /dev/null
+++ b/tests/ui/lint/dead-code/anon-const-in-pat.rs
@@ -0,0 +1,45 @@
+// check-pass
+#![feature(inline_const_pat)]
+#![allow(incomplete_features)]
+#![deny(dead_code)]
+
+const fn one() -> i32 {
+ 1
+}
+
+const fn two() -> i32 {
+ 2
+}
+
+const fn three() -> i32 {
+ 3
+}
+
+fn inline_const() {
+ // rust-lang/rust#78171: dead_code lint triggers even though function is used in const pattern
+ match 1 {
+ const { one() } => {}
+ _ => {}
+ }
+}
+
+fn inline_const_range() {
+ match 1 {
+ 1 ..= const { two() } => {}
+ _ => {}
+ }
+}
+
+struct S<const C: i32>;
+
+fn const_generic_arg() {
+ match S::<3> {
+ S::<{three()}> => {}
+ }
+}
+
+fn main() {
+ inline_const();
+ inline_const_range();
+ const_generic_arg();
+}
diff --git a/tests/ui/lint/dead-code/associated-type.rs b/tests/ui/lint/dead-code/associated-type.rs
new file mode 100644
index 000000000..1cf66e75a
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/basic.rs b/tests/ui/lint/dead-code/basic.rs
new file mode 100644
index 000000000..3b8ffd58c
--- /dev/null
+++ b/tests/ui/lint/dead-code/basic.rs
@@ -0,0 +1,15 @@
+#![deny(dead_code)]
+#![allow(unreachable_code)]
+
+fn foo() { //~ ERROR function `foo` 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/tests/ui/lint/dead-code/basic.stderr b/tests/ui/lint/dead-code/basic.stderr
new file mode 100644
index 000000000..7d068cead
--- /dev/null
+++ b/tests/ui/lint/dead-code/basic.stderr
@@ -0,0 +1,14 @@
+error: function `foo` is never used
+ --> $DIR/basic.rs:4:4
+ |
+LL | fn foo() {
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/basic.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/closure-bang.rs b/tests/ui/lint/dead-code/closure-bang.rs
new file mode 100644
index 000000000..8e8636b11
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/const-and-self.rs b/tests/ui/lint/dead-code/const-and-self.rs
new file mode 100644
index 000000000..5c96e4d0e
--- /dev/null
+++ b/tests/ui/lint/dead-code/const-and-self.rs
@@ -0,0 +1,54 @@
+// check-pass
+
+#![warn(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!()
+ }
+}
+
+enum E {
+ A,
+ B, //~ WARN variants `B` and `C` are never constructed
+ C,
+}
+
+type F = E;
+
+impl E {
+ fn check(&self) -> bool {
+ match self {
+ Self::A => true,
+ Self::B => false,
+ F::C => false,
+ }
+ }
+}
+
+fn main() {
+ let s = [0,1,2,3];
+ s.doit();
+ X::foo();
+ E::A.check();
+}
diff --git a/tests/ui/lint/dead-code/const-and-self.stderr b/tests/ui/lint/dead-code/const-and-self.stderr
new file mode 100644
index 000000000..9d1d7d6ec
--- /dev/null
+++ b/tests/ui/lint/dead-code/const-and-self.stderr
@@ -0,0 +1,19 @@
+warning: variants `B` and `C` are never constructed
+ --> $DIR/const-and-self.rs:33:5
+ |
+LL | enum E {
+ | - variants in this enum
+LL | A,
+LL | B,
+ | ^
+LL | C,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/const-and-self.rs:3:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/dead-code/empty-unused-enum.rs b/tests/ui/lint/dead-code/empty-unused-enum.rs
new file mode 100644
index 000000000..864501e94
--- /dev/null
+++ b/tests/ui/lint/dead-code/empty-unused-enum.rs
@@ -0,0 +1,5 @@
+#![deny(unused)]
+
+enum E {} //~ ERROR enum `E` is never used
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/empty-unused-enum.stderr b/tests/ui/lint/dead-code/empty-unused-enum.stderr
new file mode 100644
index 000000000..6391f0941
--- /dev/null
+++ b/tests/ui/lint/dead-code/empty-unused-enum.stderr
@@ -0,0 +1,15 @@
+error: enum `E` is never used
+ --> $DIR/empty-unused-enum.rs:3:6
+ |
+LL | enum E {}
+ | ^
+ |
+note: the lint level is 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/tests/ui/lint/dead-code/empty-unused-public-enum.rs b/tests/ui/lint/dead-code/empty-unused-public-enum.rs
new file mode 100644
index 000000000..15b04496b
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/enum-variants.rs b/tests/ui/lint/dead-code/enum-variants.rs
new file mode 100644
index 000000000..91c97232e
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/impl-trait.rs b/tests/ui/lint/dead-code/impl-trait.rs
new file mode 100644
index 000000000..757b8f83e
--- /dev/null
+++ b/tests/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 `Unused` is never used
+
+fn foo() -> impl Trait<Type = Used> {}
+
+fn main() {
+ foo();
+}
diff --git a/tests/ui/lint/dead-code/impl-trait.stderr b/tests/ui/lint/dead-code/impl-trait.stderr
new file mode 100644
index 000000000..e35e13a9e
--- /dev/null
+++ b/tests/ui/lint/dead-code/impl-trait.stderr
@@ -0,0 +1,14 @@
+error: type alias `Unused` is never used
+ --> $DIR/impl-trait.rs:12:6
+ |
+LL | type Unused = ();
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/impl-trait.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/issue-68408-false-positive.rs b/tests/ui/lint/dead-code/issue-68408-false-positive.rs
new file mode 100644
index 000000000..7ee6b5d72
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-68408-false-positive.rs
@@ -0,0 +1,22 @@
+// check-pass
+
+// Make sure we don't have any false positives here.
+
+#![deny(dead_code)]
+
+enum X {
+ A { _a: () },
+ B { _b: () },
+}
+impl X {
+ fn a() -> X {
+ X::A { _a: () }
+ }
+ fn b() -> Self {
+ Self::B { _b: () }
+ }
+}
+
+fn main() {
+ let (_, _) = (X::a(), X::b());
+}
diff --git a/tests/ui/lint/dead-code/issue-85071-2.rs b/tests/ui/lint/dead-code/issue-85071-2.rs
new file mode 100644
index 000000000..f0639931c
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071-2.rs
@@ -0,0 +1,22 @@
+// A slight variation of issue-85071.rs. Here, a method is called instead
+// of a function, and the warning is about an unreachable definition
+// instead of an unreachable expression.
+
+// check-pass
+
+#![warn(unused_variables,unreachable_code)]
+
+enum Foo {}
+
+struct S;
+impl S {
+ fn f(&self) -> Foo {todo!()}
+}
+
+fn main() {
+ let s = S;
+ let x = s.f();
+ //~^ WARNING: unused variable: `x`
+ let _y = x;
+ //~^ WARNING: unreachable definition
+}
diff --git a/tests/ui/lint/dead-code/issue-85071-2.stderr b/tests/ui/lint/dead-code/issue-85071-2.stderr
new file mode 100644
index 000000000..5e963183d
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071-2.stderr
@@ -0,0 +1,34 @@
+warning: unreachable definition
+ --> $DIR/issue-85071-2.rs:20:9
+ |
+LL | let x = s.f();
+ | ----- any code following this expression is unreachable
+LL |
+LL | let _y = x;
+ | ^^ unreachable definition
+ |
+note: this expression has type `Foo`, which is uninhabited
+ --> $DIR/issue-85071-2.rs:18:13
+ |
+LL | let x = s.f();
+ | ^^^^^
+note: the lint level is defined here
+ --> $DIR/issue-85071-2.rs:7:26
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: unused variable: `x`
+ --> $DIR/issue-85071-2.rs:18:9
+ |
+LL | let x = s.f();
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85071-2.rs:7:9
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/issue-85071.rs b/tests/ui/lint/dead-code/issue-85071.rs
new file mode 100644
index 000000000..d6969321c
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071.rs
@@ -0,0 +1,19 @@
+// Checks that an unreachable code warning is emitted when an expression is
+// preceded by an expression with an uninhabited type. Previously, the
+// variable liveness analysis was "smarter" than the reachability analysis
+// in this regard, which led to confusing "unused variable" warnings
+// without an accompanying explanatory "unreachable expression" warning.
+
+// check-pass
+
+#![warn(unused_variables,unreachable_code)]
+
+enum Foo {}
+fn f() -> Foo {todo!()}
+
+fn main() {
+ let x = f();
+ //~^ WARNING: unused variable: `x`
+ let _ = x;
+ //~^ WARNING: unreachable expression
+}
diff --git a/tests/ui/lint/dead-code/issue-85071.stderr b/tests/ui/lint/dead-code/issue-85071.stderr
new file mode 100644
index 000000000..721fb8148
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85071.stderr
@@ -0,0 +1,34 @@
+warning: unreachable expression
+ --> $DIR/issue-85071.rs:17:13
+ |
+LL | let x = f();
+ | --- any code following this expression is unreachable
+LL |
+LL | let _ = x;
+ | ^ unreachable expression
+ |
+note: this expression has type `Foo`, which is uninhabited
+ --> $DIR/issue-85071.rs:15:13
+ |
+LL | let x = f();
+ | ^^^
+note: the lint level is defined here
+ --> $DIR/issue-85071.rs:9:26
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: unused variable: `x`
+ --> $DIR/issue-85071.rs:15:9
+ |
+LL | let x = f();
+ | ^ help: if this is intentional, prefix it with an underscore: `_x`
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85071.rs:9:9
+ |
+LL | #![warn(unused_variables,unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/issue-85255.rs b/tests/ui/lint/dead-code/issue-85255.rs
new file mode 100644
index 000000000..043f68137
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85255.rs
@@ -0,0 +1,50 @@
+// Unused `pub` fields in non-`pub` structs should also trigger dead code warnings.
+// check-pass
+
+#![warn(dead_code)]
+
+struct Foo {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+struct Bar;
+
+impl Bar {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+pub(crate) struct Foo1 {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+pub(crate) struct Bar1;
+
+impl Bar1 {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+pub(crate) struct Foo2 {
+ a: i32, //~ WARNING: fields `a` and `b` are never read
+ pub b: i32,
+}
+
+pub(crate) struct Bar2;
+
+impl Bar2 {
+ fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used
+ pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used
+}
+
+
+fn main() {
+ let _ = Foo { a: 1, b: 2 };
+ let _ = Bar;
+ let _ = Foo1 { a: 1, b: 2 };
+ let _ = Bar1;
+ let _ = Foo2 { a: 1, b: 2 };
+ let _ = Bar2;
+}
diff --git a/tests/ui/lint/dead-code/issue-85255.stderr b/tests/ui/lint/dead-code/issue-85255.stderr
new file mode 100644
index 000000000..3497b952f
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-85255.stderr
@@ -0,0 +1,74 @@
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:7:5
+ |
+LL | struct Foo {
+ | --- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/issue-85255.rs:4:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:19:5
+ |
+LL | pub(crate) struct Foo1 {
+ | ---- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+
+warning: fields `a` and `b` are never read
+ --> $DIR/issue-85255.rs:31:5
+ |
+LL | pub(crate) struct Foo2 {
+ | ---- fields in this struct
+LL | a: i32,
+ | ^
+LL | pub b: i32,
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:14:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:15:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:26:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:27:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: associated function `a` is never used
+ --> $DIR/issue-85255.rs:38:8
+ |
+LL | fn a(&self) -> i32 { 5 }
+ | ^
+
+warning: associated function `b` is never used
+ --> $DIR/issue-85255.rs:39:12
+ |
+LL | pub fn b(&self) -> i32 { 6 }
+ | ^
+
+warning: 9 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/leading-underscore.rs b/tests/ui/lint/dead-code/leading-underscore.rs
new file mode 100644
index 000000000..d3582961b
--- /dev/null
+++ b/tests/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 "C" {
+ #[link_name = "abort"]
+ fn _abort() -> !;
+}
+
+pub fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-1.rs b/tests/ui/lint/dead-code/lint-dead-code-1.rs
new file mode 100644
index 000000000..8f5a4c41e
--- /dev/null
+++ b/tests/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 `Bar` is never constructed
+}
+
+mod foo2 {
+ pub struct Bar2;
+}
+
+pub static pub_static: isize = 0;
+static priv_static: isize = 0; //~ ERROR: static `priv_static` 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 `priv_const` 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 `PrivStruct` 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 `priv_enum` is never used
+enum used_enum {
+ foo3,
+ bar3 //~ ERROR variant `bar3` 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 `priv_fn` is never used
+ let unused_struct = PrivStruct;
+}
+fn used_fn() {}
+
+fn foo() { //~ ERROR: function `foo` is never used
+ bar();
+ let unused_enum = priv_enum::foo2;
+}
+
+fn bar() { //~ ERROR: function `bar` is never used
+ foo();
+}
+
+fn baz() -> impl Copy { //~ ERROR: function `baz` 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/tests/ui/lint/dead-code/lint-dead-code-1.stderr b/tests/ui/lint/dead-code/lint-dead-code-1.stderr
new file mode 100644
index 000000000..eb728b5b9
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-1.stderr
@@ -0,0 +1,71 @@
+error: static `priv_static` is never used
+ --> $DIR/lint-dead-code-1.rs:20:8
+ |
+LL | static priv_static: isize = 0;
+ | ^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-1.rs:5:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: constant `priv_const` is never used
+ --> $DIR/lint-dead-code-1.rs:27:7
+ |
+LL | const priv_const: isize = 0;
+ | ^^^^^^^^^^
+
+error: struct `PrivStruct` is never constructed
+ --> $DIR/lint-dead-code-1.rs:35:8
+ |
+LL | struct PrivStruct;
+ | ^^^^^^^^^^
+
+error: enum `priv_enum` is never used
+ --> $DIR/lint-dead-code-1.rs:64:6
+ |
+LL | enum priv_enum { foo2, bar2 }
+ | ^^^^^^^^^
+
+error: variant `bar3` is never constructed
+ --> $DIR/lint-dead-code-1.rs:67:5
+ |
+LL | enum used_enum {
+ | --------- variant in this enum
+LL | foo3,
+LL | bar3
+ | ^^^^
+
+error: function `priv_fn` is never used
+ --> $DIR/lint-dead-code-1.rs:88:4
+ |
+LL | fn priv_fn() {
+ | ^^^^^^^
+
+error: function `foo` is never used
+ --> $DIR/lint-dead-code-1.rs:93:4
+ |
+LL | fn foo() {
+ | ^^^
+
+error: function `bar` is never used
+ --> $DIR/lint-dead-code-1.rs:98:4
+ |
+LL | fn bar() {
+ | ^^^
+
+error: function `baz` is never used
+ --> $DIR/lint-dead-code-1.rs:102:4
+ |
+LL | fn baz() -> impl Copy {
+ | ^^^
+
+error: struct `Bar` is never constructed
+ --> $DIR/lint-dead-code-1.rs:12:16
+ |
+LL | pub struct Bar;
+ | ^^^
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-2.rs b/tests/ui/lint/dead-code/lint-dead-code-2.rs
new file mode 100644
index 000000000..6bfa4d96f
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-2.rs
@@ -0,0 +1,41 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+#![feature(rustc_attrs, 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 `dead_fn` is never used
+
+#[rustc_main]
+fn dead_fn2() {} //~ ERROR: function `dead_fn2` 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 `main` is never used
+ dead_fn();
+ dead_fn2();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-2.stderr b/tests/ui/lint/dead-code/lint-dead-code-2.stderr
new file mode 100644
index 000000000..85af553c9
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-2.stderr
@@ -0,0 +1,26 @@
+error: function `dead_fn` is never used
+ --> $DIR/lint-dead-code-2.rs:22:4
+ |
+LL | fn dead_fn() {}
+ | ^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-2.rs:2:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `dead_fn2` is never used
+ --> $DIR/lint-dead-code-2.rs:25:4
+ |
+LL | fn dead_fn2() {}
+ | ^^^^^^^^
+
+error: function `main` is never used
+ --> $DIR/lint-dead-code-2.rs:38:4
+ |
+LL | fn main() {
+ | ^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.rs b/tests/ui/lint/dead-code/lint-dead-code-3.rs
new file mode 100644
index 000000000..293fcdbc5
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.rs
@@ -0,0 +1,90 @@
+#![allow(unused_variables)]
+#![allow(non_camel_case_types)]
+#![allow(clashing_extern_declarations)]
+#![deny(dead_code)]
+
+#![crate_type="lib"]
+
+
+pub use extern_foo as x;
+extern "C" {
+ pub fn extern_foo();
+}
+
+struct Foo; //~ ERROR: struct `Foo` is never constructed
+impl Foo {
+ fn foo(&self) { //~ ERROR: associated function `foo` is never used
+ bar()
+ }
+}
+
+fn bar() { //~ ERROR: function `bar` 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 "C" {
+ 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 `c_void` is never used
+extern "C" {
+ fn free(p: *const c_void); //~ ERROR: function `free` is never used
+}
+
+// Check provided method
+mod inner {
+ pub trait Trait {
+ fn f(&self) { f(); }
+ }
+
+ impl Trait for isize {}
+
+ fn f() {}
+}
+
+fn anon_const() -> [(); {
+ fn blah() {} //~ ERROR: function `blah` is never used
+ 1
+}] {
+ [(); {
+ fn blah() {} //~ ERROR: function `blah` is never used
+ 1
+ }]
+}
+
+pub fn foo() {
+ let a: &dyn inner::Trait = &1_isize;
+ a.f();
+ anon_const();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.stderr b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
new file mode 100644
index 000000000..26fc13bae
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-3.stderr
@@ -0,0 +1,50 @@
+error: struct `Foo` is never constructed
+ --> $DIR/lint-dead-code-3.rs:14:8
+ |
+LL | struct Foo;
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-3.rs:4:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `bar` is never used
+ --> $DIR/lint-dead-code-3.rs:21:4
+ |
+LL | fn bar() {
+ | ^^^
+
+error: enum `c_void` is never used
+ --> $DIR/lint-dead-code-3.rs:60:6
+ |
+LL | enum c_void {}
+ | ^^^^^^
+
+error: function `blah` is never used
+ --> $DIR/lint-dead-code-3.rs:77:8
+ |
+LL | fn blah() {}
+ | ^^^^
+
+error: function `blah` is never used
+ --> $DIR/lint-dead-code-3.rs:81:12
+ |
+LL | fn blah() {}
+ | ^^^^
+
+error: associated function `foo` is never used
+ --> $DIR/lint-dead-code-3.rs:16:8
+ |
+LL | fn foo(&self) {
+ | ^^^
+
+error: function `free` is never used
+ --> $DIR/lint-dead-code-3.rs:62:8
+ |
+LL | fn free(p: *const c_void);
+ | ^^^^
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-4.rs b/tests/ui/lint/dead-code/lint-dead-code-4.rs
new file mode 100644
index 000000000..0fc6c6156
--- /dev/null
+++ b/tests/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 `b` is never read
+}
+
+fn field_read(f: Foo) -> usize {
+ f.x.pow(2)
+}
+
+enum XYZ {
+ X, //~ ERROR variants `X` and `Y` are never constructed
+ Y {
+ a: String,
+ b: i32,
+ c: i32,
+ },
+ Z
+}
+
+enum ABC { //~ ERROR enum `ABC` is never used
+ A,
+ B {
+ a: String,
+ b: i32,
+ c: i32,
+ },
+ C
+}
+
+// ensure struct variants get warning for their fields
+enum IJK {
+ I, //~ ERROR variants `I` and `K` are never constructed
+ J {
+ a: String,
+ b: i32, //~ ERROR fields `b` and `c` are never read
+ c: i32,
+ },
+ K
+
+}
+
+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: fields `x` and `c` are never read
+ b: bool,
+ c: bool,
+ _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/tests/ui/lint/dead-code/lint-dead-code-4.stderr b/tests/ui/lint/dead-code/lint-dead-code-4.stderr
new file mode 100644
index 000000000..668c1dacf
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-4.stderr
@@ -0,0 +1,66 @@
+error: field `b` is never read
+ --> $DIR/lint-dead-code-4.rs:7:5
+ |
+LL | struct Foo {
+ | --- field in this struct
+LL | x: usize,
+LL | b: bool,
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-4.rs:3:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: variants `X` and `Y` are never constructed
+ --> $DIR/lint-dead-code-4.rs:15:5
+ |
+LL | enum XYZ {
+ | --- variants in this enum
+LL | X,
+ | ^
+LL | Y {
+ | ^
+
+error: enum `ABC` is never used
+ --> $DIR/lint-dead-code-4.rs:24:6
+ |
+LL | enum ABC {
+ | ^^^
+
+error: fields `b` and `c` are never read
+ --> $DIR/lint-dead-code-4.rs:39:9
+ |
+LL | J {
+ | - fields in this variant
+LL | a: String,
+LL | b: i32,
+ | ^
+LL | c: i32,
+ | ^
+
+error: variants `I` and `K` are never constructed
+ --> $DIR/lint-dead-code-4.rs:36:5
+ |
+LL | enum IJK {
+ | --- variants in this enum
+LL | I,
+ | ^
+...
+LL | K
+ | ^
+
+error: fields `x` and `c` are never read
+ --> $DIR/lint-dead-code-4.rs:61:5
+ |
+LL | struct Bar {
+ | --- fields in this struct
+LL | x: usize,
+ | ^
+LL | b: bool,
+LL | c: bool,
+ | ^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-5.rs b/tests/ui/lint/dead-code/lint-dead-code-5.rs
new file mode 100644
index 000000000..ed90fb464
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-5.rs
@@ -0,0 +1,50 @@
+#![allow(unused_variables)]
+#![deny(dead_code)]
+
+enum Enum1 {
+ Variant1(isize),
+ Variant2 //~ ERROR: variant `Variant2` is never constructed
+}
+
+enum Enum2 {
+ Variant3(bool),
+ #[allow(dead_code)]
+ Variant4(isize),
+ Variant5 { _x: isize }, //~ ERROR: variants `Variant5` and `Variant6` are never constructed
+ Variant6(isize),
+ _Variant7,
+ Variant8 { _field: bool },
+ Variant9,
+ Variant10(usize)
+}
+
+impl Enum2 {
+ fn new_variant8() -> Enum2 {
+ Self::Variant8 { _field: true }
+ }
+
+ fn new_variant9() -> Enum2 {
+ Self::Variant9
+ }
+
+ fn new_variant10() -> Enum2 {
+ Self::Variant10(10)
+ }
+}
+
+enum Enum3 { //~ ERROR: enum `Enum3` is never used
+ Variant8,
+ Variant9
+}
+
+fn main() {
+ let v = Enum1::Variant1(1);
+ match v {
+ Enum1::Variant1(_) => (),
+ Enum1::Variant2 => ()
+ }
+ let x = Enum2::Variant3(true);
+ let _ = Enum2::new_variant8();
+ let _ = Enum2::new_variant9();
+ let _ = Enum2::new_variant10();
+}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-5.stderr b/tests/ui/lint/dead-code/lint-dead-code-5.stderr
new file mode 100644
index 000000000..eaf43e453
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-5.stderr
@@ -0,0 +1,34 @@
+error: variant `Variant2` is never constructed
+ --> $DIR/lint-dead-code-5.rs:6:5
+ |
+LL | enum Enum1 {
+ | ----- variant in this enum
+LL | Variant1(isize),
+LL | Variant2
+ | ^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-5.rs:2:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: variants `Variant5` and `Variant6` are never constructed
+ --> $DIR/lint-dead-code-5.rs:13:5
+ |
+LL | enum Enum2 {
+ | ----- variants in this enum
+...
+LL | Variant5 { _x: isize },
+ | ^^^^^^^^
+LL | Variant6(isize),
+ | ^^^^^^^^
+
+error: enum `Enum3` is never used
+ --> $DIR/lint-dead-code-5.rs:35:6
+ |
+LL | enum Enum3 {
+ | ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.rs b/tests/ui/lint/dead-code/lint-dead-code-6.rs
new file mode 100644
index 000000000..e3074acf1
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.rs
@@ -0,0 +1,20 @@
+#![deny(dead_code)]
+
+struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
+impl UnusedStruct {
+ fn unused_impl_fn_1() { //~ ERROR associated function `unused_impl_fn_1` is never used
+ println!("blah");
+ }
+
+ fn unused_impl_fn_2(var: i32) { //~ ERROR associated function `unused_impl_fn_2` is never used
+ println!("foo {}", var);
+ }
+
+ fn unused_impl_fn_3( //~ ERROR associated function `unused_impl_fn_3` is never used
+ var: i32,
+ ) {
+ println!("bar {}", var);
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/lint-dead-code-6.stderr b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
new file mode 100644
index 000000000..f9d83308a
--- /dev/null
+++ b/tests/ui/lint/dead-code/lint-dead-code-6.stderr
@@ -0,0 +1,32 @@
+error: struct `UnusedStruct` is never constructed
+ --> $DIR/lint-dead-code-6.rs:3:8
+ |
+LL | struct UnusedStruct;
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/lint-dead-code-6.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: associated function `unused_impl_fn_1` is never used
+ --> $DIR/lint-dead-code-6.rs:5:8
+ |
+LL | fn unused_impl_fn_1() {
+ | ^^^^^^^^^^^^^^^^
+
+error: associated function `unused_impl_fn_2` is never used
+ --> $DIR/lint-dead-code-6.rs:9:8
+ |
+LL | fn unused_impl_fn_2(var: i32) {
+ | ^^^^^^^^^^^^^^^^
+
+error: associated function `unused_impl_fn_3` is never used
+ --> $DIR/lint-dead-code-6.rs:13:8
+ |
+LL | fn unused_impl_fn_3(
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
new file mode 100644
index 000000000..2003e1e29
--- /dev/null
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
@@ -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,
+ };
+}
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
new file mode 100644
index 000000000..0e5c78a71
--- /dev/null
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
@@ -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
+
diff --git a/tests/ui/lint/dead-code/newline-span.rs b/tests/ui/lint/dead-code/newline-span.rs
new file mode 100644
index 000000000..209c3cd93
--- /dev/null
+++ b/tests/ui/lint/dead-code/newline-span.rs
@@ -0,0 +1,19 @@
+#![deny(dead_code)]
+
+fn unused() { //~ error: function `unused` is never used
+ println!("blah");
+}
+
+fn unused2(var: i32) { //~ error: function `unused2` is never used
+ println!("foo {}", var);
+}
+
+fn unused3( //~ error: function `unused3` is never used
+ var: i32,
+) {
+ println!("bar {}", var);
+}
+
+fn main() {
+ println!("Hello world!");
+}
diff --git a/tests/ui/lint/dead-code/newline-span.stderr b/tests/ui/lint/dead-code/newline-span.stderr
new file mode 100644
index 000000000..4eeadccc8
--- /dev/null
+++ b/tests/ui/lint/dead-code/newline-span.stderr
@@ -0,0 +1,26 @@
+error: function `unused` is never used
+ --> $DIR/newline-span.rs:3:4
+ |
+LL | fn unused() {
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/newline-span.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: function `unused2` is never used
+ --> $DIR/newline-span.rs:7:4
+ |
+LL | fn unused2(var: i32) {
+ | ^^^^^^^
+
+error: function `unused3` is never used
+ --> $DIR/newline-span.rs:11:4
+ |
+LL | fn unused3(
+ | ^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/self-assign.rs b/tests/ui/lint/dead-code/self-assign.rs
new file mode 100644
index 000000000..ea7ce98d8
--- /dev/null
+++ b/tests/ui/lint/dead-code/self-assign.rs
@@ -0,0 +1,52 @@
+// Test that dead code warnings are issued for superfluous assignments of
+// fields or variables to themselves (issue #75356).
+
+// ignore-test FIXME(81658, 83171)
+
+// check-pass
+#![allow(unused_assignments)]
+#![warn(dead_code)]
+
+fn main() {
+ let mut x = 0;
+ x = x;
+ //~^ WARNING: useless assignment of variable of type `i32` to itself
+
+ x = (x);
+ //~^ WARNING: useless assignment of variable of type `i32` to itself
+
+ x = {x};
+ // block expressions don't count as self-assignments
+
+
+ struct S<'a> { f: &'a str }
+ let mut s = S { f: "abc" };
+ s = s;
+ //~^ WARNING: useless assignment of variable of type `S` to itself
+
+ s.f = s.f;
+ //~^ WARNING: useless assignment of field of type `&str` to itself
+
+
+ struct N0 { x: Box<i32> }
+ struct N1 { n: N0 }
+ struct N2(N1);
+ struct N3 { n: N2 };
+ let mut n3 = N3 { n: N2(N1 { n: N0 { x: Box::new(42) } }) };
+ n3.n.0.n.x = n3.n.0.n.x;
+ //~^ WARNING: useless assignment of field of type `Box<i32>` to itself
+
+ let mut t = (1, ((2, 3, (4, 5)),));
+ t.1.0.2.1 = t.1.0.2.1;
+ //~^ WARNING: useless assignment of field of type `i32` to itself
+
+
+ let mut y = 0;
+ macro_rules! assign_to_y {
+ ($cur:expr) => {{
+ y = $cur;
+ }};
+ }
+ assign_to_y!(y);
+ // self-assignments in macro expansions are not reported either
+}
diff --git a/tests/ui/lint/dead-code/self-assign.stderr b/tests/ui/lint/dead-code/self-assign.stderr
new file mode 100644
index 000000000..bb79c0ec7
--- /dev/null
+++ b/tests/ui/lint/dead-code/self-assign.stderr
@@ -0,0 +1,44 @@
+warning: useless assignment of variable of type `i32` to itself
+ --> $DIR/self-assign.rs:10:5
+ |
+LL | x = x;
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/self-assign.rs:6:9
+ |
+LL | #![warn(dead_code)]
+ | ^^^^^^^^^
+
+warning: useless assignment of variable of type `i32` to itself
+ --> $DIR/self-assign.rs:13:5
+ |
+LL | x = (x);
+ | ^^^^^^^
+
+warning: useless assignment of variable of type `S` to itself
+ --> $DIR/self-assign.rs:22:5
+ |
+LL | s = s;
+ | ^^^^^
+
+warning: useless assignment of field of type `&str` to itself
+ --> $DIR/self-assign.rs:25:5
+ |
+LL | s.f = s.f;
+ | ^^^^^^^^^
+
+warning: useless assignment of field of type `Box<i32>` to itself
+ --> $DIR/self-assign.rs:34:5
+ |
+LL | n3.n.0.n.x = n3.n.0.n.x;
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: useless assignment of field of type `i32` to itself
+ --> $DIR/self-assign.rs:38:5
+ |
+LL | t.1.0.2.1 = t.1.0.2.1;
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+warning: 6 warnings emitted
+
diff --git a/tests/ui/lint/dead-code/trait-impl.rs b/tests/ui/lint/dead-code/trait-impl.rs
new file mode 100644
index 000000000..92e389a93
--- /dev/null
+++ b/tests/ui/lint/dead-code/trait-impl.rs
@@ -0,0 +1,19 @@
+// check-pass
+#![deny(dead_code)]
+
+enum Foo {
+ Bar,
+}
+
+fn main() {
+ let p = [0; 0];
+ p.bar();
+}
+
+trait Bar {
+ fn bar(&self) -> usize {
+ 3
+ }
+}
+
+impl Bar for [u32; Foo::Bar as usize] {}
diff --git a/tests/ui/lint/dead-code/tuple-struct-field.rs b/tests/ui/lint/dead-code/tuple-struct-field.rs
new file mode 100644
index 000000000..14fb30be9
--- /dev/null
+++ b/tests/ui/lint/dead-code/tuple-struct-field.rs
@@ -0,0 +1,37 @@
+#![deny(unused_tuple_struct_fields)]
+//~^ NOTE: the lint level is defined here
+
+use std::marker::PhantomData;
+
+const LEN: usize = 4;
+
+struct SingleUnused(i32, [u8; LEN], String);
+//~^ ERROR: field `1` is never read
+//~| NOTE: field in this struct
+//~| HELP: consider changing the field to be of unit type
+
+struct MultipleUnused(i32, f32, String, u8);
+//~^ ERROR: fields `0`, `1`, `2`, and `3` are never read
+//~| NOTE: fields in this struct
+//~| HELP: consider changing the fields to be of unit type
+
+struct GoodUnit(());
+
+struct GoodPhantom(PhantomData<i32>);
+
+struct Void;
+struct GoodVoid(Void);
+
+fn main() {
+ let w = SingleUnused(42, [0, 1, 2, 3], "abc".to_string());
+ let _ = w.0;
+ let _ = w.2;
+
+ let m = MultipleUnused(42, 3.14, "def".to_string(), 4u8);
+
+ let gu = GoodUnit(());
+ let gp = GoodPhantom(PhantomData);
+ let gv = GoodVoid(Void);
+
+ let _ = (gu, gp, gv, m);
+}
diff --git a/tests/ui/lint/dead-code/tuple-struct-field.stderr b/tests/ui/lint/dead-code/tuple-struct-field.stderr
new file mode 100644
index 000000000..b8ad5cbe4
--- /dev/null
+++ b/tests/ui/lint/dead-code/tuple-struct-field.stderr
@@ -0,0 +1,33 @@
+error: field `1` is never read
+ --> $DIR/tuple-struct-field.rs:8:26
+ |
+LL | struct SingleUnused(i32, [u8; LEN], String);
+ | ------------ ^^^^^^^^^
+ | |
+ | field in this struct
+ |
+note: the lint level is defined here
+ --> $DIR/tuple-struct-field.rs:1:9
+ |
+LL | #![deny(unused_tuple_struct_fields)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
+ |
+LL | struct SingleUnused(i32, (), String);
+ | ~~
+
+error: fields `0`, `1`, `2`, and `3` are never read
+ --> $DIR/tuple-struct-field.rs:13:23
+ |
+LL | struct MultipleUnused(i32, f32, String, u8);
+ | -------------- ^^^ ^^^ ^^^^^^ ^^
+ | |
+ | fields in this struct
+ |
+help: consider changing the fields to be of unit type to suppress this warning while preserving the field numbering, or remove the fields
+ |
+LL | struct MultipleUnused((), (), (), ());
+ | ~~ ~~ ~~ ~~
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lint/dead-code/type-alias.rs b/tests/ui/lint/dead-code/type-alias.rs
new file mode 100644
index 000000000..35a7f125d
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-alias.rs
@@ -0,0 +1,10 @@
+#![deny(dead_code)]
+
+type Used = u8;
+type Unused = u8; //~ ERROR type alias `Unused` is never used
+
+fn id(x: Used) -> Used { x }
+
+fn main() {
+ id(0);
+}
diff --git a/tests/ui/lint/dead-code/type-alias.stderr b/tests/ui/lint/dead-code/type-alias.stderr
new file mode 100644
index 000000000..446447d97
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-alias.stderr
@@ -0,0 +1,14 @@
+error: type alias `Unused` is never used
+ --> $DIR/type-alias.rs:4:6
+ |
+LL | type Unused = u8;
+ | ^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/type-alias.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/type-in-foreign.rs b/tests/ui/lint/dead-code/type-in-foreign.rs
new file mode 100644
index 000000000..b6c593f31
--- /dev/null
+++ b/tests/ui/lint/dead-code/type-in-foreign.rs
@@ -0,0 +1,19 @@
+// Verify that we do not warn on types that are used by foreign functions.
+// check-pass
+#![deny(dead_code)]
+
+#[repr(C)]
+struct Type(u8);
+
+#[repr(C)]
+struct Param(u8);
+
+extern "C" {
+ #[allow(dead_code)]
+ fn hey(t: Param);
+
+ #[allow(dead_code)]
+ static much: Type;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-enum.rs b/tests/ui/lint/dead-code/unused-enum.rs
new file mode 100644
index 000000000..20df3e1de
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-enum.rs
@@ -0,0 +1,12 @@
+#![deny(unused)]
+
+struct F; //~ ERROR struct `F` is never constructed
+struct B; //~ ERROR struct `B` is never constructed
+
+enum E {
+ //~^ ERROR enum `E` is never used
+ Foo(F),
+ Bar(B),
+}
+
+fn main() {}
diff --git a/tests/ui/lint/dead-code/unused-enum.stderr b/tests/ui/lint/dead-code/unused-enum.stderr
new file mode 100644
index 000000000..d2602dbb3
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-enum.stderr
@@ -0,0 +1,27 @@
+error: struct `F` is never constructed
+ --> $DIR/unused-enum.rs:3:8
+ |
+LL | struct F;
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/unused-enum.rs:1:9
+ |
+LL | #![deny(unused)]
+ | ^^^^^^
+ = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: struct `B` is never constructed
+ --> $DIR/unused-enum.rs:4:8
+ |
+LL | struct B;
+ | ^
+
+error: enum `E` is never used
+ --> $DIR/unused-enum.rs:6:6
+ |
+LL | enum E {
+ | ^
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lint/dead-code/unused-struct-variant.rs b/tests/ui/lint/dead-code/unused-struct-variant.rs
new file mode 100644
index 000000000..a914e0c33
--- /dev/null
+++ b/tests/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 `Bar` is never constructed
+}
+
+fn main() {
+ let _ = E::Foo(F);
+}
diff --git a/tests/ui/lint/dead-code/unused-struct-variant.stderr b/tests/ui/lint/dead-code/unused-struct-variant.stderr
new file mode 100644
index 000000000..d26dd3aff
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-struct-variant.stderr
@@ -0,0 +1,18 @@
+error: variant `Bar` is never constructed
+ --> $DIR/unused-struct-variant.rs:8:5
+ |
+LL | enum E {
+ | - variant in this enum
+LL | Foo(F),
+LL | Bar(B),
+ | ^^^
+ |
+note: the lint level is 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/tests/ui/lint/dead-code/unused-variant-pub.rs b/tests/ui/lint/dead-code/unused-variant-pub.rs
new file mode 100644
index 000000000..3a9061340
--- /dev/null
+++ b/tests/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/tests/ui/lint/dead-code/unused-variant.rs b/tests/ui/lint/dead-code/unused-variant.rs
new file mode 100644
index 000000000..82108fa9c
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-variant.rs
@@ -0,0 +1,12 @@
+#![deny(dead_code)]
+
+#[derive(Clone)]
+enum Enum {
+ Variant1, //~ ERROR: variant `Variant1` is never constructed
+ Variant2,
+}
+
+fn main() {
+ let e = Enum::Variant2;
+ e.clone();
+}
diff --git a/tests/ui/lint/dead-code/unused-variant.stderr b/tests/ui/lint/dead-code/unused-variant.stderr
new file mode 100644
index 000000000..6029bf268
--- /dev/null
+++ b/tests/ui/lint/dead-code/unused-variant.stderr
@@ -0,0 +1,17 @@
+error: variant `Variant1` is never constructed
+ --> $DIR/unused-variant.rs:5:5
+ |
+LL | enum Enum {
+ | ---- variant in this enum
+LL | Variant1,
+ | ^^^^^^^^
+ |
+ = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
+note: the lint level is defined here
+ --> $DIR/unused-variant.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/with-core-crate.rs b/tests/ui/lint/dead-code/with-core-crate.rs
new file mode 100644
index 000000000..0a94b528f
--- /dev/null
+++ b/tests/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 `foo` 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/tests/ui/lint/dead-code/with-core-crate.stderr b/tests/ui/lint/dead-code/with-core-crate.stderr
new file mode 100644
index 000000000..7adcf8848
--- /dev/null
+++ b/tests/ui/lint/dead-code/with-core-crate.stderr
@@ -0,0 +1,14 @@
+error: function `foo` is never used
+ --> $DIR/with-core-crate.rs:7:4
+ |
+LL | fn foo() {
+ | ^^^
+ |
+note: the lint level is defined here
+ --> $DIR/with-core-crate.rs:1:9
+ |
+LL | #![deny(dead_code)]
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lint/dead-code/with-impl.rs b/tests/ui/lint/dead-code/with-impl.rs
new file mode 100644
index 000000000..812fcdd09
--- /dev/null
+++ b/tests/ui/lint/dead-code/with-impl.rs
@@ -0,0 +1,17 @@
+// run-pass
+
+#![deny(dead_code)]
+
+pub struct GenericFoo<T>(#[allow(unused_tuple_struct_fields)] T);
+
+type Foo = GenericFoo<u32>;
+
+impl Foo {
+ fn bar(self) -> u8 {
+ 0
+ }
+}
+
+fn main() {
+ println!("{}", GenericFoo(0).bar());
+}