about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/test/ui/break-while-condition.rs17
-rw-r--r--src/test/ui/break-while-condition.stderr15
3 files changed, 42 insertions, 4 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 70d299437a6..b0766f05913 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3841,10 +3841,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
               let ctxt = BreakableCtxt {
                   // cannot use break with a value from a while loop
                   coerce: None,
-                  may_break: true,
+                  may_break: false,  // Will get updated if/when we find a `break`.
               };
 
-              self.with_breakable_ctxt(expr.id, ctxt, || {
+              let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
                   self.check_expr_has_type_or_error(&cond, tcx.types.bool);
                   let cond_diverging = self.diverges.get();
                   self.check_block_no_value(&body);
@@ -3853,6 +3853,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                   self.diverges.set(cond_diverging);
               });
 
+              if ctxt.may_break {
+                  // No way to know whether it's diverging because
+                  // of a `break` or an outer `break` or `return`.
+                  self.diverges.set(Diverges::Maybe);
+              }
+
               self.tcx.mk_nil()
           }
           hir::ExprLoop(ref body, _, source) => {
@@ -3871,7 +3877,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
               let ctxt = BreakableCtxt {
                   coerce,
-                  may_break: false, // will get updated if/when we find a `break`
+                  may_break: false, // Will get updated if/when we find a `break`.
               };
 
               let (ctxt, ()) = self.with_breakable_ctxt(expr.id, ctxt, || {
@@ -3880,7 +3886,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
               if ctxt.may_break {
                   // No way to know whether it's diverging because
-                  // of a `break` or an outer `break` or `return.
+                  // of a `break` or an outer `break` or `return`.
                   self.diverges.set(Diverges::Maybe);
               }
 
diff --git a/src/test/ui/break-while-condition.rs b/src/test/ui/break-while-condition.rs
new file mode 100644
index 00000000000..cc5d17e42d5
--- /dev/null
+++ b/src/test/ui/break-while-condition.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 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)]
+
+fn main() {
+    let _: ! = { //~ ERROR mismatched types
+        'a: while break 'a {};
+    };
+}
diff --git a/src/test/ui/break-while-condition.stderr b/src/test/ui/break-while-condition.stderr
new file mode 100644
index 00000000000..5abf60c86d3
--- /dev/null
+++ b/src/test/ui/break-while-condition.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/break-while-condition.rs:14:16
+   |
+LL |       let _: ! = { //~ ERROR mismatched types
+   |  ________________^
+LL | |         'a: while break 'a {};
+LL | |     };
+   | |_____^ expected !, found ()
+   |
+   = note: expected type `!`
+              found type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.