summaryrefslogtreecommitdiffstats
path: root/src/test/ui/reachable
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/reachable-unnameable-type-alias.rs16
-rw-r--r--src/test/ui/reachable/README.md7
-rw-r--r--src/test/ui/reachable/auxiliary/unreachable_variant.rs5
-rw-r--r--src/test/ui/reachable/expr_add.rs18
-rw-r--r--src/test/ui/reachable/expr_add.stderr17
-rw-r--r--src/test/ui/reachable/expr_again.rs11
-rw-r--r--src/test/ui/reachable/expr_again.stderr17
-rw-r--r--src/test/ui/reachable/expr_andand.rs13
-rw-r--r--src/test/ui/reachable/expr_array.rs17
-rw-r--r--src/test/ui/reachable/expr_array.stderr25
-rw-r--r--src/test/ui/reachable/expr_assign.rs29
-rw-r--r--src/test/ui/reachable/expr_assign.stderr33
-rw-r--r--src/test/ui/reachable/expr_block.rs31
-rw-r--r--src/test/ui/reachable/expr_block.stderr26
-rw-r--r--src/test/ui/reachable/expr_box.rs8
-rw-r--r--src/test/ui/reachable/expr_box.stderr17
-rw-r--r--src/test/ui/reachable/expr_call.rs21
-rw-r--r--src/test/ui/reachable/expr_call.stderr24
-rw-r--r--src/test/ui/reachable/expr_cast.rs13
-rw-r--r--src/test/ui/reachable/expr_cast.stderr24
-rw-r--r--src/test/ui/reachable/expr_if.rs31
-rw-r--r--src/test/ui/reachable/expr_if.stderr30
-rw-r--r--src/test/ui/reachable/expr_loop.rs36
-rw-r--r--src/test/ui/reachable/expr_loop.stderr37
-rw-r--r--src/test/ui/reachable/expr_match.rs39
-rw-r--r--src/test/ui/reachable/expr_match.stderr27
-rw-r--r--src/test/ui/reachable/expr_method.rs24
-rw-r--r--src/test/ui/reachable/expr_method.stderr24
-rw-r--r--src/test/ui/reachable/expr_oror.rs12
-rw-r--r--src/test/ui/reachable/expr_repeat.rs12
-rw-r--r--src/test/ui/reachable/expr_repeat.stderr17
-rw-r--r--src/test/ui/reachable/expr_return.rs13
-rw-r--r--src/test/ui/reachable/expr_return.stderr17
-rw-r--r--src/test/ui/reachable/expr_return_in_macro.rs15
-rw-r--r--src/test/ui/reachable/expr_return_in_macro.stderr17
-rw-r--r--src/test/ui/reachable/expr_struct.rs32
-rw-r--r--src/test/ui/reachable/expr_struct.stderr42
-rw-r--r--src/test/ui/reachable/expr_tup.rs17
-rw-r--r--src/test/ui/reachable/expr_tup.stderr25
-rw-r--r--src/test/ui/reachable/expr_type.rs12
-rw-r--r--src/test/ui/reachable/expr_type.stderr17
-rw-r--r--src/test/ui/reachable/expr_unary.rs12
-rw-r--r--src/test/ui/reachable/expr_unary.stderr24
-rw-r--r--src/test/ui/reachable/expr_while.rs29
-rw-r--r--src/test/ui/reachable/expr_while.stderr32
-rw-r--r--src/test/ui/reachable/unreachable-arm.rs14
-rw-r--r--src/test/ui/reachable/unreachable-arm.stderr14
-rw-r--r--src/test/ui/reachable/unreachable-code-ret.rs8
-rw-r--r--src/test/ui/reachable/unreachable-code-ret.stderr17
-rw-r--r--src/test/ui/reachable/unreachable-code.rs8
-rw-r--r--src/test/ui/reachable/unreachable-code.stderr17
-rw-r--r--src/test/ui/reachable/unreachable-in-call.rs22
-rw-r--r--src/test/ui/reachable/unreachable-in-call.stderr25
-rw-r--r--src/test/ui/reachable/unreachable-loop-patterns.rs20
-rw-r--r--src/test/ui/reachable/unreachable-loop-patterns.stderr14
-rw-r--r--src/test/ui/reachable/unreachable-try-pattern.rs41
-rw-r--r--src/test/ui/reachable/unreachable-try-pattern.stderr35
-rw-r--r--src/test/ui/reachable/unreachable-variant.rs7
-rw-r--r--src/test/ui/reachable/unreachable-variant.stderr15
-rw-r--r--src/test/ui/reachable/unwarned-match-on-never.rs24
-rw-r--r--src/test/ui/reachable/unwarned-match-on-never.stderr35
61 files changed, 1281 insertions, 0 deletions
diff --git a/src/test/ui/reachable-unnameable-type-alias.rs b/src/test/ui/reachable-unnameable-type-alias.rs
new file mode 100644
index 000000000..461355f87
--- /dev/null
+++ b/src/test/ui/reachable-unnameable-type-alias.rs
@@ -0,0 +1,16 @@
+// run-pass
+
+#![feature(staged_api)]
+#![stable(feature = "a", since = "b")]
+
+mod inner_private_module {
+ // UnnameableTypeAlias isn't marked as reachable, so no stability annotation is required here
+ pub type UnnameableTypeAlias = u8;
+}
+
+#[stable(feature = "a", since = "b")]
+pub fn f() -> inner_private_module::UnnameableTypeAlias {
+ 0
+}
+
+fn main() {}
diff --git a/src/test/ui/reachable/README.md b/src/test/ui/reachable/README.md
new file mode 100644
index 000000000..8bed5fba7
--- /dev/null
+++ b/src/test/ui/reachable/README.md
@@ -0,0 +1,7 @@
+A variety of tests around reachability. These tests in general check
+two things:
+
+- that we get unreachable code warnings in reasonable locations;
+- that we permit coercions **into** `!` from expressions which
+ diverge, where an expression "diverges" if it must execute some
+ subexpression of type `!`, or it has type `!` itself.
diff --git a/src/test/ui/reachable/auxiliary/unreachable_variant.rs b/src/test/ui/reachable/auxiliary/unreachable_variant.rs
new file mode 100644
index 000000000..4e94a4b5e
--- /dev/null
+++ b/src/test/ui/reachable/auxiliary/unreachable_variant.rs
@@ -0,0 +1,5 @@
+mod super_sekrit {
+ pub enum sooper_sekrit {
+ quux, baz
+ }
+}
diff --git a/src/test/ui/reachable/expr_add.rs b/src/test/ui/reachable/expr_add.rs
new file mode 100644
index 000000000..b45e5daf4
--- /dev/null
+++ b/src/test/ui/reachable/expr_add.rs
@@ -0,0 +1,18 @@
+#![feature(never_type)]
+#![allow(unused_variables)]
+#![deny(unreachable_code)]
+
+use std::ops;
+
+struct Foo;
+
+impl ops::Add<!> for Foo {
+ type Output = !;
+ fn add(self, rhs: !) -> ! {
+ unimplemented!()
+ }
+}
+
+fn main() {
+ let x = Foo + return; //~ ERROR unreachable
+}
diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr
new file mode 100644
index 000000000..692bd20f5
--- /dev/null
+++ b/src/test/ui/reachable/expr_add.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_add.rs:17:13
+ |
+LL | let x = Foo + return;
+ | ^^^^^^------
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_add.rs:3:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_again.rs b/src/test/ui/reachable/expr_again.rs
new file mode 100644
index 000000000..604932133
--- /dev/null
+++ b/src/test/ui/reachable/expr_again.rs
@@ -0,0 +1,11 @@
+#![allow(unused_variables)]
+
+#![deny(unreachable_code)]
+
+fn main() {
+ let x = loop {
+ continue;
+ println!("hi");
+ //~^ ERROR unreachable statement
+ };
+}
diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr
new file mode 100644
index 000000000..a3c54e135
--- /dev/null
+++ b/src/test/ui/reachable/expr_again.stderr
@@ -0,0 +1,17 @@
+error: unreachable statement
+ --> $DIR/expr_again.rs:8:9
+ |
+LL | continue;
+ | -------- any code following this expression is unreachable
+LL | println!("hi");
+ | ^^^^^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/expr_again.rs:3:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_andand.rs b/src/test/ui/reachable/expr_andand.rs
new file mode 100644
index 000000000..d37eb0a3b
--- /dev/null
+++ b/src/test/ui/reachable/expr_andand.rs
@@ -0,0 +1,13 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ // No error here.
+ let x = false && (return);
+ println!("I am not dead.");
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs
new file mode 100644
index 000000000..e6bdb9705
--- /dev/null
+++ b/src/test/ui/reachable/expr_array.rs
@@ -0,0 +1,17 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(type_ascription)]
+
+fn a() {
+ // the `22` is unreachable:
+ let x: [usize; 2] = [return, 22]; //~ ERROR unreachable
+}
+
+fn b() {
+ // the array is unreachable:
+ let x: [usize; 2] = [22, return]; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr
new file mode 100644
index 000000000..e144d7184
--- /dev/null
+++ b/src/test/ui/reachable/expr_array.stderr
@@ -0,0 +1,25 @@
+error: unreachable expression
+ --> $DIR/expr_array.rs:9:34
+ |
+LL | let x: [usize; 2] = [return, 22];
+ | ------ ^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+ |
+note: the lint level is defined here
+ --> $DIR/expr_array.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+ --> $DIR/expr_array.rs:14:25
+ |
+LL | let x: [usize; 2] = [22, return];
+ | ^^^^^------^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_assign.rs b/src/test/ui/reachable/expr_assign.rs
new file mode 100644
index 000000000..e547f75e2
--- /dev/null
+++ b/src/test/ui/reachable/expr_assign.rs
@@ -0,0 +1,29 @@
+#![feature(never_type)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ // No error here.
+ let x;
+ x = return; //~ ERROR unreachable
+}
+
+fn bar() {
+ use std::ptr;
+ let p: *mut ! = ptr::null_mut::<!>();
+ unsafe {
+ // Here we consider the `return` unreachable because
+ // "evaluating" the `*p` has type `!`. This is somewhat
+ // dubious, I suppose.
+ *p = return; //~ ERROR unreachable
+ }
+}
+
+fn baz() {
+ let mut i = 0;
+ *{return; &mut i} = 22; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr
new file mode 100644
index 000000000..c51156b3f
--- /dev/null
+++ b/src/test/ui/reachable/expr_assign.stderr
@@ -0,0 +1,33 @@
+error: unreachable expression
+ --> $DIR/expr_assign.rs:10:5
+ |
+LL | x = return;
+ | ^^^^------
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_assign.rs:5:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+ --> $DIR/expr_assign.rs:20:14
+ |
+LL | *p = return;
+ | -- ^^^^^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+
+error: unreachable expression
+ --> $DIR/expr_assign.rs:26:15
+ |
+LL | *{return; &mut i} = 22;
+ | ------ ^^^^^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/reachable/expr_block.rs b/src/test/ui/reachable/expr_block.rs
new file mode 100644
index 000000000..136bccce8
--- /dev/null
+++ b/src/test/ui/reachable/expr_block.rs
@@ -0,0 +1,31 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn a() {
+ // Here the tail expression is considered unreachable:
+ let x = {
+ return;
+ 22 //~ ERROR unreachable
+ };
+}
+
+fn b() {
+ // Here the `x` assignment is considered unreachable, not the block:
+ let x = {
+ return;
+ };
+}
+
+fn c() {
+ // Here the `println!` is unreachable:
+ let x = {
+ return;
+ println!("foo");
+ //~^ ERROR unreachable statement
+ 22
+ };
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr
new file mode 100644
index 000000000..d5f248a24
--- /dev/null
+++ b/src/test/ui/reachable/expr_block.stderr
@@ -0,0 +1,26 @@
+error: unreachable expression
+ --> $DIR/expr_block.rs:10:9
+ |
+LL | return;
+ | ------ any code following this expression is unreachable
+LL | 22
+ | ^^ unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_block.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable statement
+ --> $DIR/expr_block.rs:25:9
+ |
+LL | return;
+ | ------ any code following this expression is unreachable
+LL | println!("foo");
+ | ^^^^^^^^^^^^^^^ unreachable statement
+ |
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_box.rs b/src/test/ui/reachable/expr_box.rs
new file mode 100644
index 000000000..00328ea01
--- /dev/null
+++ b/src/test/ui/reachable/expr_box.rs
@@ -0,0 +1,8 @@
+#![feature(box_syntax)]
+#![allow(unused_variables)]
+#![deny(unreachable_code)]
+
+fn main() {
+ let x = box return; //~ ERROR unreachable
+ println!("hi");
+}
diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr
new file mode 100644
index 000000000..ea6472cbe
--- /dev/null
+++ b/src/test/ui/reachable/expr_box.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_box.rs:6:13
+ |
+LL | let x = box return;
+ | ^^^^------
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_box.rs:3:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_call.rs b/src/test/ui/reachable/expr_call.rs
new file mode 100644
index 000000000..1eaa96c3c
--- /dev/null
+++ b/src/test/ui/reachable/expr_call.rs
@@ -0,0 +1,21 @@
+#![feature(never_type)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo(x: !, y: usize) { }
+
+fn bar(x: !) { }
+
+fn a() {
+ // the `22` is unreachable:
+ foo(return, 22); //~ ERROR unreachable
+}
+
+fn b() {
+ // the call is unreachable:
+ bar(return); //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr
new file mode 100644
index 000000000..a5ad9a329
--- /dev/null
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -0,0 +1,24 @@
+error: unreachable expression
+ --> $DIR/expr_call.rs:13:17
+ |
+LL | foo(return, 22);
+ | ------ ^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+ |
+note: the lint level is defined here
+ --> $DIR/expr_call.rs:5:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable call
+ --> $DIR/expr_call.rs:18:5
+ |
+LL | bar(return);
+ | ^^^ ------ any code following this expression is unreachable
+ | |
+ | unreachable call
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_cast.rs b/src/test/ui/reachable/expr_cast.rs
new file mode 100644
index 000000000..e8e477ea4
--- /dev/null
+++ b/src/test/ui/reachable/expr_cast.rs
@@ -0,0 +1,13 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type, type_ascription)]
+
+fn a() {
+ // the cast is unreachable:
+ let x = {return} as !; //~ ERROR unreachable
+ //~| ERROR non-primitive cast
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr
new file mode 100644
index 000000000..6643f1784
--- /dev/null
+++ b/src/test/ui/reachable/expr_cast.stderr
@@ -0,0 +1,24 @@
+error: unreachable expression
+ --> $DIR/expr_cast.rs:9:13
+ |
+LL | let x = {return} as !;
+ | ^------^^^^^^
+ | ||
+ | |any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_cast.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error[E0605]: non-primitive cast: `()` as `!`
+ --> $DIR/expr_cast.rs:9:13
+ |
+LL | let x = {return} as !;
+ | ^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs
new file mode 100644
index 000000000..3c04eaf48
--- /dev/null
+++ b/src/test/ui/reachable/expr_if.rs
@@ -0,0 +1,31 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ if {return} { //~ ERROR unreachable block in `if`
+ println!("Hello, world!");
+ }
+}
+
+fn bar() {
+ if {true} {
+ return;
+ }
+ println!("I am not dead.");
+}
+
+fn baz() {
+ if {true} {
+ return;
+ } else {
+ return;
+ }
+ // As the next action to be taken after the if arms, we should
+ // report the `println!` as unreachable:
+ println!("But I am.");
+ //~^ ERROR unreachable statement
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr
new file mode 100644
index 000000000..ebd0b5a3e
--- /dev/null
+++ b/src/test/ui/reachable/expr_if.stderr
@@ -0,0 +1,30 @@
+error: unreachable block in `if` or `while` expression
+ --> $DIR/expr_if.rs:7:17
+ |
+LL | if {return} {
+ | _________------__^
+ | | |
+ | | any code following this expression is unreachable
+LL | | println!("Hello, world!");
+LL | | }
+ | |_____^ unreachable block in `if` or `while` expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_if.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable statement
+ --> $DIR/expr_if.rs:27:5
+ |
+LL | return;
+ | ------ any code following this expression is unreachable
+...
+LL | println!("But I am.");
+ | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs
new file mode 100644
index 000000000..7eab6f7bb
--- /dev/null
+++ b/src/test/ui/reachable/expr_loop.rs
@@ -0,0 +1,36 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn a() {
+ loop { return; }
+ println!("I am dead.");
+ //~^ ERROR unreachable statement
+}
+
+fn b() {
+ loop {
+ break;
+ }
+ println!("I am not dead.");
+}
+
+fn c() {
+ loop { return; }
+ println!("I am dead.");
+ //~^ ERROR unreachable statement
+}
+
+fn d() {
+ 'outer: loop { loop { break 'outer; } }
+ println!("I am not dead.");
+}
+
+fn e() {
+ loop { 'middle: loop { loop { break 'middle; } } }
+ println!("I am dead.");
+ //~^ ERROR unreachable statement
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr
new file mode 100644
index 000000000..918584686
--- /dev/null
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -0,0 +1,37 @@
+error: unreachable statement
+ --> $DIR/expr_loop.rs:8:5
+ |
+LL | loop { return; }
+ | ------ any code following this expression is unreachable
+LL | println!("I am dead.");
+ | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/expr_loop.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unreachable statement
+ --> $DIR/expr_loop.rs:21:5
+ |
+LL | loop { return; }
+ | ------ any code following this expression is unreachable
+LL | println!("I am dead.");
+ | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unreachable statement
+ --> $DIR/expr_loop.rs:32:5
+ |
+LL | loop { 'middle: loop { loop { break 'middle; } } }
+ | -------------------------------------------------- any code following this expression is unreachable
+LL | println!("I am dead.");
+ | ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs
new file mode 100644
index 000000000..2fd26b54e
--- /dev/null
+++ b/src/test/ui/reachable/expr_match.rs
@@ -0,0 +1,39 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn b() {
+ match () { () => return }
+ println!("I am dead");
+ //~^ ERROR unreachable statement
+}
+
+fn c() {
+ match () { () if false => return, () => () }
+ println!("I am not dead");
+}
+
+fn d() {
+ match () { () if false => return, () => return }
+ println!("I am dead");
+ //~^ ERROR unreachable statement
+}
+
+fn e() {
+ // Here the compiler fails to figure out that the `println` is dead.
+ match () { () if return => (), () => return }
+ println!("I am dead");
+}
+
+fn f() {
+ match Some(()) { None => (), Some(()) => return }
+ println!("I am not dead");
+}
+
+fn g() {
+ match Some(()) { None => return, Some(()) => () }
+ println!("I am not dead");
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
new file mode 100644
index 000000000..d15208609
--- /dev/null
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -0,0 +1,27 @@
+error: unreachable statement
+ --> $DIR/expr_match.rs:8:5
+ |
+LL | match () { () => return }
+ | ------------------------- any code following this `match` expression is unreachable, as all arms diverge
+LL | println!("I am dead");
+ | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/expr_match.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: unreachable statement
+ --> $DIR/expr_match.rs:19:5
+ |
+LL | match () { () if false => return, () => return }
+ | ------------------------------------------------ any code following this `match` expression is unreachable, as all arms diverge
+LL | println!("I am dead");
+ | ^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_method.rs b/src/test/ui/reachable/expr_method.rs
new file mode 100644
index 000000000..d917df05b
--- /dev/null
+++ b/src/test/ui/reachable/expr_method.rs
@@ -0,0 +1,24 @@
+#![feature(never_type)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+struct Foo;
+
+impl Foo {
+ fn foo(&self, x: !, y: usize) { }
+ fn bar(&self, x: !) { }
+}
+
+fn a() {
+ // the `22` is unreachable:
+ Foo.foo(return, 22); //~ ERROR unreachable
+}
+
+fn b() {
+ // the call is unreachable:
+ Foo.bar(return); //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr
new file mode 100644
index 000000000..41c3b8a39
--- /dev/null
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -0,0 +1,24 @@
+error: unreachable expression
+ --> $DIR/expr_method.rs:16:21
+ |
+LL | Foo.foo(return, 22);
+ | ------ ^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+ |
+note: the lint level is defined here
+ --> $DIR/expr_method.rs:5:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable call
+ --> $DIR/expr_method.rs:21:9
+ |
+LL | Foo.bar(return);
+ | ^^^ ------ any code following this expression is unreachable
+ | |
+ | unreachable call
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_oror.rs b/src/test/ui/reachable/expr_oror.rs
new file mode 100644
index 000000000..e95062de4
--- /dev/null
+++ b/src/test/ui/reachable/expr_oror.rs
@@ -0,0 +1,12 @@
+// build-pass (FIXME(62277): could be check-pass?)
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ let x = false || (return);
+ println!("I am not dead.");
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs
new file mode 100644
index 000000000..0fd13c6cb
--- /dev/null
+++ b/src/test/ui/reachable/expr_repeat.rs
@@ -0,0 +1,12 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(type_ascription)]
+
+fn a() {
+ // the repeat is unreachable:
+ let x: [usize; 2] = [return; 2]; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr
new file mode 100644
index 000000000..defa87046
--- /dev/null
+++ b/src/test/ui/reachable/expr_repeat.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_repeat.rs:9:25
+ |
+LL | let x: [usize; 2] = [return; 2];
+ | ^------^^^^
+ | ||
+ | |any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_repeat.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_return.rs b/src/test/ui/reachable/expr_return.rs
new file mode 100644
index 000000000..0fc43f450
--- /dev/null
+++ b/src/test/ui/reachable/expr_return.rs
@@ -0,0 +1,13 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(type_ascription)]
+
+fn a() {
+ // Here we issue that the "2nd-innermost" return is unreachable,
+ // but we stop there.
+ let x = {return {return {return;}}}; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr
new file mode 100644
index 000000000..e1bef80ae
--- /dev/null
+++ b/src/test/ui/reachable/expr_return.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_return.rs:10:22
+ |
+LL | let x = {return {return {return;}}};
+ | ^^^^^^^^------^^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_return.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_return_in_macro.rs b/src/test/ui/reachable/expr_return_in_macro.rs
new file mode 100644
index 000000000..4e57618bf
--- /dev/null
+++ b/src/test/ui/reachable/expr_return_in_macro.rs
@@ -0,0 +1,15 @@
+// Tests that we generate nice error messages
+// when an expression is unreachble due to control
+// flow inside of a macro expansion.
+#![deny(unreachable_code)]
+
+macro_rules! early_return {
+ () => {
+ return ()
+ }
+}
+
+fn main() {
+ return early_return!();
+ //~^ ERROR unreachable expression
+}
diff --git a/src/test/ui/reachable/expr_return_in_macro.stderr b/src/test/ui/reachable/expr_return_in_macro.stderr
new file mode 100644
index 000000000..3c562a7ee
--- /dev/null
+++ b/src/test/ui/reachable/expr_return_in_macro.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_return_in_macro.rs:13:5
+ |
+LL | return ()
+ | --------- any code following this expression is unreachable
+...
+LL | return early_return!();
+ | ^^^^^^^^^^^^^^^^^^^^^^ unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_return_in_macro.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_struct.rs b/src/test/ui/reachable/expr_struct.rs
new file mode 100644
index 000000000..31ab40582
--- /dev/null
+++ b/src/test/ui/reachable/expr_struct.rs
@@ -0,0 +1,32 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(type_ascription)]
+
+struct Foo {
+ a: usize,
+ b: usize,
+}
+
+fn a() {
+ // struct expr is unreachable:
+ let x = Foo { a: 22, b: 33, ..return }; //~ ERROR unreachable
+}
+
+fn b() {
+ // the `33` is unreachable:
+ let x = Foo { a: return, b: 33, ..return }; //~ ERROR unreachable
+}
+
+fn c() {
+ // the `..return` is unreachable:
+ let x = Foo { a: 22, b: return, ..return }; //~ ERROR unreachable
+}
+
+fn d() {
+ // the struct expr is unreachable:
+ let x = Foo { a: 22, b: return }; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr
new file mode 100644
index 000000000..36b070456
--- /dev/null
+++ b/src/test/ui/reachable/expr_struct.stderr
@@ -0,0 +1,42 @@
+error: unreachable expression
+ --> $DIR/expr_struct.rs:14:13
+ |
+LL | let x = Foo { a: 22, b: 33, ..return };
+ | ^^^^^^^^^^^^^^^^^^^^^^------^^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_struct.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+ --> $DIR/expr_struct.rs:19:33
+ |
+LL | let x = Foo { a: return, b: 33, ..return };
+ | ------ ^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+
+error: unreachable expression
+ --> $DIR/expr_struct.rs:24:39
+ |
+LL | let x = Foo { a: 22, b: return, ..return };
+ | ------ ^^^^^^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+
+error: unreachable expression
+ --> $DIR/expr_struct.rs:29:13
+ |
+LL | let x = Foo { a: 22, b: return };
+ | ^^^^^^^^^^^^^^^^------^^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/reachable/expr_tup.rs b/src/test/ui/reachable/expr_tup.rs
new file mode 100644
index 000000000..90d4382e2
--- /dev/null
+++ b/src/test/ui/reachable/expr_tup.rs
@@ -0,0 +1,17 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(type_ascription)]
+
+fn a() {
+ // the `2` is unreachable:
+ let x: (usize, usize) = (return, 2); //~ ERROR unreachable
+}
+
+fn b() {
+ // the tuple is unreachable:
+ let x: (usize, usize) = (2, return); //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr
new file mode 100644
index 000000000..5ea6bf4ab
--- /dev/null
+++ b/src/test/ui/reachable/expr_tup.stderr
@@ -0,0 +1,25 @@
+error: unreachable expression
+ --> $DIR/expr_tup.rs:9:38
+ |
+LL | let x: (usize, usize) = (return, 2);
+ | ------ ^ unreachable expression
+ | |
+ | any code following this expression is unreachable
+ |
+note: the lint level is defined here
+ --> $DIR/expr_tup.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+ --> $DIR/expr_tup.rs:14:29
+ |
+LL | let x: (usize, usize) = (2, return);
+ | ^^^^------^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/expr_type.rs b/src/test/ui/reachable/expr_type.rs
new file mode 100644
index 000000000..8d32397b5
--- /dev/null
+++ b/src/test/ui/reachable/expr_type.rs
@@ -0,0 +1,12 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type, type_ascription)]
+
+fn a() {
+ // the cast is unreachable:
+ let x = {return}: !; //~ ERROR unreachable
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr
new file mode 100644
index 000000000..c56c64be7
--- /dev/null
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -0,0 +1,17 @@
+error: unreachable expression
+ --> $DIR/expr_type.rs:9:13
+ |
+LL | let x = {return}: !;
+ | ^------^^^^
+ | ||
+ | |any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_type.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_unary.rs b/src/test/ui/reachable/expr_unary.rs
new file mode 100644
index 000000000..190c7447d
--- /dev/null
+++ b/src/test/ui/reachable/expr_unary.rs
@@ -0,0 +1,12 @@
+#![feature(never_type)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ let x: ! = * { return; }; //~ ERROR unreachable
+ //~| ERROR type `!` cannot be dereferenced
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr
new file mode 100644
index 000000000..0a763087c
--- /dev/null
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -0,0 +1,24 @@
+error[E0614]: type `!` cannot be dereferenced
+ --> $DIR/expr_unary.rs:8:16
+ |
+LL | let x: ! = * { return; };
+ | ^^^^^^^^^^^^^
+
+error: unreachable expression
+ --> $DIR/expr_unary.rs:8:16
+ |
+LL | let x: ! = * { return; };
+ | ^^^^------^^^
+ | | |
+ | | any code following this expression is unreachable
+ | unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_unary.rs:5:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0614`.
diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs
new file mode 100644
index 000000000..5005f3833
--- /dev/null
+++ b/src/test/ui/reachable/expr_while.rs
@@ -0,0 +1,29 @@
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn foo() {
+ while {return} {
+ //~^ ERROR unreachable block in `if`
+ println!("Hello, world!");
+ }
+}
+
+fn bar() {
+ while {true} {
+ return;
+ }
+ println!("I am not dead.");
+}
+
+fn baz() {
+ // Here, we cite the `while` loop as dead.
+ while {return} {
+ //~^ ERROR unreachable block in `if`
+ println!("I am dead.");
+ }
+ println!("I am, too.");
+}
+
+fn main() { }
diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr
new file mode 100644
index 000000000..b1859f619
--- /dev/null
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -0,0 +1,32 @@
+error: unreachable block in `if` or `while` expression
+ --> $DIR/expr_while.rs:7:20
+ |
+LL | while {return} {
+ | ____________------__^
+ | | |
+ | | any code following this expression is unreachable
+LL | |
+LL | | println!("Hello, world!");
+LL | | }
+ | |_____^ unreachable block in `if` or `while` expression
+ |
+note: the lint level is defined here
+ --> $DIR/expr_while.rs:4:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable block in `if` or `while` expression
+ --> $DIR/expr_while.rs:22:20
+ |
+LL | while {return} {
+ | ____________------__^
+ | | |
+ | | any code following this expression is unreachable
+LL | |
+LL | | println!("I am dead.");
+LL | | }
+ | |_____^ unreachable block in `if` or `while` expression
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/unreachable-arm.rs b/src/test/ui/reachable/unreachable-arm.rs
new file mode 100644
index 000000000..3277bf0d5
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-arm.rs
@@ -0,0 +1,14 @@
+#![feature(box_patterns)]
+
+#![allow(dead_code)]
+#![deny(unreachable_patterns)]
+
+enum Foo { A(Box<Foo>, isize), B(usize), }
+
+fn main() {
+ match Foo::B(1) {
+ Foo::B(_) | Foo::A(box _, 1) => { }
+ Foo::A(_, 1) => { } //~ ERROR unreachable pattern
+ _ => { }
+ }
+}
diff --git a/src/test/ui/reachable/unreachable-arm.stderr b/src/test/ui/reachable/unreachable-arm.stderr
new file mode 100644
index 000000000..1cbea8288
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-arm.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+ --> $DIR/unreachable-arm.rs:11:9
+ |
+LL | Foo::A(_, 1) => { }
+ | ^^^^^^^^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-arm.rs:4:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-code-ret.rs b/src/test/ui/reachable/unreachable-code-ret.rs
new file mode 100644
index 000000000..fad35794f
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-code-ret.rs
@@ -0,0 +1,8 @@
+// error-pattern: unreachable statement
+
+#![deny(unreachable_code)]
+
+fn main() {
+ return;
+ println!("Paul is dead");
+}
diff --git a/src/test/ui/reachable/unreachable-code-ret.stderr b/src/test/ui/reachable/unreachable-code-ret.stderr
new file mode 100644
index 000000000..263a1b5a9
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-code-ret.stderr
@@ -0,0 +1,17 @@
+error: unreachable statement
+ --> $DIR/unreachable-code-ret.rs:7:5
+ |
+LL | return;
+ | ------ any code following this expression is unreachable
+LL | println!("Paul is dead");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-code-ret.rs:3:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-code.rs b/src/test/ui/reachable/unreachable-code.rs
new file mode 100644
index 000000000..ad0dc8a8b
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-code.rs
@@ -0,0 +1,8 @@
+#![deny(unreachable_code)]
+#![allow(unused_variables)]
+
+fn main() {
+ loop{}
+
+ let a = 3; //~ ERROR: unreachable statement
+}
diff --git a/src/test/ui/reachable/unreachable-code.stderr b/src/test/ui/reachable/unreachable-code.stderr
new file mode 100644
index 000000000..cb1b760c2
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-code.stderr
@@ -0,0 +1,17 @@
+error: unreachable statement
+ --> $DIR/unreachable-code.rs:7:3
+ |
+LL | loop{}
+ | ------ any code following this expression is unreachable
+LL |
+LL | let a = 3;
+ | ^^^^^^^^^^ unreachable statement
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-code.rs:1:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-in-call.rs b/src/test/ui/reachable/unreachable-in-call.rs
new file mode 100644
index 000000000..dd94e79f4
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-in-call.rs
@@ -0,0 +1,22 @@
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+
+fn diverge() -> ! { panic!() }
+
+fn get_u8() -> u8 {
+ 1
+}
+fn call(_: u8, _: u8) {
+
+}
+fn diverge_first() {
+ call(diverge(),
+ get_u8()); //~ ERROR unreachable expression
+}
+fn diverge_second() {
+ call( //~ ERROR unreachable call
+ get_u8(),
+ diverge());
+}
+
+fn main() {}
diff --git a/src/test/ui/reachable/unreachable-in-call.stderr b/src/test/ui/reachable/unreachable-in-call.stderr
new file mode 100644
index 000000000..cdfa79bf8
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-in-call.stderr
@@ -0,0 +1,25 @@
+error: unreachable expression
+ --> $DIR/unreachable-in-call.rs:14:10
+ |
+LL | call(diverge(),
+ | --------- any code following this expression is unreachable
+LL | get_u8());
+ | ^^^^^^^^ unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-in-call.rs:2:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable call
+ --> $DIR/unreachable-in-call.rs:17:5
+ |
+LL | call(
+ | ^^^^ unreachable call
+LL | get_u8(),
+LL | diverge());
+ | --------- any code following this expression is unreachable
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/reachable/unreachable-loop-patterns.rs b/src/test/ui/reachable/unreachable-loop-patterns.rs
new file mode 100644
index 000000000..e9cef5f47
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-loop-patterns.rs
@@ -0,0 +1,20 @@
+#![feature(never_type, never_type_fallback)]
+#![feature(exhaustive_patterns)]
+
+#![allow(unreachable_code)]
+#![deny(unreachable_patterns)]
+
+enum Void {}
+
+impl Iterator for Void {
+ type Item = Void;
+
+ fn next(&mut self) -> Option<Void> {
+ None
+ }
+}
+
+fn main() {
+ for _ in unimplemented!() as Void {}
+ //~^ ERROR unreachable pattern
+}
diff --git a/src/test/ui/reachable/unreachable-loop-patterns.stderr b/src/test/ui/reachable/unreachable-loop-patterns.stderr
new file mode 100644
index 000000000..80ffa5d73
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-loop-patterns.stderr
@@ -0,0 +1,14 @@
+error: unreachable pattern
+ --> $DIR/unreachable-loop-patterns.rs:18:9
+ |
+LL | for _ in unimplemented!() as Void {}
+ | ^
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-loop-patterns.rs:5:9
+ |
+LL | #![deny(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/unreachable-try-pattern.rs b/src/test/ui/reachable/unreachable-try-pattern.rs
new file mode 100644
index 000000000..23360e73f
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-try-pattern.rs
@@ -0,0 +1,41 @@
+// check-pass
+#![feature(never_type, exhaustive_patterns)]
+#![warn(unreachable_code)]
+#![warn(unreachable_patterns)]
+
+enum Void {}
+
+impl From<Void> for i32 {
+ fn from(v: Void) -> i32 {
+ match v {}
+ }
+}
+
+fn bar(x: Result<!, i32>) -> Result<u32, i32> {
+ x?
+}
+
+fn foo(x: Result<!, i32>) -> Result<u32, i32> {
+ let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+ //~^ WARN unreachable pattern
+ //~| WARN unreachable expression
+ Ok(y)
+}
+
+fn qux(x: Result<u32, Void>) -> Result<u32, i32> {
+ Ok(x?)
+}
+
+fn vom(x: Result<u32, Void>) -> Result<u32, i32> {
+ let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
+ //~^ WARN unreachable pattern
+ Ok(y)
+}
+
+
+fn main() {
+ let _ = bar(Err(123));
+ let _ = foo(Err(123));
+ let _ = qux(Ok(123));
+ let _ = vom(Ok(123));
+}
diff --git a/src/test/ui/reachable/unreachable-try-pattern.stderr b/src/test/ui/reachable/unreachable-try-pattern.stderr
new file mode 100644
index 000000000..8f3e23119
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-try-pattern.stderr
@@ -0,0 +1,35 @@
+warning: unreachable expression
+ --> $DIR/unreachable-try-pattern.rs:19:36
+ |
+LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+ | -^^^^^^^
+ | |
+ | unreachable expression
+ | any code following this expression is unreachable
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-try-pattern.rs:3:9
+ |
+LL | #![warn(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+warning: unreachable pattern
+ --> $DIR/unreachable-try-pattern.rs:19:24
+ |
+LL | let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+ | ^^^^^
+ |
+note: the lint level is defined here
+ --> $DIR/unreachable-try-pattern.rs:4:9
+ |
+LL | #![warn(unreachable_patterns)]
+ | ^^^^^^^^^^^^^^^^^^^^
+
+warning: unreachable pattern
+ --> $DIR/unreachable-try-pattern.rs:30:40
+ |
+LL | let y = (match x { Ok(n) => Ok(n), Err(e) => Err(e) })?;
+ | ^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/reachable/unreachable-variant.rs b/src/test/ui/reachable/unreachable-variant.rs
new file mode 100644
index 000000000..008c2d476
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-variant.rs
@@ -0,0 +1,7 @@
+// aux-build:unreachable_variant.rs
+
+extern crate unreachable_variant as other;
+
+fn main() {
+ let _x = other::super_sekrit::sooper_sekrit::baz; //~ ERROR is private
+}
diff --git a/src/test/ui/reachable/unreachable-variant.stderr b/src/test/ui/reachable/unreachable-variant.stderr
new file mode 100644
index 000000000..6c27a2756
--- /dev/null
+++ b/src/test/ui/reachable/unreachable-variant.stderr
@@ -0,0 +1,15 @@
+error[E0603]: module `super_sekrit` is private
+ --> $DIR/unreachable-variant.rs:6:21
+ |
+LL | let _x = other::super_sekrit::sooper_sekrit::baz;
+ | ^^^^^^^^^^^^ private module
+ |
+note: the module `super_sekrit` is defined here
+ --> $DIR/auxiliary/unreachable_variant.rs:1:1
+ |
+LL | mod super_sekrit {
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0603`.
diff --git a/src/test/ui/reachable/unwarned-match-on-never.rs b/src/test/ui/reachable/unwarned-match-on-never.rs
new file mode 100644
index 000000000..71f8fe3a7
--- /dev/null
+++ b/src/test/ui/reachable/unwarned-match-on-never.rs
@@ -0,0 +1,24 @@
+#![deny(unreachable_code)]
+#![allow(dead_code)]
+
+#![feature(never_type)]
+
+fn foo(x: !) -> bool {
+ // Explicit matches on the never type are unwarned.
+ match x {}
+ // But matches in unreachable code are warned.
+ match x {} //~ ERROR unreachable expression
+}
+
+fn bar() {
+ match (return) {
+ () => () //~ ERROR unreachable arm
+ }
+}
+
+fn main() {
+ return;
+ match () { //~ ERROR unreachable expression
+ () => (),
+ }
+}
diff --git a/src/test/ui/reachable/unwarned-match-on-never.stderr b/src/test/ui/reachable/unwarned-match-on-never.stderr
new file mode 100644
index 000000000..a296d2a05
--- /dev/null
+++ b/src/test/ui/reachable/unwarned-match-on-never.stderr
@@ -0,0 +1,35 @@
+error: unreachable expression
+ --> $DIR/unwarned-match-on-never.rs:10:5
+ |
+LL | match x {}
+ | - any code following this expression is unreachable
+LL | // But matches in unreachable code are warned.
+LL | match x {}
+ | ^^^^^^^^^^ unreachable expression
+ |
+note: the lint level is defined here
+ --> $DIR/unwarned-match-on-never.rs:1:9
+ |
+LL | #![deny(unreachable_code)]
+ | ^^^^^^^^^^^^^^^^
+
+error: unreachable arm
+ --> $DIR/unwarned-match-on-never.rs:15:15
+ |
+LL | match (return) {
+ | -------- any code following this expression is unreachable
+LL | () => ()
+ | ^^ unreachable arm
+
+error: unreachable expression
+ --> $DIR/unwarned-match-on-never.rs:21:5
+ |
+LL | return;
+ | ------ any code following this expression is unreachable
+LL | / match () {
+LL | | () => (),
+LL | | }
+ | |_____^ unreachable expression
+
+error: aborting due to 3 previous errors
+