@@ -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,23 @@ marker_impls! {
858859 { T : ?Sized } & mut T ,
859860}
860861
862+ /// Used to determine whether a type contains any `UnsafePinned` (or `PhantomPinned`) internally,
863+ /// but not through an indirection. This affects, for example, whether we emit `noalias` metadata
864+ /// for `&mut T` or not.
865+ ///
866+ /// This is part of [RFC 3467](https://rust-lang.github.io/rfcs/3467-unsafe-pinned.html), and is
867+ /// tracked by [#125735](https://github.com/rust-lang/rust/issues/125735).
868+ #[ cfg_attr( not( bootstrap) , lang = "unsafe_unpin" ) ]
869+ #[ cfg_attr( bootstrap, allow( dead_code) ) ]
870+ pub ( crate ) unsafe auto trait UnsafeUnpin { }
871+
872+ impl < T : ?Sized > !UnsafeUnpin for UnsafePinned < T > { }
873+ unsafe impl < T : ?Sized > UnsafeUnpin for PhantomData < T > { }
874+ unsafe impl < T : ?Sized > UnsafeUnpin for * const T { }
875+ unsafe impl < T : ?Sized > UnsafeUnpin for * mut T { }
876+ unsafe impl < T : ?Sized > UnsafeUnpin for & T { }
877+ unsafe impl < T : ?Sized > UnsafeUnpin for & mut T { }
878+
861879/// Types that do not require any pinning guarantees.
862880///
863881/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -933,13 +951,24 @@ pub auto trait Unpin {}
933951/// A marker type which does not implement `Unpin`.
934952///
935953/// If a type contains a `PhantomPinned`, it will not implement `Unpin` by default.
954+ //
955+ // FIXME(unsafe_pinned): This is *not* a stable guarantee we want to make, at least not yet.
956+ // Note that for backwards compatibility with the new [`UnsafePinned`] wrapper type, placing this
957+ // marker in your struct acts as if you wrapped the entire struct in an `UnsafePinned`. This type
958+ // will likely eventually be deprecated, and all new code should be using `UnsafePinned` instead.
936959#[ stable( feature = "pin" , since = "1.33.0" ) ]
937960#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
938961pub struct PhantomPinned ;
939962
940963#[ stable( feature = "pin" , since = "1.33.0" ) ]
941964impl !Unpin for PhantomPinned { }
942965
966+ // This is a small hack to allow existing code which uses PhantomPinned to opt-out of noalias to
967+ // continue working. Ideally PhantomPinned could just wrap an `UnsafePinned<()>` to get the same
968+ // effect, but we can't add a new field to an already stable unit struct -- that would be a breaking
969+ // change.
970+ impl !UnsafeUnpin for PhantomPinned { }
971+
943972marker_impls ! {
944973 #[ stable( feature = "pin" , since = "1.33.0" ) ]
945974 Unpin for
0 commit comments