From 63ef53f21d326feb3b244772c452f5ac2632ef6c Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 12 May 2018 09:52:20 +0200 Subject: [PATCH] Add E0695 for unlabeled breaks --- src/librustc_passes/diagnostics.rs | 37 +++++++++++++++++++ src/librustc_passes/loops.rs | 8 ++++ .../ui/label_break_value_unlabeled_break.rs | 27 ++++++++++++++ .../label_break_value_unlabeled_break.stderr | 15 ++++++++ 4 files changed, 87 insertions(+) create mode 100644 src/test/ui/label_break_value_unlabeled_break.rs create mode 100644 src/test/ui/label_break_value_unlabeled_break.stderr diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 7a54fc72d53..4434def85ba 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -259,6 +259,43 @@ fn foo() {} i += 1; }; ``` +"##, + +E0695: r##" +A `break` statement without a label appeared inside a labeled block. + +Example of erroneous code: + +```compile_fail,E0695 +# #![feature(label_break_value)] +loop { + 'a: { + break; + } +} +``` + +Make sure to always label the `break`: + +``` +'l: loop { + 'a: { + break 'l; + } +} +``` + +Or if you want to `break` the labeled block: + +``` +# #![feature(label_break_value)] +loop { + 'a: { + break 'a; + } + break; +} +``` "## } diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 34a3f5e54b8..2d240a7cf2f 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -109,6 +109,14 @@ fn visit_expr(&mut self, e: &'hir hir::Expr) { } if self.cx == LabeledBlock { + if label.label.is_none() { + struct_span_err!(self.sess, e.span, E0695, + "unlabeled `break` inside of a labeled block") + .span_label(e.span, + "`break` statements that would diverge to or through \ + a labeled block need to bear a label") + .emit(); + } return; } diff --git a/src/test/ui/label_break_value_unlabeled_break.rs b/src/test/ui/label_break_value_unlabeled_break.rs new file mode 100644 index 00000000000..b88c23d246e --- /dev/null +++ b/src/test/ui/label_break_value_unlabeled_break.rs @@ -0,0 +1,27 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Simple unlabeled break should yield in an error +fn unlabeled_break_simple() { + 'b: { + break; //~ ERROR unlabeled `break` inside of a labeled block + } +} + +// Unlabeled break that would cross a labeled block should yield in an error +fn unlabeled_break_crossing() { + loop { + 'b: { + break; //~ ERROR unlabeled `break` inside of a labeled block + } + } +} + +pub fn main() {} diff --git a/src/test/ui/label_break_value_unlabeled_break.stderr b/src/test/ui/label_break_value_unlabeled_break.stderr new file mode 100644 index 00000000000..24b2f190757 --- /dev/null +++ b/src/test/ui/label_break_value_unlabeled_break.stderr @@ -0,0 +1,15 @@ +error[E0695]: unlabeled `break` inside of a labeled block + --> $DIR/label_break_value_unlabeled_break.rs:14:9 + | +LL | break; //~ ERROR unlabeled `break` inside of a labeled block + | ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label + +error[E0695]: unlabeled `break` inside of a labeled block + --> $DIR/label_break_value_unlabeled_break.rs:22:13 + | +LL | break; //~ ERROR unlabeled `break` inside of a labeled block + | ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0695`. -- 2.44.0