@@ -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,23 @@ marker_impls! {
858
859
{ T : ?Sized } & mut T ,
859
860
}
860
861
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
+
861
879
/// Types that do not require any pinning guarantees.
862
880
///
863
881
/// For information on what "pinning" is, see the [`pin` module] documentation.
@@ -933,13 +951,24 @@ pub auto trait Unpin {}
933
951
/// A marker type which does not implement `Unpin`.
934
952
///
935
953
/// 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.
936
959
#[ stable( feature = "pin" , since = "1.33.0" ) ]
937
960
#[ derive( Debug , Default , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
938
961
pub struct PhantomPinned ;
939
962
940
963
#[ stable( feature = "pin" , since = "1.33.0" ) ]
941
964
impl !Unpin for PhantomPinned { }
942
965
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
+
943
972
marker_impls ! {
944
973
#[ stable( feature = "pin" , since = "1.33.0" ) ]
945
974
Unpin for
0 commit comments