about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGray Olson <gray@grayolson.com>2023-10-03 11:42:46 +0200
committerManish Goregaokar <manishsmail@gmail.com>2024-01-07 08:56:09 -0800
commite0210e6e1d18f748db7d84255b84539f67fd7dc0 (patch)
tree49547410a28ea9708dce7d74ec54bbb589782c62
parent469c78bcfda4e00cfcdad2bae4793395af444ec2 (diff)
downloadrust-e0210e6e1d18f748db7d84255b84539f67fd7dc0.tar.gz
rust-e0210e6e1d18f748db7d84255b84539f67fd7dc0.zip
justify motivation of `Unpin` better
-rw-r--r--library/core/src/marker.rs9
-rw-r--r--library/core/src/pin.rs35
2 files changed, 30 insertions, 14 deletions
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5b527dfc9e7..cf14b8dee37 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<Ptr>`]: 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 17ab48dfd9a..5d05f4bf901 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],
 //! <code>[Pin]<[Box]\<T>></code> functions identically to a non-pinning [`Box<T>`]; similarly,
-//! <code>[Pin]<[&mut] T></code> would impose no additional restrictions above a regular [`&mut T`].
+//! <code>[Pin]<[&mut] T></code> 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<Ptr>`] and [`Unpin`] is through the type of the
 //! **pointee** value, [`<Ptr as Deref>::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<Ptr>`]. [`Pin<Ptr>`] 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<Ptr>`] 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 <code>self: [Pin]\<&mut Self></code> 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.