diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs new file mode 100644 index 0000000000000..6a766ede0ed87 --- /dev/null +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs @@ -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 = █ + //~^ ERROR type mismatch resolving `::Output == ()` +} + +async fn return_targets_async_block_not_async_fn() -> u8 { + //~^ ERROR type mismatch resolving + let block = async { + return 0u8; + }; + let _: &dyn Future = █ + //~^ ERROR type mismatch resolving `::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 { Err(MyErr) } + +fn rethrow_targets_async_block_not_fn() -> Result { + //~^ ERROR mismatched types + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} + +fn rethrow_targets_async_block_not_async_fn() -> Result { + //~^ ERROR mismatched types + let block = async { + err()?; + Ok(()) + }; + let _: &dyn Future> = █ +} diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr new file mode 100644 index 0000000000000..96927ac9632d6 --- /dev/null +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -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 `::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:20:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected u8, found () + | + = note: expected type `u8` + found type `()` + = note: required for the cast to the object type `dyn std::future::Future` + +error[E0271]: type mismatch resolving `::Output == ()` + --> $DIR/async-block-control-flow-static-semantics.rs:29:39 + | +LL | let _: &dyn Future = █ + | ^^^^^^ expected u8, found () + | + = note: expected type `u8` + found type `()` + = note: required for the cast to the object type `dyn std::future::Future` + +error[E0271]: type mismatch resolving `::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 { + | ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | this function's body doesn't return + | + = note: expected type `std::result::Result` + 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 { + | ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () + | | + | this function's body doesn't return + | + = note: expected type `std::result::Result` + 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`.