Skip to content

Commit 3a1eb34

Browse files
authored
Rollup merge of rust-lang#63780 - u32i64:issue-63712, r=estebank
Improve diagnostics: break/continue in wrong context - Fix rust-lang#63712 - Use `` `break` `` or `` `continue` `` instead of always `break` in `cannot _...` - Show the enclosing closure or async block we're talking about - `` `break` outside of loop `` -> `` `break` outside of a loop `` for consistency r? @estebank
2 parents f362387 + 600a64b commit 3a1eb34

17 files changed

+87
-73
lines changed

src/librustc_passes/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ be taken. Erroneous code example:
131131
132132
```compile_fail,E0268
133133
fn some_func() {
134-
break; // error: `break` outside of loop
134+
break; // error: `break` outside of a loop
135135
}
136136
```
137137

src/librustc_passes/loops.rs

+18-19
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ use errors::Applicability;
1616
enum Context {
1717
Normal,
1818
Loop(hir::LoopSource),
19-
Closure,
20-
AsyncClosure,
19+
Closure(Span),
20+
AsyncClosure(Span),
2121
LabeledBlock,
2222
AnonConst,
2323
}
@@ -58,11 +58,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
5858
hir::ExprKind::Loop(ref b, _, source) => {
5959
self.with_context(Loop(source), |v| v.visit_block(&b));
6060
}
61-
hir::ExprKind::Closure(_, ref function_decl, b, _, movability) => {
61+
hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
6262
let cx = if let Some(GeneratorMovability::Static) = movability {
63-
AsyncClosure
63+
AsyncClosure(span)
6464
} else {
65-
Closure
65+
Closure(span)
6666
};
6767
self.visit_fn_decl(&function_decl);
6868
self.with_context(cx, |v| v.visit_nested_body(b));
@@ -170,23 +170,22 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
170170
}
171171

172172
fn require_break_cx(&self, name: &str, span: Span) {
173-
match self.cx {
174-
LabeledBlock | Loop(_) => {}
175-
Closure => {
176-
struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name)
177-
.span_label(span, "cannot break inside of a closure")
173+
let err_inside_of = |article, ty, closure_span| {
174+
struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, ty)
175+
.span_label(span, format!("cannot `{}` inside of {} {}", name, article, ty))
176+
.span_label(closure_span, &format!("enclosing {}", ty))
178177
.emit();
179-
}
180-
AsyncClosure => {
181-
struct_span_err!(self.sess, span, E0267, "`{}` inside of an async block", name)
182-
.span_label(span, "cannot break inside of an async block")
183-
.emit();
184-
}
178+
};
179+
180+
match self.cx {
181+
LabeledBlock | Loop(_) => {},
182+
Closure(closure_span) => err_inside_of("a", "closure", closure_span),
183+
AsyncClosure(closure_span) => err_inside_of("an", "`async` block", closure_span),
185184
Normal | AnonConst => {
186-
struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
187-
.span_label(span, "cannot break outside of a loop")
185+
struct_span_err!(self.sess, span, E0268, "`{}` outside of a loop", name)
186+
.span_label(span, format!("cannot `{}` outside of a loop", name))
188187
.emit();
189-
}
188+
},
190189
}
191190
}
192191

src/test/ui/array-break-length.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
fn main() {
22
loop {
3-
|_: [_; break]| {} //~ ERROR: `break` outside of loop
3+
|_: [_; break]| {} //~ ERROR: `break` outside of a loop
44
//~^ ERROR mismatched types
55
}
66

77
loop {
8-
|_: [_; continue]| {} //~ ERROR: `continue` outside of loop
8+
|_: [_; continue]| {} //~ ERROR: `continue` outside of a loop
99
//~^ ERROR mismatched types
1010
}
1111
}

src/test/ui/array-break-length.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0268]: `break` outside of loop
1+
error[E0268]: `break` outside of a loop
22
--> $DIR/array-break-length.rs:3:17
33
|
44
LL | |_: [_; break]| {}
5-
| ^^^^^ cannot break outside of a loop
5+
| ^^^^^ cannot `break` outside of a loop
66

7-
error[E0268]: `continue` outside of loop
7+
error[E0268]: `continue` outside of a loop
88
--> $DIR/array-break-length.rs:8:17
99
|
1010
LL | |_: [_; continue]| {}
11-
| ^^^^^^^^ cannot break outside of a loop
11+
| ^^^^^^^^ cannot `continue` outside of a loop
1212

1313
error[E0308]: mismatched types
1414
--> $DIR/array-break-length.rs:3:9

src/test/ui/async-await/async-block-control-flow-static-semantics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
3030

3131
fn no_break_in_async_block() {
3232
async {
33-
break 0u8; //~ ERROR `break` inside of an async block
33+
break 0u8; //~ ERROR `break` inside of an `async` block
3434
};
3535
}
3636

