about summary refs log tree commit diff
path: root/src/test/ui
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-04-04 08:10:22 -0700
committerEsteban Küber <esteban@kuber.com.ar>2017-04-04 08:13:27 -0700
commitdedb7bbbbf272226f327b8cda8aaa12cf6325eca (patch)
tree9c7c7b656750a53b5ca4f7646ee1dfe60829b271 /src/test/ui
parentb477682dca3343eb89a467f0d3c73986a53d49d9 (diff)
parent5309a3e31d88def1f3ea966162ed4f81f161d500 (diff)
downloadrust-dedb7bbbbf272226f327b8cda8aaa12cf6325eca.tar.gz
rust-dedb7bbbbf272226f327b8cda8aaa12cf6325eca.zip
Merge branch 'master' into issue-32540
Diffstat (limited to 'src/test/ui')
-rw-r--r--src/test/ui/codemap_tests/huge_multispan_highlight.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-31424.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-35937.rs31
-rw-r--r--src/test/ui/did_you_mean/issue-35937.stderr26
-rw-r--r--src/test/ui/did_you_mean/issue-38147-2.stderr2
-rw-r--r--src/test/ui/did_you_mean/issue-38147-3.stderr4
-rw-r--r--src/test/ui/did_you_mean/issue-39544.rs35
-rw-r--r--src/test/ui/did_you_mean/issue-39544.stderr86
-rw-r--r--src/test/ui/did_you_mean/issue-40823.rs14
-rw-r--r--src/test/ui/did_you_mean/issue-40823.stderr8
-rw-r--r--src/test/ui/loop-break-value-no-repeat.rs25
-rw-r--r--src/test/ui/loop-break-value-no-repeat.stderr8
-rw-r--r--src/test/ui/macros/macro_path_as_generic_bound.stderr5
-rw-r--r--src/test/ui/pub/pub-restricted-error-fn.rs13
-rw-r--r--src/test/ui/pub/pub-restricted-error-fn.stderr8
-rw-r--r--src/test/ui/pub/pub-restricted-error.rs19
-rw-r--r--src/test/ui/pub/pub-restricted-error.stderr8
-rw-r--r--src/test/ui/pub/pub-restricted-non-path.rs15
-rw-r--r--src/test/ui/pub/pub-restricted-non-path.stderr8
-rw-r--r--src/test/ui/pub/pub-restricted.rs37
-rw-r--r--src/test/ui/pub/pub-restricted.stderr47
-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
-rw-r--r--src/test/ui/resolve/token-error-correct-3.stderr4
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr8
-rw-r--r--src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr4
-rw-r--r--src/test/ui/span/borrowck-object-mutability.stderr3
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs21
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr10
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs105
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr90
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs27
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr10
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs49
-rw-r--r--src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr26
76 files changed, 1761 insertions, 22 deletions
diff --git a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
index edbfd72df61..7bb69caa102 100644
--- a/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
+++ b/src/test/ui/codemap_tests/huge_multispan_highlight.stderr
@@ -2,7 +2,7 @@ error: cannot borrow immutable local variable `x` as mutable
    --> $DIR/huge_multispan_highlight.rs:100:18
     |
 12  |     let x = "foo";
-    |         - use `mut x` here to make mutable
+    |         - consider changing this to `mut x`
 ...
 100 |     let y = &mut x;
     |                  ^ cannot borrow mutably
diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr
index 4873acf551e..60fa06d314f 100644
--- a/src/test/ui/did_you_mean/issue-31424.stderr
+++ b/src/test/ui/did_you_mean/issue-31424.stderr
@@ -10,6 +10,8 @@ error: cannot borrow immutable argument `self` as mutable
 error: cannot borrow immutable argument `self` as mutable
   --> $DIR/issue-31424.rs:23:15
    |
