about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-11-18 18:31:31 -0800
committerEsteban Küber <esteban@kuber.com.ar>2019-11-18 18:33:57 -0800
commit31620fbdea3e1e706a67fa0907167818c4a4419f (patch)
tree6c291eb3dd6669401c32e188ccaccb36fffdad8c
parenta0d40f8bdfcc3c28355467973f97fd4c45ac5876 (diff)
downloadrust-31620fbdea3e1e706a67fa0907167818c4a4419f.tar.gz
rust-31620fbdea3e1e706a67fa0907167818c4a4419f.zip
Avoid ICE when `break`ing to an unreachable label
-rw-r--r--src/librustc_passes/liveness.rs13
-rw-r--r--src/test/ui/issues/issue-62480.rs10
-rw-r--r--src/test/ui/issues/issue-62480.stderr8
3 files changed, 28 insertions, 3 deletions
diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs
index fb06808619f..6847e45458a 100644
--- a/src/librustc_passes/liveness.rs
+++ b/src/librustc_passes/liveness.rs
@@ -987,8 +987,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         opt_expr.map_or(succ, |expr| self.propagate_through_expr(expr, succ))
     }
 
-    fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
-                              -> LiveNode {
+    fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode) -> LiveNode {
         debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id));
 
         match expr.kind {
@@ -1074,7 +1073,15 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
                 match target {
                     Some(b) => self.propagate_through_opt_expr(opt_expr.as_ref().map(|e| &**e), b),
-                    None => span_bug!(expr.span, "break to unknown label")
+                    None => {
+                        // FIXME: This should have been checked earlier. Once this is fixed,
+                        // replace with `delay_span_bug`. (#62480)
+                        self.ir.tcx.sess.struct_span_err(
+                            expr.span,
+                            "`break` to unknown label",
+                        ).emit();
+                        errors::FatalError.raise()
+                    }
                 }
             }
 
diff --git a/src/test/ui/issues/issue-62480.rs b/src/test/ui/issues/issue-62480.rs
new file mode 100644
index 00000000000..bc3e6c69a60
--- /dev/null
+++ b/src/test/ui/issues/issue-62480.rs
@@ -0,0 +1,10 @@
+#![feature(label_break_value)]
+
+fn main() {
+    // This used to ICE during liveness check because `target_id` passed to
+    // `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in
+    // `self.break_ln`. (#62480)
+    'a: {
+        || break 'a //~ ERROR `break` to unknown label
+    }
+}
diff --git a/src/test/ui/issues/issue-62480.stderr b/src/test/ui/issues/issue-62480.stderr
new file mode 100644
index 00000000000..de8451ad7df
--- /dev/null
+++ b/src/test/ui/issues/issue-62480.stderr
@@ -0,0 +1,8 @@
+error: `break` to unknown label
+  --> $DIR/issue-62480.rs:8:12
+   |
+LL |         || break 'a
+   |            ^^^^^^^^
+
+error: aborting due to previous error
+