Skip to content

Commit 754c09b

Browse files
committed
UnsafePinned: also include the effects of UnsafeCell
1 parent 62c5f58 commit 754c09b

File tree

1 file changed

+7
-19
lines changed

1 file changed

+7
-19
lines changed

library/core/src/pin/unsafe_pinned.rs

+7-19
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
use crate::cell::UnsafeCell;
12
use crate::marker::{PointerLike, Unpin};
23
use crate::ops::{CoerceUnsized, DispatchFromDyn};
34
use crate::pin::Pin;
45
use crate::{fmt, ptr};
56

6-
/// This type provides a way to opt-out of typical aliasing rules;
7+
/// This type provides a way to entirely opt-out of typical aliasing rules;
78
/// specifically, `&mut UnsafePinned<T>` is not guaranteed to be a unique pointer.
9+
/// This also subsumes the effects of `UnsafeCell`, i.e., `&UnsafePinned<T>` may point to data
10+
/// that is being mutated.
811
///
912
/// However, even if you define your type like `pub struct Wrapper(UnsafePinned<...>)`, it is still
1013
/// very risky to have an `&mut Wrapper` that aliases anything else. Many functions that work
@@ -25,7 +28,7 @@ use crate::{fmt, ptr};
2528
#[repr(transparent)]
2629
#[unstable(feature = "unsafe_pinned", issue = "125735")]
2730
pub struct UnsafePinned<T: ?Sized> {
28-
value: T,
31+
value: UnsafeCell<T>,
2932
}
3033

3134
/// When this type is used, that almost certainly means safe APIs need to use pinning to avoid the
@@ -34,21 +37,6 @@ pub struct UnsafePinned<T: ?Sized> {
3437
#[unstable(feature = "unsafe_pinned", issue = "125735")]
3538
impl<T: ?Sized> !Unpin for UnsafePinned<T> {}
3639

37-
/// The type is `Copy` when `T` is to avoid people assuming that `Copy` implies there is no
38-
/// `UnsafePinned` anywhere. (This is an issue with `UnsafeCell`: people use `Copy` bounds to mean
39-
/// `Freeze`.) Given that there is no `unsafe impl Copy for ...`, this is also the option that
40-
/// leaves the user more choices (as they can always wrap this in a `!Copy` type).
41-
// FIXME(unsafe_pinned): this may be unsound or a footgun?
42-
#[unstable(feature = "unsafe_pinned", issue = "125735")]
43-
impl<T: Copy> Copy for UnsafePinned<T> {}
44-
45-
#[unstable(feature = "unsafe_pinned", issue = "125735")]
46-
impl<T: Copy> Clone for UnsafePinned<T> {
47-
fn clone(&self) -> Self {
48-
*self
49-
}
50-
}
51-
5240
// `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since
5341
// we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes
5442
// unergonomic. A type that needs to be `!Send`/`!Sync` should really have an explicit
@@ -63,7 +51,7 @@ impl<T> UnsafePinned<T> {
6351
#[must_use]
6452
#[unstable(feature = "unsafe_pinned", issue = "125735")]
6553
pub const fn new(value: T) -> Self {
66-
UnsafePinned { value }
54+
UnsafePinned { value: UnsafeCell::new(value) }
6755
}
6856

6957
/// Unwraps the value, consuming this `UnsafePinned`.
@@ -72,7 +60,7 @@ impl<T> UnsafePinned<T> {
7260
#[unstable(feature = "unsafe_pinned", issue = "125735")]
7361
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
7462
pub const fn into_inner(self) -> T {
75-
self.value
63+
self.value.into_inner()
7664
}
7765
}
7866

0 commit comments

Comments
 (0)