Skip to content

Commit c7c4c12

Browse files
authored
Unrolled build for rust-lang#125392
Rollup merge of rust-lang#125392 - workingjubilee:unwind-a-problem-in-context, r=Amanieu Wrap Context.ext in AssertUnwindSafe Fixes rust-lang#125193 Alternative to rust-lang#125377 Relevant to rust-lang#123392 I believe this approach is justifiable due to the fact that this function is unstable API and we have been considering trying to dispose of the notion of "unwind safety". Making a more long-term decision should be considered carefully as part of stabilizing `fn ext`, if ever. r? `@Amanieu`
2 parents 5293c6a + 3a21fb5 commit c7c4c12

File tree

4 files changed

+27
-42
lines changed

4 files changed

+27
-42
lines changed

library/core/src/task/wake.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::mem::transmute;
55
use crate::any::Any;
66
use crate::fmt;
77
use crate::marker::PhantomData;
8+
use crate::panic::AssertUnwindSafe;
89
use crate::ptr;
910

1011
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
@@ -236,7 +237,7 @@ enum ExtData<'a> {
236237
pub struct Context<'a> {
237238
waker: &'a Waker,
238239
local_waker: &'a LocalWaker,
239-
ext: ExtData<'a>,
240+
ext: AssertUnwindSafe<ExtData<'a>>,
240241
// Ensure we future-proof against variance changes by forcing
241242
// the lifetime to be invariant (argument-position lifetimes
242243
// are contravariant while return-position lifetimes are
@@ -279,7 +280,9 @@ impl<'a> Context<'a> {
279280
#[unstable(feature = "context_ext", issue = "123392")]
280281
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
281282
pub const fn ext(&mut self) -> &mut dyn Any {
282-
match &mut self.ext {
283+
// FIXME: this field makes Context extra-weird about unwind safety
284+
// can we justify AssertUnwindSafe if we stabilize this? do we care?
285+
match &mut *self.ext {
283286
ExtData::Some(data) => *data,
284287
ExtData::None(unit) => unit,
285288
}
@@ -353,7 +356,7 @@ impl<'a> ContextBuilder<'a> {
353356
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
354357
#[unstable(feature = "context_ext", issue = "123392")]
355358
pub const fn from(cx: &'a mut Context<'_>) -> Self {
356-
let ext = match &mut cx.ext {
359+
let ext = match &mut *cx.ext {
357360
ExtData::Some(ext) => ExtData::Some(*ext),
358361
ExtData::None(()) => ExtData::None(()),
359362
};
@@ -396,7 +399,7 @@ impl<'a> ContextBuilder<'a> {
396399
#[rustc_const_unstable(feature = "const_waker", issue = "102012")]
397400
pub const fn build(self) -> Context<'a> {
398401
let ContextBuilder { waker, local_waker, ext, _marker, _marker2 } = self;
399-
Context { waker, local_waker, ext, _marker, _marker2 }
402+
Context { waker, local_waker, ext: AssertUnwindSafe(ext), _marker, _marker2 }
400403
}
401404
}
402405

tests/ui/async-await/async-is-unwindsafe.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ fn main() {
1111

1212
is_unwindsafe(async {
1313
//~^ ERROR the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
14-
//~| ERROR the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
1514
use std::ptr::null;
1615
use std::task::{Context, RawWaker, RawWakerVTable, Waker};
1716
let waker = unsafe {

tests/ui/async-await/async-is-unwindsafe.stderr

+6-37
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ LL | is_unwindsafe(async {
66
| |_____|
77
| ||
88
LL | ||
9-
LL | ||
109
LL | || use std::ptr::null;
10+
LL | || use std::task::{Context, RawWaker, RawWakerVTable, Waker};
1111
... ||
1212
LL | || drop(cx_ref);
1313
LL | || });
1414
| ||_____-^ `&mut Context<'_>` may not be safely transferred across an unwind boundary
1515
| |_____|
16-
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`
16+
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
1717
|
18-
= 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`
18+
= 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`
19+
= note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
1920
note: future does not implement `UnwindSafe` as this value is used across an await
20-
--> $DIR/async-is-unwindsafe.rs:26:18
21+
--> $DIR/async-is-unwindsafe.rs:25:18
2122
|
2223
LL | let cx_ref = &mut cx;
2324
| ------ has type `&mut Context<'_>` which does not implement `UnwindSafe`
@@ -30,38 +31,6 @@ note: required by a bound in `is_unwindsafe`
3031
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
3132
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`
3233

33-
error[E0277]: the type `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
34-
--> $DIR/async-is-unwindsafe.rs:12:5
35-
|
36-
LL | is_unwindsafe(async {
37-
| _____^_____________-
38-
| |_____|
39-
| ||
40-
LL | ||
41-
LL | ||
42-
LL | || use std::ptr::null;
43-
... ||
44-
LL | || drop(cx_ref);
45-
LL | || });
46-
| ||_____-^ `&mut (dyn Any + 'static)` may not be safely transferred across an unwind boundary
47-
| |_____|
48-
| within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 30:6}`
49-
|
50-
= 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`
51-
note: future does not implement `UnwindSafe` as this value is used across an await
52-
--> $DIR/async-is-unwindsafe.rs:26:18
53-
|
54-
LL | let mut cx = Context::from_waker(&waker);
55-
| ------ has type `Context<'_>` which does not implement `UnwindSafe`
56-
...
57-
LL | async {}.await; // this needs an inner await point
58-
| ^^^^^ await occurs here, with `mut cx` maybe used later
59-
note: required by a bound in `is_unwindsafe`
60-
--> $DIR/async-is-unwindsafe.rs:3:26
61-
|
62-
LL | fn is_unwindsafe(_: impl std::panic::UnwindSafe) {}
63-
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_unwindsafe`
64-
65-
error: aborting due to 2 previous errors
34+
error: aborting due to 1 previous error
6635

6736
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ run-pass
2+
// Tests against a regression surfaced by crater in https://github.com/rust-lang/rust/issues/125193
3+
// Unwind Safety is not a very coherent concept, but we'd prefer no regressions until we kibosh it
4+
// and this is an unstable feature anyways sooo...
5+
6+
use std::panic::UnwindSafe;
7+
use std::task::Context;
8+
9+
fn unwind_safe<T: UnwindSafe>() {}
10+
11+
fn main() {
12+
unwind_safe::<Context<'_>>(); // test UnwindSafe
13+
unwind_safe::<&Context<'_>>(); // test RefUnwindSafe
14+
}

0 commit comments

Comments
 (0)