about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/ui/reachable/README.md7
-rw-r--r--src/test/ui/reachable/expr_add.rs28
-rw-r--r--src/test/ui/reachable/expr_add.stderr14
-rw-r--r--src/test/ui/reachable/expr_again.rs20
-rw-r--r--src/test/ui/reachable/expr_again.stderr15
-rw-r--r--src/test/ui/reachable/expr_andand.rs21
-rw-r--r--src/test/ui/reachable/expr_andand.stderr0
-rw-r--r--src/test/ui/reachable/expr_array.rs28
-rw-r--r--src/test/ui/reachable/expr_array.stderr20
-rw-r--r--src/test/ui/reachable/expr_assign.rs39
-rw-r--r--src/test/ui/reachable/expr_assign.stderr26
-rw-r--r--src/test/ui/reachable/expr_block.rs41
-rw-r--r--src/test/ui/reachable/expr_block.stderr22
-rw-r--r--src/test/ui/reachable/expr_box.rs18
-rw-r--r--src/test/ui/reachable/expr_box.stderr14
-rw-r--r--src/test/ui/reachable/expr_call.rs31
-rw-r--r--src/test/ui/reachable/expr_call.stderr20
-rw-r--r--src/test/ui/reachable/expr_cast.rs23
-rw-r--r--src/test/ui/reachable/expr_cast.stderr14
-rw-r--r--src/test/ui/reachable/expr_if.rs41
-rw-r--r--src/test/ui/reachable/expr_if.stderr15
-rw-r--r--src/test/ui/reachable/expr_loop.rs44
-rw-r--r--src/test/ui/reachable/expr_loop.stderr31
-rw-r--r--src/test/ui/reachable/expr_match.rs54
-rw-r--r--src/test/ui/reachable/expr_match.stderr30
-rw-r--r--src/test/ui/reachable/expr_method.rs34
-rw-r--r--src/test/ui/reachable/expr_method.stderr20
-rw-r--r--src/test/ui/reachable/expr_oror.rs20
-rw-r--r--src/test/ui/reachable/expr_oror.stderr0
-rw-r--r--src/test/ui/reachable/expr_repeat.rs23
-rw-r--r--src/test/ui/reachable/expr_repeat.stderr14
-rw-r--r--src/test/ui/reachable/expr_return.rs24
-rw-r--r--src/test/ui/reachable/expr_return.stderr14
-rw-r--r--src/test/ui/reachable/expr_struct.rs43
-rw-r--r--src/test/ui/reachable/expr_struct.stderr32
-rw-r--r--src/test/ui/reachable/expr_tup.rs28
-rw-r--r--src/test/ui/reachable/expr_tup.stderr20
-rw-r--r--src/test/ui/reachable/expr_type.rs23
-rw-r--r--src/test/ui/reachable/expr_type.stderr14
-rw-r--r--src/test/ui/reachable/expr_unary.rs21
-rw-r--r--src/test/ui/reachable/expr_unary.stderr8
-rw-r--r--src/test/ui/reachable/expr_while.rs38
-rw-r--r--src/test/ui/reachable/expr_while.stderr31
43 files changed, 1023 insertions, 0 deletions
diff --git a/src/test/ui/reachable/README.md b/src/test/ui/reachable/README.md
new file mode 100644
index 00000000000..8bed5fba7a2
--- /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/expr_add.rs b/src/test/ui/reachable/expr_add.rs
new file mode 100644
index 00000000000..87d017adf68
--- /dev/null
+++ b/src/test/ui/reachable/expr_add.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![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;
+}
diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr
new file mode 100644
index 00000000000..1a2cc252051
--- /dev/null
+++ b/src/test/ui/reachable/expr_add.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_add.rs:27:13
+   |
+27 |     let x = Foo + return;
+   |             ^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_add.rs:13:9
+   |
+13 | #![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 00000000000..cdbdb8dc0db
--- /dev/null
+++ b/src/test/ui/reachable/expr_again.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(box_syntax)]
+#![allow(unused_variables)]
+#![deny(unreachable_code)]
+
+fn main() {
+    let x = loop {
+        continue;
+        println!("hi");
+    };
+}
diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr
new file mode 100644
index 00000000000..bf4e4dc4711
--- /dev/null
+++ b/src/test/ui/reachable/expr_again.stderr
@@ -0,0 +1,15 @@
+error: unreachable statement
+  --> $DIR/expr_again.rs:18:9
+   |
+18 |         println!("hi");
+   |         ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_again.rs:13:9
+   |
+13 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro outside of the current crate
+
+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 00000000000..af404d03097
--- /dev/null
+++ b/src/test/ui/reachable/expr_andand.rs
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![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_andand.stderr b/src/test/ui/reachable/expr_andand.stderr
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/reachable/expr_andand.stderr
diff --git a/src/test/ui/reachable/expr_array.rs b/src/test/ui/reachable/expr_array.rs
new file mode 100644
index 00000000000..00e8be07725
--- /dev/null
+++ b/src/test/ui/reachable/expr_array.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // the `22` is unreachable:
+    let x: [usize; 2] = [return, 22];
+}
+
+fn b() {
+    // the `array is unreachable:
+    let x: [usize; 2] = [22, return];
+}
+
+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 00000000000..f8dbdb5f8bb
--- /dev/null
+++ b/src/test/ui/reachable/expr_array.stderr
@@ -0,0 +1,20 @@
+error: unreachable expression
+  --> $DIR/expr_array.rs:20:34
+   |
+20 |     let x: [usize; 2] = [return, 22];
+   |                                  ^^
+   |
+note: lint level defined here
+  --> $DIR/expr_array.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_array.rs:25:25
+   |
+25 |     let x: [usize; 2] = [22, return];
+   |                         ^^^^^^^^^^^^
+
+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 00000000000..1b9357013d2
--- /dev/null
+++ b/src/test/ui/reachable/expr_assign.rs
@@ -0,0 +1,39 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn foo() {
+    // No error here.
+    let x;
+    x = return;
+}
+
+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;
+    }
+}
+
+fn baz() {
+    let mut i = 0;
+    *{return; &mut i} = 22;
+}
+
+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 00000000000..807f6a1c1d5
--- /dev/null
+++ b/src/test/ui/reachable/expr_assign.stderr
@@ -0,0 +1,26 @@
+error: unreachable expression
+  --> $DIR/expr_assign.rs:20:5
+   |
+20 |     x = return;
+   |     ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_assign.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_assign.rs:30:14
+   |
+30 |         *p = return;
+   |              ^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_assign.rs:36:15
+   |
+36 |     *{return; &mut i} = 22;
+   |               ^^^^^^
+
+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 00000000000..093589b4dc8
--- /dev/null
+++ b/src/test/ui/reachable/expr_block.rs
@@ -0,0 +1,41 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn a() {
+    // Here the tail expression is considered unreachable:
+    let x = {
+        return;
+        22
+    };
+}
+
+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");
+        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 00000000000..542ce1c3fd9
--- /dev/null
+++ b/src/test/ui/reachable/expr_block.stderr
@@ -0,0 +1,22 @@
+error: unreachable expression
+  --> $DIR/expr_block.rs:21:9
+   |
+21 |         22
+   |         ^^
+   |
+note: lint level defined here
+  --> $DIR/expr_block.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable statement
+  --> $DIR/expr_block.rs:36:9
+   |
+36 |         println!("foo");
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+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 00000000000..6509b608335
--- /dev/null
+++ b/src/test/ui/reachable/expr_box.rs
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(box_syntax)]
+#![allow(unused_variables)]
+#![deny(unreachable_code)]
+
+fn main() {
+    let x = box return;
+    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 00000000000..78ba231cef9
--- /dev/null
+++ b/src/test/ui/reachable/expr_box.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_box.rs:16:13
+   |
+16 |     let x = box return;
+   |             ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_box.rs:13:9
+   |
+13 | #![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 00000000000..8d9f303df7f
--- /dev/null
+++ b/src/test/ui/reachable/expr_call.rs
@@ -0,0 +1,31 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn foo(x: !, y: usize) { }
+
+fn bar(x: !) { }
+
+fn a() {
+    // the `22` is unreachable:
+    foo(return, 22);
+}
+
+fn b() {
+    // the call is unreachable:
+    bar(return);
+}
+
+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 00000000000..5526827f59f
--- /dev/null
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -0,0 +1,20 @@
+error: unreachable expression
+  --> $DIR/expr_call.rs:23:17
+   |
+23 |     foo(return, 22);
+   |                 ^^
+   |
+note: lint level defined here
+  --> $DIR/expr_call.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_call.rs:28:5
+   |
+28 |     bar(return);
+   |     ^^^^^^^^^^^
+
+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 00000000000..926ef864ebf
--- /dev/null
+++ b/src/test/ui/reachable/expr_cast.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // the cast is unreachable:
+    let x = {return} as !;
+}
+
+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 00000000000..a22300dcc13
--- /dev/null
+++ b/src/test/ui/reachable/expr_cast.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_cast.rs:20:13
+   |
+20 |     let x = {return} as !;
+   |             ^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_cast.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_if.rs b/src/test/ui/reachable/expr_if.rs
new file mode 100644
index 00000000000..2a265e772f3
--- /dev/null
+++ b/src/test/ui/reachable/expr_if.rs
@@ -0,0 +1,41 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn foo() {
+    if {return} {
+        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.");
+}
+
+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 00000000000..2cf17474f6e
--- /dev/null
+++ b/src/test/ui/reachable/expr_if.stderr
@@ -0,0 +1,15 @@
+error: unreachable statement
+  --> $DIR/expr_if.rs:38:5
+   |
+38 |     println!("But I am.");
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_if.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_loop.rs b/src/test/ui/reachable/expr_loop.rs
new file mode 100644
index 00000000000..3ed4b2dcf0c
--- /dev/null
+++ b/src/test/ui/reachable/expr_loop.rs
@@ -0,0 +1,44 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn a() {
+    loop { return; }
+    println!("I am dead.");
+}
+
+fn b() {
+    loop {
+        break;
+    }
+    println!("I am not dead.");
+}
+
+fn c() {
+    loop { return; }
+    println!("I am dead.");
+}
+
+fn d() {
+    'outer: loop { loop { break 'outer; } }
+    println!("I am not dead.");
+}
+
+fn e() {
+    loop { 'middle: loop { loop { break 'middle; } } }
+    println!("I am dead.");
+}
+
+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 00000000000..6e98e754c54
--- /dev/null
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -0,0 +1,31 @@
+error: unreachable statement
+  --> $DIR/expr_loop.rs:19:5
+   |
+19 |     println!("I am dead.");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_loop.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro outside of the current crate
+
+error: unreachable statement
+  --> $DIR/expr_loop.rs:31:5
+   |
+31 |     println!("I am dead.");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: unreachable statement
+  --> $DIR/expr_loop.rs:41:5
+   |
+41 |     println!("I am dead.");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+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 00000000000..23bdcc035b2
--- /dev/null
+++ b/src/test/ui/reachable/expr_match.rs
@@ -0,0 +1,54 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn a() {
+    // The match is considered unreachable here, because the `return`
+    // diverges:
+    match {return} { }
+}
+
+fn b() {
+    match () { () => return }
+    println!("I am dead");
+}
+
+fn c() {
+    match () { () if false => return, () => () }
+    println!("I am not dead");
+}
+
+fn d() {
+    match () { () if false => return, () => return }
+    println!("I am dead");
+}
+
+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 00000000000..f5857a5b345
--- /dev/null
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -0,0 +1,30 @@
+error: unreachable expression
+  --> $DIR/expr_match.rs:20:5
+   |
+20 |     match {return} { }
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_match.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable statement
+  --> $DIR/expr_match.rs:25:5
+   |
+25 |     println!("I am dead");
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: unreachable statement
+  --> $DIR/expr_match.rs:35:5
+   |
+35 |     println!("I am dead");
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to 3 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 00000000000..f1d979d7df7
--- /dev/null
+++ b/src/test/ui/reachable/expr_method.rs
@@ -0,0 +1,34 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+struct Foo;
+
+impl Foo {
+    fn foo(&self, x: !, y: usize) { }
+    fn bar(&self, x: !) { }
+}
+
+fn a() {
+    // the `22` is unreachable:
+    Foo.foo(return, 22);
+}
+
+fn b() {
+    // the call is unreachable:
+    Foo.bar(return);
+}
+
+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 00000000000..177d4352a37
--- /dev/null
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -0,0 +1,20 @@
+error: unreachable expression
+  --> $DIR/expr_method.rs:26:21
+   |
+26 |     Foo.foo(return, 22);
+   |                     ^^
+   |
+note: lint level defined here
+  --> $DIR/expr_method.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_method.rs:31:5
+   |
+31 |     Foo.bar(return);
+   |     ^^^^^^^^^^^^^^^
+
+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 00000000000..d01304d4034
--- /dev/null
+++ b/src/test/ui/reachable/expr_oror.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![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_oror.stderr b/src/test/ui/reachable/expr_oror.stderr
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/reachable/expr_oror.stderr
diff --git a/src/test/ui/reachable/expr_repeat.rs b/src/test/ui/reachable/expr_repeat.rs
new file mode 100644
index 00000000000..6078d6d5bde
--- /dev/null
+++ b/src/test/ui/reachable/expr_repeat.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // the repeat is unreachable:
+    let x: [usize; 2] = [return; 2];
+}
+
+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 00000000000..19afc5dd7b5
--- /dev/null
+++ b/src/test/ui/reachable/expr_repeat.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_repeat.rs:20:25
+   |
+20 |     let x: [usize; 2] = [return; 2];
+   |                         ^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_repeat.rs:14:9
+   |
+14 | #![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 00000000000..c640ca06630
--- /dev/null
+++ b/src/test/ui/reachable/expr_return.rs
@@ -0,0 +1,24 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // Here we issue that the "2nd-innermost" return is unreachable,
+    // but we stop there.
+    let x = {return {return {return;}}};
+}
+
+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 00000000000..3eb70a4dd7c
--- /dev/null
+++ b/src/test/ui/reachable/expr_return.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_return.rs:21:22
+   |
+21 |     let x = {return {return {return;}}};
+   |                      ^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_return.rs:14:9
+   |
+14 | #![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 00000000000..09e31819279
--- /dev/null
+++ b/src/test/ui/reachable/expr_struct.rs
@@ -0,0 +1,43 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+struct Foo {
+    a: usize,
+    b: usize,
+}
+
+fn a() {
+    // struct expr is unreachable:
+    let x = Foo { a: 22, b: 33, ..return };
+}
+
+fn b() {
+    // the `33` is unreachable:
+    let x = Foo { a: return, b: 33, ..return };
+}
+
+fn c() {
+    // the `..return` is unreachable:
+    let x = Foo { a: 22, b: return, ..return };
+}
+
+fn d() {
+    // the struct expr is unreachable:
+    let x = Foo { a: 22, b: return };
+}
+
+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 00000000000..4b7ac660413
--- /dev/null
+++ b/src/test/ui/reachable/expr_struct.stderr
@@ -0,0 +1,32 @@
+error: unreachable expression
+  --> $DIR/expr_struct.rs:25:13
+   |
+25 |     let x = Foo { a: 22, b: 33, ..return };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_struct.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_struct.rs:30:33
+   |
+30 |     let x = Foo { a: return, b: 33, ..return };
+   |                                 ^^
+
+error: unreachable expression
+  --> $DIR/expr_struct.rs:35:39
+   |
+35 |     let x = Foo { a: 22, b: return, ..return };
+   |                                       ^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_struct.rs:40:13
+   |
+40 |     let x = Foo { a: 22, b: return };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
+
+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 00000000000..7c75296de6c
--- /dev/null
+++ b/src/test/ui/reachable/expr_tup.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // the `2` is unreachable:
+    let x: (usize, usize) = (return, 2);
+}
+
+fn b() {
+    // the tuple is unreachable:
+    let x: (usize, usize) = (2, return);
+}
+
+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 00000000000..63f477fd0c3
--- /dev/null
+++ b/src/test/ui/reachable/expr_tup.stderr
@@ -0,0 +1,20 @@
+error: unreachable expression
+  --> $DIR/expr_tup.rs:20:38
+   |
+20 |     let x: (usize, usize) = (return, 2);
+   |                                      ^
+   |
+note: lint level defined here
+  --> $DIR/expr_tup.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable expression
+  --> $DIR/expr_tup.rs:25:29
+   |
+25 |     let x: (usize, usize) = (2, return);
+   |                             ^^^^^^^^^^^
+
+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 00000000000..2fa277c382e
--- /dev/null
+++ b/src/test/ui/reachable/expr_type.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+#![feature(type_ascription)]
+
+fn a() {
+    // the cast is unreachable:
+    let x = {return}: !;
+}
+
+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 00000000000..6ed79974ccb
--- /dev/null
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -0,0 +1,14 @@
+error: unreachable expression
+  --> $DIR/expr_type.rs:20:13
+   |
+20 |     let x = {return}: !;
+   |             ^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_type.rs:14:9
+   |
+14 | #![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 00000000000..57901fbaa7c
--- /dev/null
+++ b/src/test/ui/reachable/expr_unary.rs
@@ -0,0 +1,21 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn foo() {
+    let x: ! = ! { return; 22 };
+}
+
+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 00000000000..11172652d84
--- /dev/null
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -0,0 +1,8 @@
+error: cannot apply unary operator `!` to type `!`
+  --> $DIR/expr_unary.rs:18:16
+   |
+18 |     let x: ! = ! { return; 22 };
+   |                ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_while.rs b/src/test/ui/reachable/expr_while.rs
new file mode 100644
index 00000000000..7dcd609fbc8
--- /dev/null
+++ b/src/test/ui/reachable/expr_while.rs
@@ -0,0 +1,38 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+#![allow(dead_code)]
+#![deny(unreachable_code)]
+#![feature(never_type)]
+
+fn foo() {
+    while {return} {
+        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} {
+        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 00000000000..066cfc86c64
--- /dev/null
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -0,0 +1,31 @@
+error: unreachable statement
+  --> $DIR/expr_while.rs:19:9
+   |
+19 |         println!("Hello, world!");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_while.rs:14:9
+   |
+14 | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: this error originates in a macro outside of the current crate
+
+error: unreachable statement
+  --> $DIR/expr_while.rs:33:9
+   |
+33 |         println!("I am dead.");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: unreachable statement
+  --> $DIR/expr_while.rs:35:5
+   |
+35 |     println!("I am, too.");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to 3 previous errors
+