Skip to content

Commit 1e02bc6

Browse files
committed
Better error message for break in async blocks.
1 parent 9dd5c19 commit 1e02bc6

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

src/librustc_passes/loops.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc::ty::TyCtxt;
77
use rustc::hir::def_id::DefId;
88
use rustc::hir::map::Map;
99
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
10-
use rustc::hir::{self, Node, Destination};
10+
use rustc::hir::{self, Node, Destination, GeneratorMovability};
1111
use syntax::struct_span_err;
1212
use syntax_pos::Span;
1313
use errors::Applicability;
@@ -17,6 +17,7 @@ enum Context {
1717
Normal,
1818
Loop(hir::LoopSource),
1919
Closure,
20+
AsyncClosure,
2021
LabeledBlock,
2122
AnonConst,
2223
}
@@ -57,9 +58,14 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
5758
hir::ExprKind::Loop(ref b, _, source) => {
5859
self.with_context(Loop(source), |v| v.visit_block(&b));
5960
}
60-
hir::ExprKind::Closure(_, ref function_decl, b, _, _) => {
61+
hir::ExprKind::Closure(_, ref function_decl, b, _, movability) => {
62+
let cx = if let Some(GeneratorMovability::Static) = movability {
63+
AsyncClosure
64+
} else {
65+
Closure
66+
};
6167
self.visit_fn_decl(&function_decl);
62-
self.with_context(Closure, |v| v.visit_nested_body(b));
68+
self.with_context(cx, |v| v.visit_nested_body(b));
6369
}
6470
hir::ExprKind::Block(ref b, Some(_label)) => {
6571
self.with_context(LabeledBlock, |v| v.visit_block(&b));
@@ -171,6 +177,11 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
171177
.span_label(span, "cannot break inside of a closure")
172178
.emit();
173179
}
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+
}
174185
Normal | AnonConst => {
175186
struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
176187
.span_label(span, "cannot break outside of a loop")

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
3232

3333
fn no_break_in_async_block() {
3434
async {
35-
break 0u8; //~ ERROR `break` inside of a closure
36-
// FIXME: This diagnostic is pretty bad.
35+
break 0u8; //~ ERROR `break` inside of an async block
3736
};
3837
}
3938

4039
fn no_break_in_async_block_even_with_outer_loop() {
4140
loop {
4241
async {
43-
break 0u8; //~ ERROR `break` inside of a closure
42+
break 0u8; //~ ERROR `break` inside of an async block
4443
};
4544
}
4645
}

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0267]: `break` inside of a closure
1+
error[E0267]: `break` inside of an async block
22
--> $DIR/async-block-control-flow-static-semantics.rs:35:9
33
|
44
LL | break 0u8;
5-
| ^^^^^^^^^ cannot break inside of a closure
5+
| ^^^^^^^^^ cannot break inside of an async block
66

7-
error[E0267]: `break` inside of a closure
8-
--> $DIR/async-block-control-flow-static-semantics.rs:43:13
7+
error[E0267]: `break` inside of an async block
8+
--> $DIR/async-block-control-flow-static-semantics.rs:42:13
99
|
1010
LL | break 0u8;
11-
| ^^^^^^^^^ cannot break inside of a closure
11+
| ^^^^^^^^^ cannot break inside of an async block
1212

1313
error[E0308]: mismatched types
1414
--> $DIR/async-block-control-flow-static-semantics.rs:15:43
@@ -52,7 +52,7 @@ LL | async fn return_targets_async_block_not_async_fn() -> u8 {
5252
= note: the return type of a function must have a statically known size
5353

5454
error[E0308]: mismatched types
55-
--> $DIR/async-block-control-flow-static-semantics.rs:51:44
55+
--> $DIR/async-block-control-flow-static-semantics.rs:50:44
5656
|
5757
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
5858
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
@@ -63,7 +63,7 @@ LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
6363
found type `()`
6464

6565
error[E0308]: mismatched types
66-
--> $DIR/async-block-control-flow-static-semantics.rs:60:50
66+
--> $DIR/async-block-control-flow-static-semantics.rs:59:50
6767
|
6868
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
6969
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()

0 commit comments

Comments
 (0)