From 31620fbdea3e1e706a67fa0907167818c4a4419f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 18 Nov 2019 18:31:31 -0800 Subject: [PATCH] Avoid ICE when `break`ing to an unreachable label --- src/librustc_passes/liveness.rs | 13 ++++++++++--- src/test/ui/issues/issue-62480.rs | 10 ++++++++++ src/test/ui/issues/issue-62480.stderr | 8 ++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/issues/issue-62480.rs create mode 100644 src/test/ui/issues/issue-62480.stderr diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index fb06808619f66..6847e45458a0b 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 0000000000000..bc3e6c69a6024 --- /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 0000000000000..de8451ad7df0a --- /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 +