Skip to content

Commit 87fb0ad

Browse files
authored
Rollup merge of #63387 - Centril:async-block-control-flow-tests, r=cramertj
Test interaction between `async { ... }` and `?`, `return`, and `break` Per the second checkbox in #62121 (comment), test that `async { .. }` blocks: 1. do not allow `break` expressions. 2. get targeted by `return` and not the parent function. 3. get targeted by `?` and not the parent function. Works towards resolving blockers in #63209. r? @cramertj
2 parents c9dd930 + 48fbf48 commit 87fb0ad

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Test that `async { .. }` blocks:
2+
// 1. do not allow `break` expressions.
3+
// 2. get targeted by `return` and not the parent function.
4+
// 3. get targeted by `?` and not the parent function.
5+
//
6+
// edition:2018
7+
// ignore-tidy-linelength
8+
9+
#![feature(async_await)]
10+
11+
fn main() {}
12+
13+
use core::future::Future;
14+
15+
fn return_targets_async_block_not_fn() -> u8 {
16+
//~^ ERROR mismatched types
17+
let block = async {
18+
return 0u8;
19+
};
20+
let _: &dyn Future<Output = ()> = &block;
21+
//~^ ERROR type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
22+
}
23+
24+
async fn return_targets_async_block_not_async_fn() -> u8 {
25+
//~^ ERROR type mismatch resolving
26+
let block = async {
27+
return 0u8;
28+
};
29+
let _: &dyn Future<Output = ()> = &block;
30+
//~^ ERROR type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
31+
}
32+
33+
fn no_break_in_async_block() {
34+
async {
35+
break 0u8; //~ ERROR `break` inside of a closure
36+
// FIXME: This diagnostic is pretty bad.
37+
};
38+
}
39+
40+
fn no_break_in_async_block_even_with_outer_loop() {
41+
loop {
42+
async {
43+
break 0u8; //~ ERROR `break` inside of a closure
44+
};
45+
}
46+
}
47+
48+
struct MyErr;
49+
fn err() -> Result<u8, MyErr> { Err(MyErr) }
50+
51+
fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
52+
//~^ ERROR mismatched types
53+
let block = async {
54+
err()?;
55+
Ok(())
56+
};
57+
let _: &dyn Future<Output = Result<(), MyErr>> = &block;
58+
}
59+
60+
fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
61+
//~^ ERROR mismatched types
62+
let block = async {
63+
err()?;
64+
Ok(())
65+
};
66+
let _: &dyn Future<Output = Result<(), MyErr>> = &block;
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
error[E0267]: `break` inside of a closure
2+
--> $DIR/async-block-control-flow-static-semantics.rs:35:9
3+
|
4+
LL | break 0u8;
5+
| ^^^^^^^^^ cannot break inside of a closure
6+
7+
error[E0267]: `break` inside of a closure
8+
--> $DIR/async-block-control-flow-static-semantics.rs:43:13
9+
|
10+
LL | break 0u8;
11+
| ^^^^^^^^^ cannot break inside of a closure
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/async-block-control-flow-static-semantics.rs:15:43
15+
|
16+
LL | fn return_targets_async_block_not_fn() -> u8 {
17+
| --------------------------------- ^^ expected u8, found ()
18+
| |
19+
| this function's body doesn't return
20+
|
21+
= note: expected type `u8`
22+
found type `()`
23+
24+
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
25+
--> $DIR/async-block-control-flow-static-semantics.rs:20:39
26+
|
27+
LL | let _: &dyn Future<Output = ()> = &block;
28+
| ^^^^^^ expected u8, found ()
29+
|
30+
= note: expected type `u8`
31+
found type `()`
32+
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
33+
34+
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
35+
--> $DIR/async-block-control-flow-static-semantics.rs:29:39
36+
|
37+
LL | let _: &dyn Future<Output = ()> = &block;
38+
| ^^^^^^ expected u8, found ()
39+
|
40+
= note: expected type `u8`
41+
found type `()`
42+
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
43+
44+
error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == u8`
45+
--> $DIR/async-block-control-flow-static-semantics.rs:24:55
46+
|
47+
LL | async fn return_targets_async_block_not_async_fn() -> u8 {
48+
| ^^ expected (), found u8
49+
|
50+
= note: expected type `()`
51+
found type `u8`
52+
= note: the return type of a function must have a statically known size
53+
54+
error[E0308]: mismatched types
55+
--> $DIR/async-block-control-flow-static-semantics.rs:51:44
56+
|
57+
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
58+
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
59+
| |
60+
| this function's body doesn't return
61+
|
62+
= note: expected type `std::result::Result<u8, MyErr>`
63+
found type `()`
64+
65+
error[E0308]: mismatched types
66+
--> $DIR/async-block-control-flow-static-semantics.rs:60:50
67+
|
68+
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
69+
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
70+
| |
71+
| this function's body doesn't return
72+
|
73+
= note: expected type `std::result::Result<u8, MyErr>`
74+
found type `()`
75+
76+
error: aborting due to 8 previous errors
77+
78+
Some errors have detailed explanations: E0267, E0271, E0308.
79+
For more information about an error, try `rustc --explain E0267`.

0 commit comments

Comments
 (0)