Skip to content

Commit 63ef53f

Browse files
committed
Add E0695 for unlabeled breaks
1 parent 5665980 commit 63ef53f

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed

src/librustc_passes/diagnostics.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,43 @@ let result = loop { // ok!
259259
i += 1;
260260
};
261261
```
262+
"##,
263+
264+
E0695: r##"
265+
A `break` statement without a label appeared inside a labeled block.
266+
267+
Example of erroneous code:
268+
269+
```compile_fail,E0695
270+
# #![feature(label_break_value)]
271+
loop {
272+
'a: {
273+
break;
274+
}
275+
}
276+
```
277+
278+
Make sure to always label the `break`:
279+
280+
```
281+
'l: loop {
282+
'a: {
283+
break 'l;
284+
}
285+
}
286+
```
287+
288+
Or if you want to `break` the labeled block:
289+
290+
```
291+
# #![feature(label_break_value)]
292+
loop {
293+
'a: {
294+
break 'a;
295+
}
296+
break;
297+
}
298+
```
262299
"##
263300
}
264301

src/librustc_passes/loops.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
109109
}
110110

111111
if self.cx == LabeledBlock {
112+
if label.label.is_none() {
113+
struct_span_err!(self.sess, e.span, E0695,
114+
"unlabeled `break` inside of a labeled block")
115+
.span_label(e.span,
116+
"`break` statements that would diverge to or through \
117+
a labeled block need to bear a label")
118+
.emit();
119+
}
112120
return;
113121
}
114122

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Simple unlabeled break should yield in an error
12+
fn unlabeled_break_simple() {
13+
'b: {
14+
break; //~ ERROR unlabeled `break` inside of a labeled block
15+
}
16+
}
17+
18+
// Unlabeled break that would cross a labeled block should yield in an error
19+
fn unlabeled_break_crossing() {
20+
loop {
21+
'b: {
22+
break; //~ ERROR unlabeled `break` inside of a labeled block
23+
}
24+
}
25+
}
26+
27+
pub fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0695]: unlabeled `break` inside of a labeled block
2+
--> $DIR/label_break_value_unlabeled_break.rs:14:9
3+
|
4+
LL | break; //~ ERROR unlabeled `break` inside of a labeled block
5+
| ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label
6+
7+
error[E0695]: unlabeled `break` inside of a labeled block
8+
--> $DIR/label_break_value_unlabeled_break.rs:22:13
9+
|
10+
LL | break; //~ ERROR unlabeled `break` inside of a labeled block
11+
| ^^^^^ `break` statements that would diverge to or through a labeled block need to bear a label
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0695`.

0 commit comments

Comments
 (0)