about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2020-10-22 23:12:46 +0100
committervarkor <github@varkor.com>2020-10-22 23:12:46 +0100
commitd1c2815d6aa131182aa93603de215d63c52d0c53 (patch)
treec8fee55f49b06975b367dad1f24770316ba48ac8
parentd415fae8b76cddbcd7825cb6642186a833453b3c (diff)
downloadrust-d1c2815d6aa131182aa93603de215d63c52d0c53.tar.gz
rust-d1c2815d6aa131182aa93603de215d63c52d0c53.zip
Use `diverges` instead of `!`-type
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--src/test/ui/break-diverging-value.rs5
-rw-r--r--src/test/ui/break-diverging-value.stderr21
3 files changed, 6 insertions, 22 deletions
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 15820d367c0..dce3be9399d 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -630,7 +630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // If we encountered a `break`, then (no surprise) it may be possible to break from the
             // loop... unless the value being returned from the loop diverges itself, e.g.
             // `break return 5` or `break loop {}`.
-            ctxt.may_break |= !e_ty.is_never();
+            ctxt.may_break |= !self.diverges.get().is_always();
 
             // the type of a `break` is always `!`, since it diverges
             tcx.types.never
diff --git a/src/test/ui/break-diverging-value.rs b/src/test/ui/break-diverging-value.rs
index 0117abeb105..d070fddaffc 100644
--- a/src/test/ui/break-diverging-value.rs
+++ b/src/test/ui/break-diverging-value.rs
@@ -12,9 +12,8 @@ fn loop_break_break() -> i32 { //~ ERROR mismatched types
     let loop_value = loop { break break };
 }
 
-fn loop_break_return_2() -> i32 { //~ ERROR mismatched types
-    let loop_value = loop { break { return; () } };
-    //~^ ERROR `return;` in a function whose return type is not `()`
+fn loop_break_return_2() -> i32 {
+    let loop_value = loop { break { return 0; () } }; // ok
 }
 
 enum Void {}
diff --git a/src/test/ui/break-diverging-value.stderr b/src/test/ui/break-diverging-value.stderr
index de3f9bd778a..69edcd24080 100644
--- a/src/test/ui/break-diverging-value.stderr
+++ b/src/test/ui/break-diverging-value.stderr
@@ -6,29 +6,14 @@ LL | fn loop_break_break() -> i32 {
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
-error[E0069]: `return;` in a function whose return type is not `()`
-  --> $DIR/break-diverging-value.rs:16:37
-   |
-LL |     let loop_value = loop { break { return; () } };
-   |                                     ^^^^^^ return type is not `()`
-
-error[E0308]: mismatched types
-  --> $DIR/break-diverging-value.rs:15:29
-   |
-LL | fn loop_break_return_2() -> i32 {
-   |    -------------------      ^^^ expected `i32`, found `()`
-   |    |
-   |    implicitly returns `()` as its body has no tail or `return` expression
-
 error[E0308]: mismatched types
-  --> $DIR/break-diverging-value.rs:26:25
+  --> $DIR/break-diverging-value.rs:25:25
    |
 LL | fn loop_break_void() -> i32 {
    |    ---------------      ^^^ expected `i32`, found `()`
    |    |
    |    implicitly returns `()` as its body has no tail or `return` expression
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0069, E0308.
-For more information about an error, try `rustc --explain E0069`.
+For more information about this error, try `rustc --explain E0308`.