diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5b527dfc9e7e9..cf14b8dee3700 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -910,6 +910,13 @@ marker_impls! { /// to the pointee value like it normally would, thus allowing the user to do anything that they /// normally could with a non-[`Pin`]-wrapped `Ptr` to that value. /// +/// The idea of this trait is to alleviate the reduced ergonomics of APIs that require the use +/// of [`Pin`] for soundness for some types, but which also want to be used by other types that +/// don't care about pinning. The prime example of such an API is [`Future::poll`]. There are many +/// [`Future`] types that don't care about pinning. These futures can implement `Unpin` and +/// therefore get around the pinning related restrictions in the API, while still allowing the +/// subset of [`Future`]s which *do* require pinning to be implemented soundly. +/// /// For more discussion on the consequences of [`Unpin`] within the wider scope of the pinning /// system, see [the section about `Unpin`] in the [`pin` module]. /// @@ -947,6 +954,8 @@ marker_impls! { /// by adding [`PhantomPinned`] field. For more details, see the [`pin` module] docs. /// /// [`mem::replace`]: crate::mem::replace "mem replace" +/// [`Future`]: crate::future::Future "Future" +/// [`Future::poll`]: crate::future::Future::poll "Future poll" /// [`Pin`]: crate::pin::Pin "Pin" /// [`Pin`]: crate::pin::Pin "Pin" /// [`pin` module]: crate::pin "pin module" diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 17ab48dfd9afd..5d05f4bf901b3 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -349,7 +349,15 @@ //! implement the [`Unpin`] auto-trait, which cancels the restrictive effects of //! [`Pin`] when the *pointee* type `T` is [`Unpin`]. When [`T: Unpin`][Unpin], //! [Pin]<[Box]\> functions identically to a non-pinning [`Box`]; similarly, -//! [Pin]<[&mut] T> would impose no additional restrictions above a regular [`&mut T`]. +//! [Pin]<[&mut] T> would impose no additional restrictions above a regular +//! [`&mut T`]. +//! +//! The idea of this trait is to alleviate the reduced ergonomics of APIs that require the use +//! of [`Pin`] for soundness for some types, but which also want to be used by other types that +//! don't care about pinning. The prime example of such an API is [`Future::poll`]. There are many +//! [`Future`] types that don't care about pinning. These futures can implement [`Unpin`] and +//! therefore get around the pinning related restrictions in the API, while still allowing the +//! subset of [`Future`]s which *do* require pinning to be implemented soundly. //! //! Note that the interaction between a [`Pin`] and [`Unpin`] is through the type of the //! **pointee** value, [`::Target`][Target]. Whether the `Ptr` type itself @@ -945,15 +953,14 @@ use crate::{ /// /// In order to pin a value, we wrap a *pointer to that value* (of some type `Ptr`) in a /// [`Pin`]. [`Pin`] can wrap any pointer type, forming a promise that the **pointee** -/// will not be *moved* or [otherwise invalidated][subtle-details]. Note that it is -/// impossible to create or misuse a [`Pin`] to violate this promise without using [`unsafe`]. -/// If the pointee value's type implements [`Unpin`], we are free to disregard these requirements -/// entirely and can wrap any pointer to that value in [`Pin`] directly via [`Pin::new`]. -/// If the pointee value's type does not implement [`Unpin`], then Rust will not let us use the -/// [`Pin::new`] function directly and we'll need to construct a [`Pin`]-wrapped pointer in one of -/// the more specialized manners discussed below. +/// will not be *moved* or [otherwise invalidated][subtle-details]. If the pointee value's type +/// implements [`Unpin`], we are free to disregard these requirements entirely and can wrap any +/// pointer to that value in [`Pin`] directly via [`Pin::new`]. If the pointee value's type does +/// not implement [`Unpin`], then Rust will not let us use the [`Pin::new`] function directly and +/// we'll need to construct a [`Pin`]-wrapped pointer in one of the more specialized manners +/// discussed below. /// -/// We call such a [`Pin`]-wrapped pointer a **pinning pointer,** (or pinning ref, or pinning +/// We call such a [`Pin`]-wrapped pointer a **pinning pointer** (or pinning ref, or pinning /// [`Box`], etc.) because its existince is the thing that is pinning the underlying pointee in /// place: it is the metaphorical "pin" securing the data in place on the pinboard (in memory). /// @@ -962,18 +969,18 @@ use crate::{ /// the pointer's ***pointee** value*. /// /// The most common set of types which require pinning related guarantees for soundness are the -/// state machines that implement [`Future`] for the return value of `async fn`s under the -/// hood. These compiler-generated [`Future`]s may contain self-referrential pointers, one of the -/// most common use cases for [`Pin`]. More details on this point are provided in the +/// compiler-generated state machines that implement [`Future`] for the return value of +/// `async fn`s. These compiler-generated [`Future`]s may contain self-referrential pointers, one +/// of the most common use cases for [`Pin`]. More details on this point are provided in the /// [`pin` module] docs, but suffice it to say they require the guarantees provided by pinning to /// be implemented soundly. /// -/// This requirement from the implementation of `async fn`s means that the [`Future`] trait +/// This requirement for the implementation of `async fn`s means that the [`Future`] trait /// requires all calls to [`poll`] to use a self: [Pin]\<&mut Self> parameter instead /// of the usual `&mut self`. Therefore, when manually polling a future, you will need to pin it /// first. /// -/// You may notice that `async fn`-generated [`Future`]s are only a small percentage of all +/// You may notice that `async fn`-sourced [`Future`]s are only a small percentage of all /// [`Future`]s that exist, yet we had to modify the signature of [`poll`] for all [`Future`]s /// to accommodate them. This is unfortunate, but there is a way that the language attempts to /// alleviate the extra friction that this API choice incurs: the [`Unpin`] trait.