@@ -17,6 +17,7 @@ use crate::cell::UnsafeCell;
1717use crate :: cmp;
1818use crate :: fmt:: Debug ;
1919use crate :: hash:: { Hash , Hasher } ;
20+ use crate :: pin:: UnsafePinned ;
2021
2122/// Implements a given marker trait for multiple types at the same time.
2223///
@@ -858,6 +859,20 @@ marker_impls! {
858859 { T : ?Sized } & mut T ,
859860}
860861
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+
861876/// Types that do not require any pinning guarantees.
862877///
863878/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -933,13 +948,25 @@ pub auto trait Unpin {}
933948/// A marker type which does not implement `Unpin`.
934949///
935950/// 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.
936957#[ stable( feature = "pin" , since = "1.33.0" ) ]
937958#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
938959pub struct PhantomPinned ;
939960
940961#[ stable( feature = "pin" , since = "1.33.0" ) ]
941962impl !Unpin for PhantomPinned { }
942963
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+
943970marker_impls ! {
944971 #[ stable( feature = "pin" , since = "1.33.0" ) ]
945972 Unpin for
0 commit comments