+22 |     fn bar(self: &mut Self) {
+   |            ---- consider changing this to `mut self`
 23 |         (&mut self).bar();
    |               ^^^^ cannot borrow mutably
 
diff --git a/src/test/ui/did_you_mean/issue-35937.rs b/src/test/ui/did_you_mean/issue-35937.rs
new file mode 100644
index 00000000000..9ec8728fd32
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-35937.rs
@@ -0,0 +1,31 @@
+// Copyright 2017 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.
+
+struct Foo {
+    pub v: Vec<String>
+}
+
+fn main() {
+    let f = Foo { v: Vec::new() };
+    f.v.push("cat".to_string());
+}
+
+
+struct S {
+    x: i32,
+}
+fn foo() {
+    let s = S { x: 42 };
+    s.x += 1;
+}
+
+fn bar(s: S) {
+    s.x += 1;
+}
diff --git a/src/test/ui/did_you_mean/issue-35937.stderr b/src/test/ui/did_you_mean/issue-35937.stderr
new file mode 100644
index 00000000000..bea3d129143
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-35937.stderr
@@ -0,0 +1,26 @@
+error: cannot borrow immutable field `f.v` as mutable
+  --> $DIR/issue-35937.rs:17:5
+   |
+16 |     let f = Foo { v: Vec::new() };
+   |         - consider changing this to `mut f`
+17 |     f.v.push("cat".to_string());
+   |     ^^^ cannot mutably borrow immutable field
+
+error: cannot assign to immutable field `s.x`
+  --> $DIR/issue-35937.rs:26:5
+   |
+25 |     let s = S { x: 42 };
+   |         - consider changing this to `mut s`
+26 |     s.x += 1;
+   |     ^^^^^^^^ cannot mutably borrow immutable field
+
+error: cannot assign to immutable field `s.x`
+  --> $DIR/issue-35937.rs:30:5
+   |
+29 | fn bar(s: S) {
+   |        - consider changing this to `mut s`
+30 |     s.x += 1;
+   |     ^^^^^^^^ cannot mutably borrow immutable field
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr
index fdaf0cd44d9..855feaf7d2d 100644
--- a/src/test/ui/did_you_mean/issue-38147-2.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-2.stderr
@@ -2,7 +2,7 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
   --> $DIR/issue-38147-2.rs:17:9
    |
 12 |     s: &'a String
-   |     ------------- use `&'a mut String` here to make mutable
+   |        ---------- use `&'a mut String` here to make mutable
 ...
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr
index d2280fa561b..d970d078df8 100644
--- a/src/test/ui/did_you_mean/issue-38147-3.stderr
+++ b/src/test/ui/did_you_mean/issue-38147-3.stderr
@@ -2,10 +2,8 @@ error: cannot borrow immutable borrowed content `*self.s` as mutable
   --> $DIR/issue-38147-3.rs:17:9
    |
 12 |     s: &'a String
-   |     ------------- use `&'a mut String` here to make mutable
+   |        ---------- use `&'a mut String` here to make mutable
 ...
-16 |     fn f(&self) {
-   |          ----- use `&mut self` here to make mutable
 17 |         self.s.push('x');
    |         ^^^^^^ cannot borrow as mutable
 
diff --git a/src/test/ui/did_you_mean/issue-39544.rs b/src/test/ui/did_you_mean/issue-39544.rs
index bcdafefa247..6331fc5771f 100644
--- a/src/test/ui/did_you_mean/issue-39544.rs
+++ b/src/test/ui/did_you_mean/issue-39544.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum X {
+pub enum X {
     Y
 }
 
-struct Z {
+pub struct Z {
     x: X
 }
 
@@ -20,3 +20,34 @@ fn main() {
     let z = Z { x: X::Y };
     let _ = &mut z.x;
 }
+
+impl Z {
+    fn foo<'z>(&'z self) {
+        let _ = &mut self.x;
+    }
+
+    fn foo1(&self, other: &Z) {
+        let _ = &mut self.x;
+        let _ = &mut other.x;
+    }
+
+    fn foo2<'a>(&'a self, other: &Z) {
+        let _ = &mut self.x;
+        let _ = &mut other.x;
+    }
+
+    fn foo3<'a>(self: &'a Self, other: &Z) {
+        let _ = &mut self.x;
+        let _ = &mut other.x;
+    }
+
+    fn foo4(other: &Z) {
+        let _ = &mut other.x;
+    }
+
+}
+
+pub fn with_arg(z: Z, w: &Z) {
+    let _ = &mut z.x;
+    let _ = &mut w.x;
+}
diff --git a/src/test/ui/did_you_mean/issue-39544.stderr b/src/test/ui/did_you_mean/issue-39544.stderr
index 7f124e6d34d..e1e229a8b05 100644
--- a/src/test/ui/did_you_mean/issue-39544.stderr
+++ b/src/test/ui/did_you_mean/issue-39544.stderr
@@ -6,5 +6,89 @@ error: cannot borrow immutable field `z.x` as mutable
 21 |     let _ = &mut z.x;
    |                  ^^^ cannot mutably borrow immutable field
 
-error: aborting due to previous error
+error: cannot borrow immutable field `self.x` as mutable
+  --> $DIR/issue-39544.rs:26:22
+   |
+25 |     fn foo<'z>(&'z self) {
+   |                -------- use `&'z mut self` here to make mutable
+26 |         let _ = &mut self.x;
+   |                      ^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `self.x` as mutable
+  --> $DIR/issue-39544.rs:30:22
+   |
+29 |     fn foo1(&self, other: &Z) {
+   |             ----- use `&mut self` here to make mutable
+30 |         let _ = &mut self.x;
+   |                      ^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `other.x` as mutable
+  --> $DIR/issue-39544.rs:31:22
+   |
+29 |     fn foo1(&self, other: &Z) {
+   |                           -- use `&mut Z` here to make mutable
+30 |         let _ = &mut self.x;
+31 |         let _ = &mut other.x;
+   |                      ^^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `self.x` as mutable
+  --> $DIR/issue-39544.rs:35:22
+   |
+34 |     fn foo2<'a>(&'a self, other: &Z) {
+   |                 -------- use `&'a mut self` here to make mutable
+35 |         let _ = &mut self.x;
+   |                      ^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `other.x` as mutable
+  --> $DIR/issue-39544.rs:36:22
+   |
+34 |     fn foo2<'a>(&'a self, other: &Z) {
+   |                                  -- use `&mut Z` here to make mutable
+35 |         let _ = &mut self.x;
+36 |         let _ = &mut other.x;
+   |                      ^^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `self.x` as mutable
+  --> $DIR/issue-39544.rs:40:22
+   |
+39 |     fn foo3<'a>(self: &'a Self, other: &Z) {
+   |                       -------- use `&'a mut Self` here to make mutable
+40 |         let _ = &mut self.x;
+   |                      ^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `other.x` as mutable
+  --> $DIR/issue-39544.rs:41:22
+   |
+39 |     fn foo3<'a>(self: &'a Self, other: &Z) {
+   |                                        -- use `&mut Z` here to make mutable
+40 |         let _ = &mut self.x;
+41 |         let _ = &mut other.x;
+   |                      ^^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `other.x` as mutable
+  --> $DIR/issue-39544.rs:45:22
+   |
+44 |     fn foo4(other: &Z) {
+   |                    -- use `&mut Z` here to make mutable
+45 |         let _ = &mut other.x;
+   |                      ^^^^^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `z.x` as mutable
+  --> $DIR/issue-39544.rs:51:18
+   |
+50 | pub fn with_arg(z: Z, w: &Z) {
+   |                 - consider changing this to `mut z`
+51 |     let _ = &mut z.x;
+   |                  ^^^ cannot mutably borrow immutable field
+
+error: cannot borrow immutable field `w.x` as mutable
+  --> $DIR/issue-39544.rs:52:18
+   |
+50 | pub fn with_arg(z: Z, w: &Z) {
+   |                          -- use `&mut Z` here to make mutable
+51 |     let _ = &mut z.x;
+52 |     let _ = &mut w.x;
+   |                  ^^^ cannot mutably borrow immutable field
+
+error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-40823.rs b/src/test/ui/did_you_mean/issue-40823.rs
new file mode 100644
index 00000000000..f4ae3257279
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40823.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 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.
+
+fn main() {
+    let mut buf = &[1, 2, 3, 4];
+    buf.iter_mut();
+}
diff --git a/src/test/ui/did_you_mean/issue-40823.stderr b/src/test/ui/did_you_mean/issue-40823.stderr
new file mode 100644
index 00000000000..8e77ebd9b6d
--- /dev/null
+++ b/src/test/ui/did_you_mean/issue-40823.stderr
@@ -0,0 +1,8 @@
+error: cannot borrow immutable borrowed content `*buf` as mutable
+  --> $DIR/issue-40823.rs:13:5
+   |
+13 |     buf.iter_mut();
+   |     ^^^ cannot borrow as mutable
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/loop-break-value-no-repeat.rs b/src/test/ui/loop-break-value-no-repeat.rs
new file mode 100644
index 00000000000..790f796fae0
--- /dev/null
+++ b/src/test/ui/loop-break-value-no-repeat.rs
@@ -0,0 +1,25 @@
+// 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(loop_break_value)]
+#![allow(unused_variables)]
+
+use std::ptr;
+
+// Test that we only report **one** error here and that is that
+// `break` with an expression is illegal in this context. In
+// particular, we don't report any mismatched types error, which is
+// besides the point.
+
+fn main() {
+    for _ in &[1,2,3] {
+        break 22
+    }
+}
diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr
new file mode 100644
index 00000000000..0d99abd3907
--- /dev/null
+++ b/src/test/ui/loop-break-value-no-repeat.stderr
@@ -0,0 +1,8 @@
+error[E0571]: `break` with value from a `for` loop
+  --> $DIR/loop-break-value-no-repeat.rs:23:9
+   |
+23 |         break 22
+   |         ^^^^^^^^ can only break with a value inside `loop`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/macro_path_as_generic_bound.stderr b/src/test/ui/macros/macro_path_as_generic_bound.stderr
index 96635032105..e4044f5aaf2 100644
--- a/src/test/ui/macros/macro_path_as_generic_bound.stderr
+++ b/src/test/ui/macros/macro_path_as_generic_bound.stderr
@@ -2,10 +2,7 @@ error[E0433]: failed to resolve. Use of undeclared type or module `m`
   --> $DIR/macro_path_as_generic_bound.rs:17:6
    |
 17 | foo!(m::m2::A);
-   | -----^^^^^^^^--
-   | |    |
-   | |    Use of undeclared type or module `m`
-   | in this macro invocation
+   |      ^^^^^^^^ Use of undeclared type or module `m`
 
 error: cannot continue compilation due to previous error
 
diff --git a/src/test/ui/pub/pub-restricted-error-fn.rs b/src/test/ui/pub/pub-restricted-error-fn.rs
new file mode 100644
index 00000000000..13514310371
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-error-fn.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 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(pub_restricted)]
+
+pub(crate) () fn foo() {}
diff --git a/src/test/ui/pub/pub-restricted-error-fn.stderr b/src/test/ui/pub/pub-restricted-error-fn.stderr
new file mode 100644
index 00000000000..470e8331247
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-error-fn.stderr
@@ -0,0 +1,8 @@
+error: unmatched visibility `pub`
+  --> $DIR/pub-restricted-error-fn.rs:13:10
+   |
+13 | pub(crate) () fn foo() {}
+   |          ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-restricted-error.rs b/src/test/ui/pub/pub-restricted-error.rs
new file mode 100644
index 00000000000..99af031899a
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-error.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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(pub_restricted)]
+
+struct Bar(pub(()));
+
+struct Foo {
+    pub(crate) () foo: usize,
+}
+
+
diff --git a/src/test/ui/pub/pub-restricted-error.stderr b/src/test/ui/pub/pub-restricted-error.stderr
new file mode 100644
index 00000000000..b8b4c80778d
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-error.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `(`
+  --> $DIR/pub-restricted-error.rs:16:16
+   |
+16 |     pub(crate) () foo: usize,
+   |                ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-restricted-non-path.rs b/src/test/ui/pub/pub-restricted-non-path.rs
new file mode 100644
index 00000000000..3f74285717a
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-non-path.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 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(pub_restricted)]
+
+pub (.) fn afn() {}
+
+fn main() {}
diff --git a/src/test/ui/pub/pub-restricted-non-path.stderr b/src/test/ui/pub/pub-restricted-non-path.stderr
new file mode 100644
index 00000000000..ebfccc4d720
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted-non-path.stderr
@@ -0,0 +1,8 @@
+error: expected identifier, found `.`
+  --> $DIR/pub-restricted-non-path.rs:13:6
+   |
+13 | pub (.) fn afn() {}
+   |      ^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/pub/pub-restricted.rs b/src/test/ui/pub/pub-restricted.rs
new file mode 100644
index 00000000000..48e487f71a7
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted.rs
@@ -0,0 +1,37 @@
+// Copyright 2017 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(pub_restricted)]
+
+mod a {}
+
+pub (a) fn afn() {}
+pub (b) fn bfn() {}
+pub fn privfn() {}
+mod x {
+    mod y {
+        pub (in x) fn foo() {}
+        pub (super) fn bar() {}
+        pub (crate) fn qux() {}
+    }
+}
+
+mod y {
+    struct Foo {
+        pub (crate) c: usize,
+        pub (super) s: usize,
+        valid_private: usize,
+        pub (in y) valid_in_x: usize,
+        pub (a) invalid: usize,
+        pub (in x) non_parent_invalid: usize,
+    }
+}
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr
new file mode 100644
index 00000000000..5bc230e8da3
--- /dev/null
+++ b/src/test/ui/pub/pub-restricted.stderr
@@ -0,0 +1,47 @@
+error: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:15:5
+   |
+15 | pub (a) fn afn() {}
+   |     ^^^
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+help: to make this visible only to module `a`, add `in` before the path:
+   | pub (in a) fn afn() {}
+
+error: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:16:5
+   |
+16 | pub (b) fn bfn() {}
+   |     ^^^
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+help: to make this visible only to module `b`, add `in` before the path:
+   | pub (in b) fn bfn() {}
+
+error: incorrect visibility restriction
+  --> $DIR/pub-restricted.rs:32:13
+   |
+32 |         pub (a) invalid: usize,
+   |             ^^^
+   |
+   = help: some possible visibility restrictions are:
+           `pub(crate)`: visible only on the current crate
+           `pub(super)`: visible only in the current module's parent
+           `pub(in path::to::module)`: visible only on the specified path
+help: to make this visible only to module `a`, add `in` before the path:
+   |         pub (in a) invalid: usize,
+
+error: visibilities can only be restricted to ancestor modules
+  --> $DIR/pub-restricted.rs:33:17
+   |
+33 |         pub (in x) non_parent_invalid: usize,
+   |                 ^
+
+error: aborting due to 4 previous errors
+
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
+
diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr
index bf7db67e728..849787e383f 100644
--- a/src/test/ui/resolve/token-error-correct-3.stderr
+++ b/src/test/ui/resolve/token-error-correct-3.stderr
@@ -39,10 +39,6 @@ error[E0308]: mismatched types
    |
    = note: expected type `()`
               found type `std::result::Result<bool, std::io::Error>`
-   = help: here are some functions which might fulfill your needs:
-           - .unwrap()
-           - .unwrap_err()
-           - .unwrap_or_default()
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
index b83a6aaebf3..edf1635a6b8 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr
@@ -2,7 +2,7 @@ error: cannot borrow immutable argument `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:63:24
    |
 62 | fn deref_mut_field1(x: Own<Point>) {
-   |                     - use `mut x` here to make mutable
+   |                     - consider changing this to `mut x`
 63 |     let __isize = &mut x.y; //~ ERROR cannot borrow
    |                        ^ cannot borrow mutably
 
@@ -28,7 +28,7 @@ error: cannot borrow immutable argument `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:98:5
    |
 97 | fn assign_field1<'a>(x: Own<Point>) {
-   |                      - use `mut x` here to make mutable
+   |                      - consider changing this to `mut x`
 98 |     x.y = 3; //~ ERROR cannot borrow
    |     ^ cannot borrow mutably
 
@@ -54,7 +54,7 @@ error: cannot borrow immutable argument `x` as mutable
    --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:119:5
     |
 118 | fn deref_mut_method1(x: Own<Point>) {
-    |                      - use `mut x` here to make mutable
+    |                      - consider changing this to `mut x`
 119 |     x.set(0, 0); //~ ERROR cannot borrow
     |     ^ cannot borrow mutably
 
@@ -70,7 +70,7 @@ error: cannot borrow immutable argument `x` as mutable
    --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:139:6
     |
 138 | fn assign_method1<'a>(x: Own<Point>) {
-    |                       - use `mut x` here to make mutable
+    |                       - consider changing this to `mut x`
 139 |     *x.y_mut() = 3; //~ ERROR cannot borrow
     |      ^ cannot borrow mutably
 
diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
index af954a4d792..2ec01168721 100644
--- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
+++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr
@@ -2,7 +2,7 @@ error: cannot borrow immutable argument `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:39:25
    |
 38 | fn deref_mut1(x: Own<isize>) {
-   |               - use `mut x` here to make mutable
+   |               - consider changing this to `mut x`
 39 |     let __isize = &mut *x; //~ ERROR cannot borrow
    |                         ^ cannot borrow mutably
 
@@ -18,7 +18,7 @@ error: cannot borrow immutable argument `x` as mutable
   --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:59:6
    |
 58 | fn assign1<'a>(x: Own<isize>) {
-   |                - use `mut x` here to make mutable
+   |                - consider changing this to `mut x`
 59 |     *x = 3; //~ ERROR cannot borrow
    |      ^ cannot borrow mutably
 
diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr
index 4ef1cb9c239..0abdbdc3a21 100644
--- a/src/test/ui/span/borrowck-object-mutability.stderr
+++ b/src/test/ui/span/borrowck-object-mutability.stderr
@@ -10,6 +10,9 @@ error: cannot borrow immutable borrowed content `*x` as mutable
 error: cannot borrow immutable `Box` content `*x` as mutable
   --> $DIR/borrowck-object-mutability.rs:29:5
    |
+27 | fn owned_receiver(x: Box<Foo>) {
+   |                   - consider changing this to `mut x`
+28 |     x.borrowed();
 29 |     x.borrowed_mut(); //~ ERROR cannot borrow
    |     ^ cannot borrow as mutable
 
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs
new file mode 100644
index 00000000000..fc3c58e5223
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+struct Obj<F> where F: FnMut() -> u32 {
+    closure: F,
+}
+
+fn main() {
+    let o = Obj { closure: || 42 };
+    o.closure();
+    //~^ ERROR no method named `closure` found
+    //~| HELP use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
+    //~| NOTE field, not a method
+}
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
new file mode 100644
index 00000000000..9e5e4adb180
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-18343.stderr
@@ -0,0 +1,10 @@
+error: no method named `closure` found for type `Obj<[closure@$DIR/issue-18343.rs:16:28: 16:33]>` in the current scope
+  --> $DIR/issue-18343.rs:17:7
+   |
+17 |     o.closure();
+   |       ^^^^^^^ field, not a method
+   |
+   = help: use `(o.closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs
new file mode 100644
index 00000000000..f84f35ce84b
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.rs
@@ -0,0 +1,105 @@
+// Copyright 2014 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(core, fnbox)]
+
+use std::boxed::FnBox;
+
+struct FuncContainer {
+    f1: fn(data: u8),
+    f2: extern "C" fn(data: u8),
+    f3: unsafe fn(data: u8),
+}
+
+struct FuncContainerOuter {
+    container: Box<FuncContainer>
+}
+
+struct Obj<F> where F: FnOnce() -> u32 {
+    closure: F,
+    not_closure: usize,
+}
+
+struct BoxedObj {
+    boxed_closure: Box<FnBox() -> u32>,
+}
+
+struct Wrapper<F> where F: FnMut() -> u32 {
+    wrap: Obj<F>,
+}
+
+fn func() -> u32 {
+    0
+}
+
+fn check_expression() -> Obj<Box<FnBox() -> u32>> {
+    Obj { closure: Box::new(|| 42_u32) as Box<FnBox() -> u32>, not_closure: 42 }
+}
+
+fn main() {
+    // test variations of function
+
+    let o_closure = Obj { closure: || 42, not_closure: 42 };
+    o_closure.closure(); //~ ERROR no method named `closure` found
+    //~^ HELP use `(o_closure.closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+
+    o_closure.not_closure();
+    //~^ ERROR no method named `not_closure` found
+    //~| NOTE field, not a method
+    //~| HELP did you mean to write `o_closure.not_closure` instead of `o_closure.not_closure(...)`?
+
+    let o_func = Obj { closure: func, not_closure: 5 };
+    o_func.closure(); //~ ERROR no method named `closure` found
+    //~^ HELP use `(o_func.closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+
+    let boxed_fn = BoxedObj { boxed_closure: Box::new(func) };
+    boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
+    //~^ HELP use `(boxed_fn.boxed_closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+
+    let boxed_closure = BoxedObj { boxed_closure: Box::new(|| 42_u32) as Box<FnBox() -> u32> };
+    boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
+    //~^ HELP use `(boxed_closure.boxed_closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+
+    // test expression writing in the notes
+
+    let w = Wrapper { wrap: o_func };
+    w.wrap.closure();//~ ERROR no method named `closure` found
+    //~^ HELP use `(w.wrap.closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+
+    w.wrap.not_closure();
+    //~^ ERROR no method named `not_closure` found
+    //~| NOTE field, not a method
+    //~| HELP did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
+
+    check_expression().closure();//~ ERROR no method named `closure` found
+    //~^ HELP use `(check_expression().closure)(...)` if you meant to call the function stored
+    //~| NOTE field, not a method
+}
+
+impl FuncContainerOuter {
+    fn run(&self) {
+        unsafe {
+            (*self.container).f1(1); //~ ERROR no method named `f1` found
+            //~^ HELP use `((*self.container).f1)(...)`
+            //~| NOTE field, not a method
+            (*self.container).f2(1); //~ ERROR no method named `f2` found
+            //~^ HELP use `((*self.container).f2)(...)`
+            //~| NOTE field, not a method
+            (*self.container).f3(1); //~ ERROR no method named `f3` found
+            //~^ HELP use `((*self.container).f3)(...)`
+            //~| NOTE field, not a method
+        }
+    }
+}
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
new file mode 100644
index 00000000000..56e1060bdb9
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-2392.stderr
@@ -0,0 +1,90 @@
+error: no method named `closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope
+  --> $DIR/issue-2392.rs:50:15
+   |
+50 |     o_closure.closure(); //~ ERROR no method named `closure` found
+   |               ^^^^^^^ field, not a method
+   |
+   = help: use `(o_closure.closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: no method named `not_closure` found for type `Obj<[closure@$DIR/issue-2392.rs:49:36: 49:41]>` in the current scope
+  --> $DIR/issue-2392.rs:54:15
+   |
+54 |     o_closure.not_closure();
+   |               ^^^^^^^^^^^ field, not a method
+   |
+   = help: did you mean to write `o_closure.not_closure` instead of `o_closure.not_closure(...)`?
+
+error: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
+  --> $DIR/issue-2392.rs:60:12
+   |
+60 |     o_func.closure(); //~ ERROR no method named `closure` found
+   |            ^^^^^^^ field, not a method
+   |
+   = help: use `(o_func.closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: no method named `boxed_closure` found for type `BoxedObj` in the current scope
+  --> $DIR/issue-2392.rs:65:14
+   |
+65 |     boxed_fn.boxed_closure();//~ ERROR no method named `boxed_closure` found
+   |              ^^^^^^^^^^^^^ field, not a method
+   |
+   = help: use `(boxed_fn.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
+
+error: no method named `boxed_closure` found for type `BoxedObj` in the current scope
+  --> $DIR/issue-2392.rs:70:19
+   |
+70 |     boxed_closure.boxed_closure();//~ ERROR no method named `boxed_closure` found
+   |                   ^^^^^^^^^^^^^ field, not a method
+   |
+   = help: use `(boxed_closure.boxed_closure)(...)` if you meant to call the function stored in the `boxed_closure` field
+
+error: no method named `closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
+  --> $DIR/issue-2392.rs:77:12
+   |
+77 |     w.wrap.closure();//~ ERROR no method named `closure` found
+   |            ^^^^^^^ field, not a method
+   |
+   = help: use `(w.wrap.closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: no method named `not_closure` found for type `Obj<fn() -> u32 {func}>` in the current scope
+  --> $DIR/issue-2392.rs:81:12
+   |
+81 |     w.wrap.not_closure();
+   |            ^^^^^^^^^^^ field, not a method
+   |
+   = help: did you mean to write `w.wrap.not_closure` instead of `w.wrap.not_closure(...)`?
+
+error: no method named `closure` found for type `Obj<std::boxed::Box<std::boxed::FnBox<(), Output=u32> + 'static>>` in the current scope
+  --> $DIR/issue-2392.rs:86:24
+   |
+86 |     check_expression().closure();//~ ERROR no method named `closure` found
+   |                        ^^^^^^^ field, not a method
+   |
+   = help: use `(check_expression().closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: no method named `f1` found for type `FuncContainer` in the current scope
+  --> $DIR/issue-2392.rs:94:31
+   |
+94 |             (*self.container).f1(1); //~ ERROR no method named `f1` found
+   |                               ^^ field, not a method
+   |
+   = help: use `((*self.container).f1)(...)` if you meant to call the function stored in the `f1` field
+
+error: no method named `f2` found for type `FuncContainer` in the current scope
+  --> $DIR/issue-2392.rs:97:31
+   |
+97 |             (*self.container).f2(1); //~ ERROR no method named `f2` found
+   |                               ^^ field, not a method
+   |
+   = help: use `((*self.container).f2)(...)` if you meant to call the function stored in the `f2` field
+
+error: no method named `f3` found for type `FuncContainer` in the current scope
+   --> $DIR/issue-2392.rs:100:31
+    |
+100 |             (*self.container).f3(1); //~ ERROR no method named `f3` found
+    |                               ^^ field, not a method
+    |
+    = help: use `((*self.container).f3)(...)` if you meant to call the function stored in the `f3` field
+
+error: aborting due to 11 previous errors
+
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs
new file mode 100644
index 00000000000..2fd7dc246c2
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.rs
@@ -0,0 +1,27 @@
+// 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.
+
+struct Example {
+    example: Box<Fn(i32) -> i32>
+}
+
+fn main() {
+    let demo = Example {
+        example: Box::new(|x| {
+            x + 1
+        })
+    };
+
+    demo.example(1);
+    //~^ ERROR no method named `example`
+    //~| HELP use `(demo.example)(...)`
+    //~| NOTE field, not a method
+    // (demo.example)(1);
+}
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
new file mode 100644
index 00000000000..0d2a895bad1
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-32128.stderr
@@ -0,0 +1,10 @@
+error: no method named `example` found for type `Example` in the current scope
+  --> $DIR/issue-32128.rs:22:10
+   |
+22 |     demo.example(1);
+   |          ^^^^^^^ field, not a method
+   |
+   = help: use `(demo.example)(...)` if you meant to call the function stored in the `example` field
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs
new file mode 100644
index 00000000000..03c84fc57be
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.rs
@@ -0,0 +1,49 @@
+// 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.
+
+use std::ops::Deref;
+
+struct Obj<F> where F: FnMut() -> u32 {
+    fn_ptr: fn() -> (),
+    closure: F,
+}
+
+struct C {
+    c_fn_ptr: fn() -> (),
+}
+
+struct D(C);
+
+impl Deref for D {
+    type Target = C;
+    fn deref(&self) -> &C {
+        &self.0
+    }
+}
+
+
+fn empty() {}
+
+fn main() {
+    let o = Obj { fn_ptr: empty, closure: || 42 };
+    let p = &o;
+    p.closure(); //~ ERROR no method named `closure` found
+    //~^ HELP use `(p.closure)(...)` if you meant to call the function stored in the `closure` field
+    //~| NOTE `closure` is a field storing a function, not a method
+    let q = &p;
+    q.fn_ptr(); //~ ERROR no method named `fn_ptr` found
+    //~^ HELP use `(q.fn_ptr)(...)` if you meant to call the function stored in the `fn_ptr` field
+    //~| NOTE `fn_ptr` is a field storing a function, not a method
+    let r = D(C { c_fn_ptr: empty });
+    let s = &r;
+    s.c_fn_ptr(); //~ ERROR no method named `c_fn_ptr` found
+    //~^ HELP use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr`
+    //~| NOTE `c_fn_ptr` is a field storing a function, not a method
+}
diff --git a/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
new file mode 100644
index 00000000000..70d64e3ffa3
--- /dev/null
+++ b/src/test/ui/suggestions/confuse-field-and-method/issue-33784.stderr
@@ -0,0 +1,26 @@
+error: no method named `closure` found for type `&Obj<[closure@$DIR/issue-33784.rs:35:43: 35:48]>` in the current scope
+  --> $DIR/issue-33784.rs:37:7
+   |
+37 |     p.closure(); //~ ERROR no method named `closure` found
+   |       ^^^^^^^ field, not a method
+   |
+   = help: use `(p.closure)(...)` if you meant to call the function stored in the `closure` field
+
+error: no method named `fn_ptr` found for type `&&Obj<[closure@$DIR/issue-33784.rs:35:43: 35:48]>` in the current scope
+  --> $DIR/issue-33784.rs:41:7
+   |
+41 |     q.fn_ptr(); //~ ERROR no method named `fn_ptr` found
+   |       ^^^^^^ field, not a method
+   |
+   = help: use `(q.fn_ptr)(...)` if you meant to call the function stored in the `fn_ptr` field
+
+error: no method named `c_fn_ptr` found for type `&D` in the current scope
+  --> $DIR/issue-33784.rs:46:7
+   |
+46 |     s.c_fn_ptr(); //~ ERROR no method named `c_fn_ptr` found
+   |       ^^^^^^^^ field, not a method
+   |
+   = help: use `(s.c_fn_ptr)(...)` if you meant to call the function stored in the `c_fn_ptr` field
+
+error: aborting due to 3 previous errors
+