1+ use crate :: cell:: UnsafeCell ;
12use crate :: marker:: { PointerLike , Unpin } ;
23use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
34use crate :: pin:: Pin ;
45use 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" ) ]
2730pub 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" ) ]
3538impl < 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