about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_const_eval/check_match.rs27
-rw-r--r--src/test/compile-fail/uninhabited-patterns.rs8
2 files changed, 30 insertions, 5 deletions
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index 0b1f2465a4d..6f33b4fad76 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -273,7 +273,7 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
     let mut seen = Matrix::empty();
     let mut catchall = None;
     let mut printed_if_let_err = false;
-    for &(ref pats, guard) in arms {
+    for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
         for &(pat, hir_pat) in pats {
             let v = vec![pat];
 
@@ -302,10 +302,27 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
                             let &(ref first_arm_pats, _) = &arms[0];
                             let first_pat = &first_arm_pats[0];
                             let span = first_pat.0.span;
-                            struct_span_err!(cx.tcx.sess, span, E0165,
-                                             "irrefutable while-let pattern")
-                                .span_label(span, &format!("irrefutable pattern"))
-                                .emit();
+
+                            // check which arm we're on.
+                            match arm_index {
+                                // The arm with the user-specified pattern.
+                                0 => {
+                                    let mut diagnostic = Diagnostic::new(Level::Warning,
+                                                                         "unreachable pattern");
+                                    diagnostic.set_span(pat.span);
+                                    cx.tcx.sess.add_lint_diagnostic(
+                                            lint::builtin::UNREACHABLE_PATTERNS,
+                                            hir_pat.id, diagnostic);
+                                },
+                                // The arm with the wildcard pattern.
+                                1 => {
+                                    struct_span_err!(cx.tcx.sess, span, E0165,
+                                                     "irrefutable while-let pattern")
+                                        .span_label(span, &format!("irrefutable pattern"))
+                                        .emit();
+                                },
+                                _ => bug!(),
+                            }
                         },
 
                         hir::MatchSource::ForLoopDesugar |
diff --git a/src/test/compile-fail/uninhabited-patterns.rs b/src/test/compile-fail/uninhabited-patterns.rs
index 0de29f3a8d7..4c894b0bdd3 100644
--- a/src/test/compile-fail/uninhabited-patterns.rs
+++ b/src/test/compile-fail/uninhabited-patterns.rs
@@ -24,6 +24,10 @@ struct NotSoSecretlyEmpty {
     _priv: !,
 }
 
+fn foo() -> Option<NotSoSecretlyEmpty> {
+    None
+}
+
 fn main() {
     let x: &[!] = &[];
 
@@ -45,5 +49,9 @@ fn main() {
         Err(Err(_y)) => (),
         Err(Ok(_y)) => (),  //~ ERROR unreachable pattern
     }
+
+    while let Some(_y) = foo() {
+        //~^ ERROR unreachable pattern
+    }
 }