@@ -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
///
@@ -878,6 +879,23 @@ marker_impls! {
878
879
{ T : ?Sized } & mut T ,
879
880
}
880
881
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
+
881
899
/// Types that do not require any pinning guarantees.
882
900
///
883
901
/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -953,13 +971,24 @@ pub auto trait Unpin {}
953
971
/// A marker type which does not implement `Unpin`.
954
972
///
955
973
/// 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.
956
979
#[ stable( feature = "pin" , since = "1.33.0" ) ]
957
980
#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
958
981
pub struct PhantomPinned ;
959
982
960
983
#[ stable( feature = "pin" , since = "1.33.0" ) ]
961
984
impl !Unpin for PhantomPinned { }
962
985
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
+
963
992
marker_impls ! {
964
993
#[ stable( feature = "pin" , since = "1.33.0" ) ]
965
994
Unpin for
0 commit comments