diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs index 29622c9d030a3..5ec99c5d183fb 100644 --- a/src/test/ui/async-await/async-await.rs +++ b/src/test/ui/async-await/async-await.rs @@ -70,6 +70,8 @@ fn async_nonmove_block(x: u8) -> impl Future { } } +// see async-closure.rs for async_closure + async_closure_in_unsafe_block + async fn async_fn(x: u8) -> u8 { wake_and_yield_once().await; x @@ -120,6 +122,18 @@ async unsafe fn unsafe_async_fn(x: u8) -> u8 { x } +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(unsafe_async_fn(x).await) + } + } +} + struct Foo; trait Bar { @@ -176,6 +190,7 @@ fn main() { async_fn, generic_async_fn, async_fn_with_internal_borrow, + async_block_in_unsafe_block, Foo::async_assoc_item, |x| { async move { diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs index f5dc9e24d2d86..925b54b398517 100644 --- a/src/test/ui/async-await/async-closure.rs +++ b/src/test/ui/async-await/async-closure.rs @@ -53,6 +53,21 @@ fn async_closure(x: u8) -> impl Future { })(x) } +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(unsafe_async_fn(x).await) + })(x) +} + +async unsafe fn unsafe_async_fn(x: u8) -> u8 { + wake_and_yield_once().await; + x +} + +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + fn test_future_yields_once_then_returns(f: F) where F: FnOnce(u8) -> Fut, @@ -77,5 +92,6 @@ fn main() { test! { async_closure, + async_closure_in_unsafe_block, } } diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs new file mode 100644 index 0000000000000..cb9156dcc6e58 --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -0,0 +1,21 @@ +// edition:2018 + +#![feature(async_await)] + +struct S; + +impl S { + async unsafe fn f() {} +} + +async unsafe fn f() {} + +async fn g() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} + +fn main() { + S::f(); //~ ERROR call to unsafe function is unsafe + f(); //~ ERROR call to unsafe function is unsafe +} diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr new file mode 100644 index 0000000000000..d22413beecbcf --- /dev/null +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr @@ -0,0 +1,35 @@ +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5 + | +LL | S::f(); + | ^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:20:5 + | +LL | f(); + | ^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/async-await/await-macro.rs b/src/test/ui/async-await/await-macro.rs index c37835d73e92b..b9cd3903513a4 100644 --- a/src/test/ui/async-await/await-macro.rs +++ b/src/test/ui/async-await/await-macro.rs @@ -77,6 +77,12 @@ fn async_closure(x: u8) -> impl Future { })(x) } +fn async_closure_in_unsafe_block(x: u8) -> impl Future { + (unsafe { + async move |x: u8| unsafe_fn(await!(unsafe_async_fn(x))) + })(x) +} + async fn async_fn(x: u8) -> u8 { await!(wake_and_yield_once()); x @@ -127,6 +133,18 @@ async unsafe fn unsafe_async_fn(x: u8) -> u8 { x } +unsafe fn unsafe_fn(x: u8) -> u8 { + x +} + +fn async_block_in_unsafe_block(x: u8) -> impl Future { + unsafe { + async move { + unsafe_fn(await!(unsafe_async_fn(x))) + } + } +} + struct Foo; trait Bar { @@ -134,11 +152,15 @@ trait Bar { } impl Foo { - async fn async_method(x: u8) -> u8 { + async fn async_assoc_item(x: u8) -> u8 { unsafe { await!(unsafe_async_fn(x)) } } + + async unsafe fn async_unsafe_assoc_item(x: u8) -> u8 { + await!(unsafe_async_fn(x)) + } } fn test_future_yields_once_then_returns(f: F) @@ -177,15 +199,22 @@ fn main() { async_block, async_nonmove_block, async_closure, + async_closure_in_unsafe_block, async_fn, generic_async_fn, async_fn_with_internal_borrow, - Foo::async_method, + async_block_in_unsafe_block, + Foo::async_assoc_item, |x| { async move { unsafe { await!(unsafe_async_fn(x)) } } }, + |x| { + async move { + unsafe { await!(Foo::async_unsafe_assoc_item(x)) } + } + }, } test_with_borrow! { async_block_with_borrow_named_lifetime,