3737
fn no_break_in_async_block_even_with_outer_loop() {
3838
loop {
3939
async {
40-
break 0u8; //~ ERROR `break` inside of an async block
40+
break 0u8; //~ ERROR `break` inside of an `async` block
4141
};
4242
}
4343
}

src/test/ui/async-await/async-block-control-flow-static-semantics.stderr

+14-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
error[E0267]: `break` inside of an async block
1+
error[E0267]: `break` inside of an `async` block
22
--> $DIR/async-block-control-flow-static-semantics.rs:33:9
33
|
4-
LL | break 0u8;
5-
| ^^^^^^^^^ cannot break inside of an async block
4+
LL | async {
5+
| ___________-
6+
LL | | break 0u8;
7+
| | ^^^^^^^^^ cannot `break` inside of an `async` block
8+
LL | | };
9+
| |_____- enclosing `async` block
610

7-
error[E0267]: `break` inside of an async block
11+
error[E0267]: `break` inside of an `async` block
812
--> $DIR/async-block-control-flow-static-semantics.rs:40:13
913
|
10-
LL | break 0u8;
11-
| ^^^^^^^^^ cannot break inside of an async block
14+
LL | async {
15+
| _______________-
16+
LL | | break 0u8;
17+
| | ^^^^^^^^^ cannot `break` inside of an `async` block
18+
LL | | };
19+
| |_________- enclosing `async` block
1220

1321
error[E0308]: mismatched types
1422
--> $DIR/async-block-control-flow-static-semantics.rs:13:43

src/test/ui/break-outside-loop.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ fn cond() -> bool { true }
77
fn foo<F>(_: F) where F: FnOnce() {}
88

