You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Rollup merge of #140638 - RalfJung:unsafe-pinned-shared-aliased, r=workingjubilee
UnsafePinned: also include the effects of UnsafeCell
This tackles #137750 by including an `UnsafeCell` in `UnsafePinned`, thus imbuing it with all the usual properties of interior mutability (no `noalias` nor `dereferenceable` on shared refs, special treatment by Miri's aliasing model). The soundness issue is not fixed yet because coroutine lowering does not use `UnsafePinned`.
The RFC said that `UnsafePinned` would not permit mutability on shared references, but since then, #137750 has demonstrated that this is not tenable. In the face of those examples, I propose that we do the "obvious" thing and permit shared mutable state inside `UnsafePinned`. This seems loosely consistent with the fact that we allow going from `Pin<&mut T>` to `&T` (where the former can be aliased with other pointers that perform mutation, and hence the same goes for the latter) -- but the `as_ref` example shows that we in fact would need to add this `UnsafeCell` even if we didn't have a safe conversion to `&T`, since for the compiler and Miri, `&T` and `Pin<&T>` are basically the same type.
To make this possible, I had to remove the `Copy` and `Clone` impls for `UnsafePinned`.
Tracking issue: #125735
Cc ``@rust-lang/lang`` ``@rust-lang/opsem`` ``@Sky9x``
I don't think this needs FCP since the type is still unstable -- we'll finally decide whether we like this approach when `UnsafePinned` is moved towards stabilization (IOW, this PR is reversible). However, I'd still like to make sure that the lang team is okay with the direction I am proposing here.
error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[OFFSET], but that tag does not exist in the borrow stack for this location
2
+
--> tests/fail/async-shared-mutable.rs:LL:CC
3
+
|
4
+
LL | *x = 1;
5
+
| ^^^^^^
6
+
| |
7
+
| attempting a write access using <TAG> at ALLOC[OFFSET], but that tag does not exist in the borrow stack for this location
8
+
| this error occurs as part of an access at ALLOC[OFFSET]
9
+
|
10
+
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
11
+
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
12
+
help: <TAG> was created by a Unique retag at offsets [OFFSET]
13
+
--> tests/fail/async-shared-mutable.rs:LL:CC
14
+
|
15
+
LL | / core::future::poll_fn(move |_| {
16
+
LL | | *x = 1;
17
+
LL | | Poll::<()>::Pending
18
+
LL | | })
19
+
LL | | .await
20
+
| |______________^
21
+
help: <TAG> was later invalidated at offsets [OFFSET] by a SharedReadOnly retag
22
+
--> tests/fail/async-shared-mutable.rs:LL:CC
23
+
|
24
+
LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
25
+
| ^^^^^^^^^^
26
+
= note: BACKTRACE (of the first span):
27
+
= note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC
28
+
= note: inside `<std::future::PollFn<{closure@tests/fail/async-shared-mutable.rs:LL:CC}> as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC
error: Undefined Behavior: write access through <TAG> at ALLOC[OFFSET] is forbidden
2
+
--> tests/fail/async-shared-mutable.rs:LL:CC
3
+
|
4
+
LL | *x = 1;
5
+
| ^^^^^^ write access through <TAG> at ALLOC[OFFSET] is forbidden
6
+
|
7
+
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
8
+
= help: the accessed tag <TAG> has state Frozen which forbids this child write access
9
+
help: the accessed tag <TAG> was created here, in the initial state Reserved
10
+
--> tests/fail/async-shared-mutable.rs:LL:CC
11
+
|
12
+
LL | / core::future::poll_fn(move |_| {
13
+
LL | | *x = 1;
14
+
LL | | Poll::<()>::Pending
15
+
LL | | })
16
+
LL | | .await
17
+
| |______________^
18
+
help: the accessed tag <TAG> later transitioned to Active due to a child write access at offsets [OFFSET]
19
+
--> tests/fail/async-shared-mutable.rs:LL:CC
20
+
|
21
+
LL | *x = 1;
22
+
| ^^^^^^
23
+
= help: this transition corresponds to the first write to a 2-phase borrowed mutable reference
24
+
help: the accessed tag <TAG> later transitioned to Frozen due to a reborrow (acting as a foreign read access) at offsets [OFFSET]
25
+
--> tests/fail/async-shared-mutable.rs:LL:CC
26
+
|
27
+
LL | let _: Pin<&_> = f.as_ref(); // Or: `f.as_mut().into_ref()`.
28
+
| ^^^^^^^^^^
29
+
= help: this transition corresponds to a loss of write permissions
30
+
= note: BACKTRACE (of the first span):
31
+
= note: inside closure at tests/fail/async-shared-mutable.rs:LL:CC
32
+
= note: inside `<std::future::PollFn<{closure@tests/fail/async-shared-mutable.rs:LL:CC}> as std::future::Future>::poll` at RUSTLIB/core/src/future/poll_fn.rs:LL:CC
0 commit comments