1
+ use crate :: cell:: UnsafeCell ;
1
2
use crate :: marker:: { PointerLike , Unpin } ;
2
3
use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
3
4
use crate :: pin:: Pin ;
4
5
use crate :: { fmt, ptr} ;
5
6
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;
7
8
/// 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.
8
11
///
9
12
/// However, even if you define your type like `pub struct Wrapper(UnsafePinned<...>)`, it is still
10
13
/// very risky to have an `&mut Wrapper` that aliases anything else. Many functions that work
@@ -25,7 +28,7 @@ use crate::{fmt, ptr};
25
28
#[ repr( transparent) ]
26
29
#[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
27
30
pub struct UnsafePinned < T : ?Sized > {
28
- value : T ,
31
+ value : UnsafeCell < T > ,
29
32
}
30
33
31
34
/// 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> {
34
37
#[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
35
38
impl < T : ?Sized > !Unpin for UnsafePinned < T > { }
36
39
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
-
52
40
// `Send` and `Sync` are inherited from `T`. This is similar to `SyncUnsafeCell`, since
53
41
// we eventually concluded that `UnsafeCell` implicitly making things `!Sync` is sometimes
54
42
// unergonomic. A type that needs to be `!Send`/`!Sync` should really have an explicit
@@ -63,7 +51,7 @@ impl<T> UnsafePinned<T> {
63
51
#[ must_use]
64
52
#[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
65
53
pub const fn new ( value : T ) -> Self {
66
- UnsafePinned { value }
54
+ UnsafePinned { value : UnsafeCell :: new ( value ) }
67
55
}
68
56
69
57
/// Unwraps the value, consuming this `UnsafePinned`.
@@ -72,7 +60,7 @@ impl<T> UnsafePinned<T> {
72
60
#[ unstable( feature = "unsafe_pinned" , issue = "125735" ) ]
73
61
#[ rustc_allow_const_fn_unstable( const_precise_live_drops) ]
74
62
pub const fn into_inner ( self ) -> T {
75
- self . value
63
+ self . value . into_inner ( )
76
64
}
77
65
}
78
66
0 commit comments