99
fn main() {
10-
let pth = break; //~ ERROR: `break` outside of loop
11-
if cond() { continue } //~ ERROR: `continue` outside of loop
10+
let pth = break; //~ ERROR: `break` outside of a loop
11+
if cond() { continue } //~ ERROR: `continue` outside of a loop
1212

1313
while cond() {
1414
if cond() { break }
@@ -21,5 +21,5 @@ fn main() {
2121

2222
let rs: Foo = Foo{t: pth};
2323

24-
let unconstrained = break; //~ ERROR: `break` outside of loop
24+
let unconstrained = break; //~ ERROR: `break` outside of a loop
2525
}

src/test/ui/break-outside-loop.stderr

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
1-
error[E0268]: `break` outside of loop
1+
error[E0268]: `break` outside of a loop
22
--> $DIR/break-outside-loop.rs:10:15
33
|
44
LL | let pth = break;
5-
| ^^^^^ cannot break outside of a loop
5+
| ^^^^^ cannot `break` outside of a loop
66

7-
error[E0268]: `continue` outside of loop
7+
error[E0268]: `continue` outside of a loop
88
--> $DIR/break-outside-loop.rs:11:17
99
|
1010
LL | if cond() { continue }
11-
| ^^^^^^^^ cannot break outside of a loop
11+
| ^^^^^^^^ cannot `continue` outside of a loop
1212

1313
error[E0267]: `break` inside of a closure
1414
--> $DIR/break-outside-loop.rs:17:25
1515
|
16+
LL | foo(|| {
17+
| -- enclosing closure
1618
LL | if cond() { break }
17-
| ^^^^^ cannot break inside of a closure
19+
| ^^^^^ cannot `break` inside of a closure
1820

1921
error[E0267]: `continue` inside of a closure
2022
--> $DIR/break-outside-loop.rs:18:25
2123
|
24+
LL | foo(|| {
25+
| -- enclosing closure
26+
LL | if cond() { break }
2227
LL | if cond() { continue }
23-
| ^^^^^^^^ cannot break inside of a closure
28+
| ^^^^^^^^ cannot `continue` inside of a closure
2429

25-
error[E0268]: `break` outside of loop
30+
error[E0268]: `break` outside of a loop
2631
--> $DIR/break-outside-loop.rs:24:25
2732
|
2833
LL | let unconstrained = break;
29-
| ^^^^^ cannot break outside of a loop
34+
| ^^^^^ cannot `break` outside of a loop
3035

3136
error: aborting due to 5 previous errors
3237

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
fn main() {
2-
|_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
2+
|_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop
33

4-
while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
4+
while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop
55
//~^ ERROR mismatched types
66

7-
while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
7+
while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop
88
//~^ ERROR mismatched types
99
}

src/test/ui/closures/closure-array-break-length.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error[E0268]: `continue` outside of loop
1+
error[E0268]: `continue` outside of a loop
22
--> $DIR/closure-array-break-length.rs:2:13
33
|
44
LL | |_: [_; continue]| {};
5-
| ^^^^^^^^ cannot break outside of a loop
5+
| ^^^^^^^^ cannot `continue` outside of a loop
66

7-
error[E0268]: `continue` outside of loop
7+
error[E0268]: `continue` outside of a loop
88
--> $DIR/closure-array-break-length.rs:4:19
99
|
1010
LL | while |_: [_; continue]| {} {}
11-
| ^^^^^^^^ cannot break outside of a loop
11+
| ^^^^^^^^ cannot `continue` outside of a loop
1212

13-
error[E0268]: `break` outside of loop
13+
error[E0268]: `break` outside of a loop
1414
--> $DIR/closure-array-break-length.rs:7:19
1515
|
1616
LL | while |_: [_; break]| {} {}
17-
| ^^^^^ cannot break outside of a loop
17+
| ^^^^^ cannot `break` outside of a loop
1818

1919
error[E0308]: mismatched types
2020
--> $DIR/closure-array-break-length.rs:4:11

src/test/ui/error-codes/E0267.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error[E0267]: `break` inside of a closure
22
--> $DIR/E0267.rs:2:18
33
|
44
LL | let w = || { break; };
5-
| ^^^^^ cannot break inside of a closure
5+
| -- ^^^^^ cannot `break` inside of a closure
6+
| |
7+
| enclosing closure
68

79
error: aborting due to previous error
810

src/test/ui/error-codes/E0268.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0268]: `break` outside of loop
1+
error[E0268]: `break` outside of a loop
22
--> $DIR/E0268.rs:2:5
33
|
44
LL | break;
5-
| ^^^^^ cannot break outside of a loop
5+
| ^^^^^ cannot `break` outside of a loop
66

77
error: aborting due to previous error
88

src/test/ui/issues/issue-28105.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Make sure that a continue span actually contains the keyword.
22

33
fn main() {
4-
continue //~ ERROR `continue` outside of loop
4+
continue //~ ERROR `continue` outside of a loop
55
;
6-
break //~ ERROR `break` outside of loop
6+
break //~ ERROR `break` outside of a loop
77
;
88
}

src/test/ui/issues/issue-28105.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0268]: `continue` outside of loop
1+
error[E0268]: `continue` outside of a loop
22
--> $DIR/issue-28105.rs:4:5
33
|
44
LL | continue
5-
| ^^^^^^^^ cannot break outside of a loop
5+
| ^^^^^^^^ cannot `continue` outside of a loop
66

7-
error[E0268]: `break` outside of loop
7+
error[E0268]: `break` outside of a loop
88
--> $DIR/issue-28105.rs:6:5
99
|
1010
LL | break
11-
| ^^^^^ cannot break outside of a loop
11+
| ^^^^^ cannot `break` outside of a loop
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/issues/issue-43162.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0268]: `break` outside of loop
1+
error[E0268]: `break` outside of a loop
22
--> $DIR/issue-43162.rs:3:5
33
|
44
LL | break true;
5-
| ^^^^^^^^^^ cannot break outside of a loop
5+
| ^^^^^^^^^^ cannot `break` outside of a loop
66

7-
error[E0268]: `break` outside of loop
7+
error[E0268]: `break` outside of a loop
88
--> $DIR/issue-43162.rs:7:5
99
|
1010
LL | break {};
11-
| ^^^^^^^^ cannot break outside of a loop
11+
| ^^^^^^^^ cannot `break` outside of a loop
1212

1313
error[E0308]: mismatched types
1414
--> $DIR/issue-43162.rs:1:13

src/test/ui/issues/issue-50576.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
44
LL | |bool: [u8; break 'L]| 0;
55
| ^^ undeclared label `'L`
66

7-
error[E0268]: `break` outside of loop
7+
error[E0268]: `break` outside of a loop
88
--> $DIR/issue-50576.rs:2:17
99
|
1010
LL | |bool: [u8; break 'L]| 0;
11-
| ^^^^^^^^ cannot break outside of a loop
11+
| ^^^^^^^^ cannot `break` outside of a loop
1212

13-
error[E0268]: `break` outside of loop
13+
error[E0268]: `break` outside of a loop
1414
--> $DIR/issue-50576.rs:5:16
1515
|
1616
LL | Vec::<[u8; break]>::new();
17-
| ^^^^^ cannot break outside of a loop
17+
| ^^^^^ cannot `break` outside of a loop
1818

1919
error: aborting due to 3 previous errors
2020

src/test/ui/issues/issue-50581.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0268]: `break` outside of loop
1+
error[E0268]: `break` outside of a loop
22
--> $DIR/issue-50581.rs:2:14
33
|
44
LL | |_: [u8; break]| ();
5-
| ^^^^^ cannot break outside of a loop
5+
| ^^^^^ cannot `break` outside of a loop
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)