Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test interaction between async { ... } and ?, return, and break #63387

Merged
merged 1 commit into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// 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.
//
// edition:2018
// ignore-tidy-linelength

#![feature(async_await)]

fn main() {}

use core::future::Future;

fn return_targets_async_block_not_fn() -> u8 {
//~^ ERROR mismatched types
let block = async {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
}

async fn return_targets_async_block_not_async_fn() -> u8 {
//~^ ERROR type mismatch resolving
let block = async {
return 0u8;
};
let _: &dyn Future<Output = ()> = &block;
//~^ ERROR type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
}

fn no_break_in_async_block() {
async {
break 0u8; //~ ERROR `break` inside of a closure
// FIXME: This diagnostic is pretty bad.
};
}

fn no_break_in_async_block_even_with_outer_loop() {
loop {
async {
break 0u8; //~ ERROR `break` inside of a closure
};
}
}

struct MyErr;
fn err() -> Result<u8, MyErr> { Err(MyErr) }

fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
//~^ ERROR mismatched types
let block = async {
err()?;
Ok(())
};
let _: &dyn Future<Output = Result<(), MyErr>> = &block;
}

fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
//~^ ERROR mismatched types
let block = async {
err()?;
Ok(())
};
let _: &dyn Future<Output = Result<(), MyErr>> = &block;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
error[E0267]: `break` inside of a closure
--> $DIR/async-block-control-flow-static-semantics.rs:35:9
|
LL | break 0u8;
| ^^^^^^^^^ cannot break inside of a closure

error[E0267]: `break` inside of a closure
--> $DIR/async-block-control-flow-static-semantics.rs:43:13
|
LL | break 0u8;
| ^^^^^^^^^ cannot break inside of a closure

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:15:43
|
LL | fn return_targets_async_block_not_fn() -> u8 {
| --------------------------------- ^^ expected u8, found ()
| |
| this function's body doesn't return
|
= note: expected type `u8`
found type `()`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:20:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected u8, found ()
|
= note: expected type `u8`
found type `()`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
--> $DIR/async-block-control-flow-static-semantics.rs:29:39
|
LL | let _: &dyn Future<Output = ()> = &block;
| ^^^^^^ expected u8, found ()
|
= note: expected type `u8`
found type `()`
= note: required for the cast to the object type `dyn std::future::Future<Output = ()>`

error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == u8`
--> $DIR/async-block-control-flow-static-semantics.rs:24:55
|
LL | async fn return_targets_async_block_not_async_fn() -> u8 {
| ^^ expected (), found u8
|
= note: expected type `()`
found type `u8`
= note: the return type of a function must have a statically known size

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:51:44
|
LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
| ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
| this function's body doesn't return
|
= note: expected type `std::result::Result<u8, MyErr>`
found type `()`

error[E0308]: mismatched types
--> $DIR/async-block-control-flow-static-semantics.rs:60:50
|
LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> {
| ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found ()
| |
| this function's body doesn't return
|
= note: expected type `std::result::Result<u8, MyErr>`
found type `()`

error: aborting due to 8 previous errors

Some errors have detailed explanations: E0267, E0271, E0308.
For more information about an error, try `rustc --explain E0267`.