@@ -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///
@@ -878,6 +879,23 @@ marker_impls! {
878879 { T : ?Sized } & mut T ,
879880}
880881
882+ /// Used to determine whether a type contains any `UnsafePinned` (or `PhantomPinned`) internally,
883+ /// but not through an indirection. This affects, for example, whether we emit `noalias` metadata
884+ /// for `&mut T` or not.
885+ ///
886+ /// This is part of [RFC 3467](https://rust-lang.github.io/rfcs/3467-unsafe-pinned.html), and is
887+ /// tracked by [#125735](https://github.com/rust-lang/rust/issues/125735).
888+ #[ cfg_attr( not( bootstrap) , lang = "unsafe_unpin" ) ]
889+ #[ cfg_attr( bootstrap, allow( dead_code) ) ]
890+ pub ( crate ) unsafe auto trait UnsafeUnpin { }
891+
892+ impl < T : ?Sized > !UnsafeUnpin for UnsafePinned < T > { }
893+ unsafe impl < T : ?Sized > UnsafeUnpin for PhantomData < T > { }
894+ unsafe impl < T : ?Sized > UnsafeUnpin for * const T { }
895+ unsafe impl < T : ?Sized > UnsafeUnpin for * mut T { }
896+ unsafe impl < T : ?Sized > UnsafeUnpin for & T { }
897+ unsafe impl < T : ?Sized > UnsafeUnpin for & mut T { }
898+
881899/// Types that do not require any pinning guarantees.
882900///
883901/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -953,13 +971,24 @@ pub auto trait Unpin {}
953971/// A marker type which does not implement `Unpin`.
954972///
955973/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
974+ //
975+ // FIXME(unsafe_pinned): This is *not* a stable guarantee we want to make, at least not yet.
976+ // Note that for backwards compatibility with the new [`UnsafePinned`] wrapper type, placing this
977+ // marker in your struct acts as if you wrapped the entire struct in an `UnsafePinned`. This type
978+ // will likely eventually be deprecated, and all new code should be using `UnsafePinned` instead.
956979#[ stable( feature = "pin" , since = "1.33.0" ) ]
957980#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
958981pub struct PhantomPinned ;
959982
960983#[ stable( feature = "pin" , since = "1.33.0" ) ]
961984impl !Unpin for PhantomPinned { }
962985
986+ // This is a small hack to allow existing code which uses PhantomPinned to opt-out of noalias to
987+ // continue working. Ideally PhantomPinned could just wrap an `UnsafePinned<()>` to get the same
988+ // effect, but we can't add a new field to an already stable unit struct -- that would be a breaking
989+ // change.
990+ impl !UnsafeUnpin for PhantomPinned { }
991+
963992marker_impls ! {
964993 #[ stable( feature = "pin" , since = "1.33.0" ) ]
965994 Unpin for
0 commit comments