@@ -899,25 +899,37 @@ marker_impls! {
899
899
{ T : ?Sized } & mut T ,
900
900
}
901
901
902
- /// Types that can be safely moved after being pinned.
903
- ///
904
- /// Rust itself has no notion of immovable types, and considers moves (e.g.,
905
- /// through assignment or [`mem::replace`]) to always be safe.
906
- ///
907
- /// The [`Pin`][Pin] type is used instead to prevent moves through the type
908
- /// system. Pointers `P<T>` wrapped in the [`Pin<P<T>>`][Pin] wrapper can't be
909
- /// moved out of. See the [`pin` module] documentation for more information on
910
- /// pinning.
911
- ///
912
- /// Implementing the `Unpin` trait for `T` lifts the restrictions of pinning off
913
- /// the type, which then allows moving `T` out of [`Pin<P<T>>`][Pin] with
914
- /// functions such as [`mem::replace`].
915
- ///
916
- /// `Unpin` has no consequence at all for non-pinned data. In particular,
917
- /// [`mem::replace`] happily moves `!Unpin` data (it works for any `&mut T`, not
918
- /// just when `T: Unpin`). However, you cannot use [`mem::replace`] on data
919
- /// wrapped inside a [`Pin<P<T>>`][Pin] because you cannot get the `&mut T` you
920
- /// need for that, and *that* is what makes this system work.
902
+ /// Types that do not require any pinning guarantees.
903
+ ///
904
+ /// For information on what "pinning" is, see the [`pin` module] documentation.
905
+ ///
906
+ /// Implementing the `Unpin` trait for `T` expresses the fact that `T` is pinning-agnostic:
907
+ /// it shall not expose nor rely on any pinning guarantees. This, in turn, means that a
908
+ /// `Pin`-wrapped pointer to such a type can feature a *fully unrestricted* API.
909
+ /// In other words, if `T: Unpin`, a value of type `T` will *not* be bound by the invariants
910
+ /// which pinning otherwise offers, even when "pinned" by a [`Pin<Ptr>`] pointing at it.
911
+ /// When a value of type `T` is pointed at by a [`Pin<Ptr>`], [`Pin`] will not restrict access
912
+ /// to the pointee value like it normally would, thus allowing the user to do anything that they
913
+ /// normally could with a non-[`Pin`]-wrapped `Ptr` to that value.
914
+ ///
915
+ /// The idea of this trait is to alleviate the reduced ergonomics of APIs that require the use
916
+ /// of [`Pin`] for soundness for some types, but which also want to be used by other types that
917
+ /// don't care about pinning. The prime example of such an API is [`Future::poll`]. There are many
918
+ /// [`Future`] types that don't care about pinning. These futures can implement `Unpin` and
919
+ /// therefore get around the pinning related restrictions in the API, while still allowing the
920
+ /// subset of [`Future`]s which *do* require pinning to be implemented soundly.
921
+ ///
922
+ /// For more discussion on the consequences of [`Unpin`] within the wider scope of the pinning
923
+ /// system, see the [section about `Unpin`] in the [`pin` module].
924
+ ///
925
+ /// `Unpin` has no consequence at all for non-pinned data. In particular, [`mem::replace`] happily
926
+ /// moves `!Unpin` data, which would be immovable when pinned ([`mem::replace`] works for any
927
+ /// `&mut T`, not just when `T: Unpin`).
928
+ ///
929
+ /// *However*, you cannot use [`mem::replace`] on `!Unpin` data which is *pinned* by being wrapped
930
+ /// inside a [`Pin<Ptr>`] pointing at it. This is because you cannot (safely) use a
931
+ /// [`Pin<Ptr>`] to get an `&mut T` to its pointee value, which you would need to call
932
+ /// [`mem::replace`], and *that* is what makes this system work.
921
933
///
922
934
/// So this, for example, can only be done on types implementing `Unpin`:
923
935
///
@@ -935,11 +947,22 @@ marker_impls! {
935
947
/// mem::replace(&mut *pinned_string, "other".to_string());
936
948
/// ```
937
949
///
938
- /// This trait is automatically implemented for almost every type.
939
- ///
940
- /// [`mem::replace`]: crate::mem::replace
941
- /// [Pin]: crate::pin::Pin
942
- /// [`pin` module]: crate::pin
950
+ /// This trait is automatically implemented for almost every type. The compiler is free
951
+ /// to take the conservative stance of marking types as [`Unpin`] so long as all of the types that
952
+ /// compose its fields are also [`Unpin`]. This is because if a type implements [`Unpin`], then it
953
+ /// is unsound for that type's implementation to rely on pinning-related guarantees for soundness,
954
+ /// *even* when viewed through a "pinning" pointer! It is the responsibility of the implementor of
955
+ /// a type that relies upon pinning for soundness to ensure that type is *not* marked as [`Unpin`]
956
+ /// by adding [`PhantomPinned`] field. For more details, see the [`pin` module] docs.
957
+ ///
958
+ /// [`mem::replace`]: crate::mem::replace "mem replace"
959
+ /// [`Future`]: crate::future::Future "Future"
960
+ /// [`Future::poll`]: crate::future::Future::poll "Future poll"
961
+ /// [`Pin`]: crate::pin::Pin "Pin"
962
+ /// [`Pin<Ptr>`]: crate::pin::Pin "Pin"
963
+ /// [`pin` module]: crate::pin "pin module"
964
+ /// [section about `Unpin`]: crate::pin#unpin "pin module docs about unpin"
965
+ /// [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe"
943
966
#[ stable( feature = "pin" , since = "1.33.0" ) ]
944
967
#[ diagnostic:: on_unimplemented(
945
968
note = "consider using the `pin!` macro\n consider using `Box::pin` if you need to access the pinned value outside of the current scope" ,
0 commit comments