about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee Young <workingjubilee@gmail.com>2024-05-21 18:55:12 -0700
committerJosh Stone <jistone@redhat.com>2024-06-06 11:41:35 -0700
commitb8fb165d41a9bd78d80fc9a2f5fff2ec8bb4ebf3 (patch)
treee6ff1fae96efb509019415636adcb4d615fb3c5a
parent3c5120646e2fa220a3cad6133d9da4a9f51f5dc7 (diff)
downloadrust-b8fb165d41a9bd78d80fc9a2f5fff2ec8bb4ebf3.tar.gz
rust-b8fb165d41a9bd78d80fc9a2f5fff2ec8bb4ebf3.zip
Wrap Context.ext in AssertUnwindSafe
(cherry picked from commit 3a21fb5cec07052cb664b6a051e233cd4776283a)
-rw-r--r--library/core/src/task/wake.rs11
-rw-r--r--tests/ui/async-await/async-is-unwindsafe.rs1
-rw-r--r--tests/ui/async-await/async-is-unwindsafe.stderr43
-rw-r--r--tests/ui/async-await/context-is-sorta-unwindsafe.rs14
4 files changed, 27 insertions, 42 deletions
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 7691721b91e..3d21b09fa8a 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -5,6 +5,7 @@ use crate::mem::transmute;
 use crate::any::Any;
 use crate::fmt;
 use crate::marker::PhantomData;
+use crate::panic::AssertUnwindSafe;
 use crate::ptr;
 
 /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
@@ -236,7 +237,7 @@ enum ExtData<'a> {
 pub struct Context<'a> {
     waker: &'a Waker,
     local_waker: &'a LocalWaker,
-    ext: ExtData<'a>,
+    ext: AssertUnwindSafe<ExtData<'a>>,
     // Ensure we future-proof against variance changes by forcing
     // the lifetime to be invariant (argument-position lifetimes
     // are contravariant while return-position lifetimes are
@@ -279,7 +280,9 @@ impl<'a> Context<'a> {
     #[unstable(feature = "context_ext", issue = "123392")]
     #[rustc_const_unstable(feature = "const_waker", issue = "102012")]
     pub const fn ext(&mut self) -> &mut dyn Any {
-        match &mut self.ext {
+        // FIXME: this field makes Context extra-weird about unwind safety
+        // can we justify AssertUnwindSafe if we stabilize this? do we care?
+        match &mut *self.ext {
             ExtData::Some(data) => *data,
             ExtData::None(unit) => unit,
         }
@@ -353,7 +356,7 @@ impl<'a> ContextBuilder<'a> {
     #[rustc_const_unstable(feature = "const_waker", issue = "102012")]
     #[unstable(feature = "context_ext", issue = "123392")]
     pub const fn from(cx: &'a mut Context<'_>) -> Self {
-        let ext = match &mut cx.ext {
+        let ext = match &mut *cx.ext {
             ExtData::Some(ext) => ExtData::Some(*ext),
             ExtData::None(()) => ExtData::None(()),
         };
@@ -396,7 +399,7 @@ impl<'a> ContextBuilder<'a> {
     #[rustc_const_unstable(feature = "const_waker", issue = "102012")]
     pub const fn build(self) -> Context<'a> {
         let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self;
-        Context { waker, local_waker, ext, _marker, _marker2 }
+        Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 }
     }
 }
 
diff --git a/tests/ui/async-await/async-is-unwindsafe.rs b/tests/ui/async-await/async-is-unwindsafe.rs
index d0202f72f00..53009b6e741 100644
--- a/tests/ui/async-await/async-is-unwindsafe.rs
+++ b/tests/ui/async-await/async-is-unwindsafe.rs
@@ -11,7 +11,6 @@ fn main() {
 
     is_unwindsafe(async {
         //~^ ERROR the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
-        //~| ERROR the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
         use std::ptr::null;
         use std::task::{Context, RawWaker, RawWakerVTable, Waker};
         let waker = unsafe {
diff --git a/tests/ui/async-await/async-is-unwindsafe.stderr b/tests/ui/async-await/async-is-unwindsafe.stderr
index 6bb06df9f39..5d87fc74768 100644
--- a/tests/ui/async-await/async-is-unwindsafe.stderr
+++ b/tests/ui/async-await/async-is-unwindsafe.stderr
@@ -6,18 +6,19 @@ LL |        is_unwindsafe(async {
    |  |_____|
    | ||
 LL | ||
-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: 30:6}`
+   |        within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
    |
-   = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}: UnwindSafe`
+   = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}: UnwindSafe`
+   = note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
 note: future does not implement `UnwindSafe` as this value is used across an await
-  --> $DIR/async-is-unwindsafe.rs:26:18
+  --> $DIR/async-is-unwindsafe.rs:25:18
    |
 LL |         let cx_ref = &mut cx;
    |             ------ has type `&mut Context<'_>` which does not implement `UnwindSafe`
@@ -30,38 +31,6 @@ note: required by a bound in `is_unwindsafe`
 LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
    |                          ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`
 
-error[E0277]: the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
-  --> $DIR/async-is-unwindsafe.rs:12:5
-   |
-LL |        is_unwindsafe(async {
-   |   _____^_____________-
-   |  |_____|
-   | ||
-LL | ||
-LL | ||
-LL | ||         use std::ptr::null;
-...  ||
-LL | ||         drop(cx_ref);
-LL | ||     });
-   | ||_____-^ `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
-   |  |_____|
-   |        within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`
-   |
-   = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`, the trait `UnwindSafe` is not implemented for `&mut (dyn Any + 'static)`, which is required by `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}: UnwindSafe`
-note: future does not implement `UnwindSafe` as this value is used across an await
-  --> $DIR/async-is-unwindsafe.rs:26:18
-   |
-LL |         let mut cx = Context::from_waker(&waker);
-   |             ------ has type `Context<'_>` which does not implement `UnwindSafe`
-...
-LL |         async {}.await; // this needs an inner await point
-   |                  ^^^^^ await occurs here, with `mut cx` maybe used later
-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 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/context-is-sorta-unwindsafe.rs b/tests/ui/async-await/context-is-sorta-unwindsafe.rs
new file mode 100644
index 00000000000..278476ea237
--- /dev/null
+++ b/tests/ui/async-await/context-is-sorta-unwindsafe.rs
@@ -0,0 +1,14 @@
+//@ run-pass
+// Tests against a regression surfaced by crater in https://github.com/rust-lang/rust/issues/125193
+// Unwind Safety is not a very coherent concept, but we'd prefer no regressions until we kibosh it
+// and this is an unstable feature anyways sooo...
+
+use std::panic::UnwindSafe;
+use std::task::Context;
+
+fn unwind_safe<T: UnwindSafe>() {}
+
+fn main() {
+    unwind_safe::<Context<'_>>(); // test UnwindSafe
+    unwind_safe::<&Context<'_>>(); // test RefUnwindSafe
+}