about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/_match.rs11
-rw-r--r--src/test/ui/match/match-unreachable-warning-with-diverging-discrim.rs16
-rw-r--r--src/test/ui/match/match-unreachable-warning-with-diverging-discrim.stderr14
-rw-r--r--src/test/ui/reachable/expr_match.rs6
-rw-r--r--src/test/ui/reachable/expr_match.stderr19
-rw-r--r--src/test/ui/unreachable/unwarned-match-on-never.rs24
-rw-r--r--src/test/ui/unreachable/unwarned-match-on-never.stderr28
7 files changed, 64 insertions, 54 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 0cc9924474c..4f155995cd3 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -608,19 +608,20 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
             self.check_expr_has_type_or_error(discrim, discrim_ty);
         };
 
-        // If the discriminant diverges, the match is pointless (e.g.,
-        // `match (return) { }`).
-        self.warn_if_unreachable(expr.id, expr.span, "expression");
-
         // If there are no arms, that is a diverging match; a special case.
         if arms.is_empty() {
             self.diverges.set(self.diverges.get() | Diverges::Always);
             return tcx.types.never;
         }
 
+        if self.diverges.get().always() {
+            for arm in arms {
+                self.warn_if_unreachable(arm.body.id, arm.body.span, "arm");
+            }
+        }
+
         // Otherwise, we have to union together the types that the
         // arms produce and so forth.
-
         let discrim_diverges = self.diverges.get();
         self.diverges.set(Diverges::Maybe);
 
diff --git a/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.rs b/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.rs
deleted file mode 100644
index aae0f3135d8..00000000000
--- a/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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_parens)]
-#![deny(unreachable_code)]
-
-fn main() {
-    match (return) { } //~ ERROR unreachable expression
-}
diff --git a/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.stderr b/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.stderr
deleted file mode 100644
index 10a86f92fe1..00000000000
--- a/src/test/ui/match/match-unreachable-warning-with-diverging-discrim.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: unreachable expression
-  --> $DIR/match-unreachable-warning-with-diverging-discrim.rs:15:5
-   |
-LL |     match (return) { } //~ ERROR unreachable expression
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-note: lint level defined here
-  --> $DIR/match-unreachable-warning-with-diverging-discrim.rs:12:9
-   |
-LL | #![deny(unreachable_code)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/reachable/expr_match.rs b/src/test/ui/reachable/expr_match.rs
index 2faa262d110..73f26129805 100644
--- a/src/test/ui/reachable/expr_match.rs
+++ b/src/test/ui/reachable/expr_match.rs
@@ -13,12 +13,6 @@
 #![allow(dead_code)]
 #![deny(unreachable_code)]
 
-fn a() {
-    // The match is considered unreachable here, because the `return`
-    // diverges:
-    match {return} { } //~ ERROR unreachable
-}
-
 fn b() {
     match () { () => return }
     println!("I am dead");
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index 240341232d8..fe1a0c4ea11 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -1,30 +1,23 @@
-error: unreachable expression
-  --> $DIR/expr_match.rs:19:5
+error: unreachable statement
+  --> $DIR/expr_match.rs:18:5
    |
-LL |     match {return} { } //~ ERROR unreachable
-   |     ^^^^^^^^^^^^^^^^^^
+LL |     println!("I am dead");
+   |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/expr_match.rs:14:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-
-error: unreachable statement
-  --> $DIR/expr_match.rs:24:5
-   |
-LL |     println!("I am dead");
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: unreachable statement
-  --> $DIR/expr_match.rs:35:5
+  --> $DIR/expr_match.rs:29:5
    |
 LL |     println!("I am dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.rs b/src/test/ui/unreachable/unwarned-match-on-never.rs
new file mode 100644
index 00000000000..71f8fe3a783
--- /dev/null
+++ b/src/test/ui/unreachable/unwarned-match-on-never.rs
@@ -0,0 +1,24 @@
+#![deny(unreachable_code)]
+#![allow(dead_code)]
+
+#![feature(never_type)]
+
+fn foo(x: !) -> bool {
+    // Explicit matches on the never type are unwarned.
+    match x {}
+    // But matches in unreachable code are warned.
+    match x {} //~ ERROR unreachable expression
+}
+
+fn bar() {
+    match (return) {
+        () => () //~ ERROR unreachable arm
+    }
+}
+
+fn main() {
+    return;
+    match () { //~ ERROR unreachable expression
+        () => (),
+    }
+}
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.stderr b/src/test/ui/unreachable/unwarned-match-on-never.stderr
new file mode 100644
index 00000000000..8807e5f04e5
--- /dev/null
+++ b/src/test/ui/unreachable/unwarned-match-on-never.stderr
@@ -0,0 +1,28 @@
+error: unreachable expression
+  --> $DIR/unwarned-match-on-never.rs:10:5
+   |
+LL |     match x {} //~ ERROR unreachable expression
+   |     ^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unwarned-match-on-never.rs:1:9
+   |
+LL | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: unreachable arm
+  --> $DIR/unwarned-match-on-never.rs:15:15
+   |
+LL |         () => () //~ ERROR unreachable arm
+   |               ^^
+
+error: unreachable expression
+  --> $DIR/unwarned-match-on-never.rs:21:5
+   |
+LL | /     match () { //~ ERROR unreachable expression
+LL | |         () => (),
+LL | |     }
+   | |_____^
+
+error: aborting due to 3 previous errors
+