@@ -17,6 +17,7 @@ use crate::cell::UnsafeCell;
17
17
use crate :: cmp;
18
18
use crate :: fmt:: Debug ;
19
19
use crate :: hash:: { Hash , Hasher } ;
20
+ use crate :: pin:: UnsafePinned ;
20
21
21
22
/// Implements a given marker trait for multiple types at the same time.
22
23
///
@@ -858,6 +859,20 @@ marker_impls! {
858
859
{ T : ?Sized } & mut T ,
859
860
}
860
861
862
+ /// Used to determine whether a type contains any `UnsafePinned`
863
+ /// (or `PhantomPinned`) internally, but not through an indirection. This
864
+ /// affects, for example, whether we emit `noalias` metadata for `&mut T` or not.
865
+ #[ cfg_attr( not( bootstrap) , lang = "unsafe_unpin" ) ]
866
+ #[ cfg_attr( bootstrap, allow( dead_code) ) ]
867
+ pub ( crate ) unsafe auto trait UnsafeUnpin { }
868
+
869
+ impl < T : ?Sized > !UnsafeUnpin for UnsafePinned < T > { }
870
+ unsafe impl < T : ?Sized > UnsafeUnpin for PhantomData < T > { }
871
+ unsafe impl < T : ?Sized > UnsafeUnpin for * const T { }
872
+ unsafe impl < T : ?Sized > UnsafeUnpin for * mut T { }
873
+ unsafe impl < T : ?Sized > UnsafeUnpin for & T { }
874
+ unsafe impl < T : ?Sized > UnsafeUnpin for & mut T { }
875
+
861
876
/// Types that do not require any pinning guarantees.
862
877
///
863
878
/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -933,13 +948,25 @@ pub auto trait Unpin {}
933
948
/// A marker type which does not implement `Unpin`.
934
949
///
935
950
/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
951
+ //
952
+ // FIXME(unsafe_pinned): This is *not* a stable guarantee we want to make, at least not yet.
953
+ // Note that for backwards compatibility with the new [`UnsafePinned`] wrapper
954
+ // type, placing this marker in your struct acts as if you wrapped the entire
955
+ // struct in an `UnsafePinned`. This type will likely eventually be deprecated,
956
+ // and all new code should be using `UnsafePinned` instead.
936
957
#[ stable( feature = "pin" , since = "1.33.0" ) ]
937
958
#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
938
959
pub struct PhantomPinned ;
939
960
940
961
#[ stable( feature = "pin" , since = "1.33.0" ) ]
941
962
impl !Unpin for PhantomPinned { }
942
963
964
+ // This is a small hack to allow existing code which uses PhantomPinned to
965
+ // opt-out of noalias to continue working. Ideally PhantomPinned could just
966
+ // wrap an `UnsafePinned<()>` to get the same effect, but we can't add a new
967
+ // field to an already stable unit struct -- that would be a breaking change.
968
+ impl !UnsafeUnpin for PhantomPinned { }
969
+
943
970
marker_impls ! {
944
971
#[ stable( feature = "pin" , since = "1.33.0" ) ]
945
972
Unpin for
0 commit comments