forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test that async blocks are UnwindSafe
This was a regression from the reverted rust-lang#105250 which is now covered by a test.
- Loading branch information
Showing
2 changed files
with
68 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// edition:2018 | ||
|
||
fn is_unwindsafe(_: impl std::panic::UnwindSafe) {} | ||
|
||
fn main() { | ||
// A normal future created by an async block takes a `&mut Context<'_>` argument. | ||
// That should not leak through to the whole async block. | ||
is_unwindsafe(async { | ||
async {}.await; // this needs an inner await point | ||
}); | ||
|
||
is_unwindsafe(async { | ||
//~^ ERROR the type `&mut Context<'_>` may not be safely transferred across an unwind boundary | ||
use std::ptr::null; | ||
use std::task::{Context, RawWaker, RawWakerVTable, Waker}; | ||
let waker = unsafe { | ||
Waker::from_raw(RawWaker::new( | ||
null(), | ||
&RawWakerVTable::new(|_| todo!(), |_| todo!(), |_| todo!(), |_| todo!()), | ||
)) | ||
}; | ||
let mut cx = Context::from_waker(&waker); | ||
let cx_ref = &mut cx; | ||
|
||
async {}.await; // this needs an inner await point | ||
|
||
// in this case, `&mut Context<'_>` is *truly* alive across an await point | ||
drop(cx_ref); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary | ||
--> $DIR/async-is-unwindsafe.rs:12:19 | ||
| | ||
LL | is_unwindsafe(async { | ||
| ___________________^ | ||
LL | | | ||
LL | | use std::ptr::null; | ||
LL | | use std::task::{Context, RawWaker, RawWakerVTable, Waker}; | ||
... | | ||
LL | | drop(cx_ref); | ||
LL | | }); | ||
| | ^ | ||
| | | | ||
| |_____`&mut Context<'_>` may not be safely transferred across an unwind boundary | ||
| within this `[async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6]` | ||
| | ||
= help: within `[async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6]`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>` | ||
= note: `UnwindSafe` is implemented for `&std::task::Context<'_>`, but not for `&mut std::task::Context<'_>` | ||
note: future does not implement `UnwindSafe` as this value is used across an await | ||
--> $DIR/async-is-unwindsafe.rs:25:17 | ||
| | ||
LL | let cx_ref = &mut cx; | ||
| ------ has type `&mut Context<'_>` which does not implement `UnwindSafe` | ||
LL | | ||
LL | async {}.await; // this needs an inner await point | ||
| ^^^^^^ await occurs here, with `cx_ref` maybe used later | ||
... | ||
LL | }); | ||
| - `cx_ref` is later dropped here | ||
note: required by a bound in `is_unwindsafe` | ||
--> $DIR/async-is-unwindsafe.rs:3:26 | ||
| | ||
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {} | ||
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe` | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0277`. |