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,30 +28,19 @@ 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
34+ // Override the manual `!Sync` in `UnsafeCell`.
35+ #[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
36+ unsafe impl < T : ?Sized + Sync > Sync for UnsafePinned < T > { }
37+
3138/// When this type is used, that almost certainly means safe APIs need to use pinning to avoid the
3239/// aliases from becoming invalidated. Therefore let's mark this as `!Unpin`. You can always opt
3340/// back in to `Unpin` with an `impl` block, provided your API is still sound while unpinned.
3441#[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
3542impl < T : ?Sized > !Unpin for UnsafePinned < T > { }
3643
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-
5244// `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since
5345// we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes
5446// unergonomic. A type that needs to be `!Send`/`!Sync` should really have an explicit
@@ -63,7 +55,7 @@ impl<T> UnsafePinned<T> {
6355 #[ must_use]
6456 #[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
6557 pub const fn new ( value : T ) -> Self {
66- UnsafePinned { value }
58+ UnsafePinned { value : UnsafeCell :: new ( value ) }
6759 }
6860
6961 /// Unwraps the value, consuming this `UnsafePinned`.
@@ -72,7 +64,7 @@ impl<T> UnsafePinned<T> {
7264 #[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
7365 #[ rustc_allow_const_fn_unstable( const_precise_live_drops) ]
7466 pub const fn into_inner ( self ) -> T {
75- self . value
67+ self . value . into_inner ( )
7668 }
7769}
7870
0 commit comments