[Pin]\
ensures that the pointee of any pointer type
-//! `P` has a stable location in memory, meaning it cannot be moved elsewhere
-//! and its memory cannot be deallocated until it gets dropped. We say that the
-//! pointee is "pinned". Things get more subtle when discussing types that
-//! combine pinned with non-pinned data; [see below](#projections-and-structural-pinning)
-//! for more details.
-//!
-//! By default, all types in Rust are movable. Rust allows passing all types by-value,
-//! and common smart-pointer types such as [Box]\
and [&mut] T
allow
-//! replacing and moving the values they contain: you can move out of a [Box]\
,
-//! or you can use [`mem::swap`]. [Pin]\
wraps a pointer type `P`, so
-//! [Pin]<[Box]\>
functions much like a regular [Box]\
:
-//! when a [Pin]<[Box]\>
gets dropped, so do its contents, and the memory gets
-//! deallocated. Similarly, [Pin]<[&mut] T>
is a lot like [&mut] T
.
-//! However, [Pin]\
does not let clients actually obtain a [Box]\
-//! or [&mut] T
to pinned data, which implies that you cannot use operations such
-//! as [`mem::swap`]:
+//! Types that pin data to a location in memory.
+//!
+//! It is sometimes useful to be able to rely upon a certain value not being able to *move*,
+//! in the sense that its address in memory cannot change. This is useful specifically when there
+//! is a *pointer* that is pointing at that value. The ability to rely on this guarantee that
+//! the *value a pointer is pointing at* (its *pointee*) will not move is necessary to implement
+//! things like self-referential structs, as moving an object with pointers that are meant to
+//! point into that struct's own data would cause those pointers to no longer be valid (they
+//! would still be pointing at the struct's old location in memory).
+//!
+//! "Pinning" allows us to put a value *which is being pointed at* by some pointer `Ptr` into a state
+//! that prevents safe code from *moving* the *pointee* value. In this way, we can allow [`unsafe`] code
+//! to rely on the pointer not having its pointee moved out from under it.
+//!
+//! The rest of this documentation is intended to be the source of truth for users of [`Pin`] helps us implement steps (2) and (3) safely. +//! +//! ## `Pin` and pointers +//! +//! [`Pin
`] can wrap any pointer type, forming a promise that the pointee will not be *moved*. +//! This promise must be upheld by [`unsafe`] code which interacts with the [`Pin
`] so that
+//! [`unsafe`] code can place the pointee in an address-sensitive state that will not be broken
+//! by a *move*. Operations on an address-sensitive type accept an argument like
+//! [Pin]<[`&mut T`]>
or [Pin]<[`Box
to indicate this contract to
+//! the caller.
+//!
+//! Since [`Pin
`] can wrap any pointer type, it interacts with +//! [`Deref`] and [`DerefMut`]. A [`Pin
`] where [`P: Deref`][Deref] is a
+//! "`P`-style pointer" to a pinned [`P::Target`][Target] – so, a
+//! [Pin]<[`Box
is an owned pointer to a pinned `T`, and a
+//! [Pin]<[`Rc
is a reference-counted pointer to a pinned `T`.
+//!
+//! [`Pin
`] requires that implementations of [`Deref`] and [`DerefMut`] return a pointer to +//! pinned data when they are called on a pinned pointer and do not *move* out of their `self` +//! parameter. It is unsound for [`unsafe`] code to wrap such "evil" pointers; see +//! [`Pin
::new_unchecked`] for details. +//! +//! Pinning does not require any compiler "magic", only a specific contract between the library API +//! and its users. This differs from e.g. [`UnsafeCell`] which changes the semantics of a program's +//! compiled output. A [`Pin
`] is a handle to a value which does not allow moving the value out,
+//! but Rust still considers all values themselves to be moveable with e.g. [`mem::swap`].
+//!
+//! These guarantees are necessary to make our `AddrTracker` example work. If any code
+//! sees a [Pin]<&mut AddrTracker>
, it can safely assume that it will *always* see
+//! [the same object][address-stability] for the same address (for the lifetime of
+//! the pointee). If we had written `check_for_move` above to accept a
+//! [Pin]<[`&mut Self`]>
instead, multiple calls to it *cannot* panic:
+//!
+//! ```
+//! # use std::pin::Pin;
+//! # #[derive(Default)]
+//! # struct AddrTracker(usize);
+//! impl AddrTracker {
+//! fn check_for_move(self: Pin<&mut Self>) {
+//! unsafe {
+//! let unpinned = Pin::get_unchecked_mut(self);
+//! let addr = unpinned as *mut Self as usize;
+//! match unpinned.0 {
+//! 0 => unpinned.0 = addr,
+//! x => assert_eq!(x, addr),
+//! }
+//! }
+//! }
//! }
+//!
+//! let mut tracker = Box::pin(AddrTracker::default());
+//! tracker.as_mut().check_for_move();
+//! tracker.as_mut().check_for_move();
//! ```
//!
-//! It is worth reiterating that [Pin]\
does *not* change the fact that a Rust
-//! compiler considers all types movable. [`mem::swap`] remains callable for any `T`. Instead,
-//! [Pin]\
prevents certain *values* (pointed to by pointers wrapped in
-//! [Pin]\
) from being moved by making it impossible to call methods that require
-//! [&mut] T
on them (like [`mem::swap`]).
-//!
-//! [Pin]\
can be used to wrap any pointer type `P`, and as such it interacts with
-//! [`Deref`] and [`DerefMut`]. A [Pin]\
where P: [Deref]
should be
-//! considered as a "`P`-style pointer" to a pinned P::[Target]
– so, a
-//! [Pin]<[Box]\
is an owned pointer to a pinned `T`, and a
-//! [Pin]<[Rc]\
is a reference-counted pointer to a pinned `T`.
-//! For correctness, [Pin]\
relies on the implementations of [`Deref`] and
-//! [`DerefMut`] not to move out of their `self` parameter, and only ever to
-//! return a pointer to pinned data when they are called on a pinned pointer.
-//!
-//! # `Unpin`
-//!
-//! Many types are always freely movable, even when pinned, because they do not
-//! rely on having a stable address. This includes all the basic types (like
-//! [`bool`], [`i32`], and references) as well as types consisting solely of these
-//! types. Types that do not care about pinning implement the [`Unpin`]
-//! auto-trait, which cancels the effect of [Pin]\
. For T: [Unpin]
,
-//! [Pin]<[Box]\
and [Box]\
function identically, as do
-//! [Pin]<[&mut] T>
and [&mut] T
.
-//!
-//! Note that pinning and [`Unpin`] only affect the pointed-to type P::[Target]
,
-//! not the pointer type `P` itself that got wrapped in [Pin]\
. For example,
-//! whether or not [Box]\
is [`Unpin`] has no effect on the behavior of
-//! [Pin]<[Box]\
(here, `T` is the pointed-to type).
-//!
-//! # Example: self-referential struct
-//!
-//! Before we go into more details to explain the guarantees and choices
-//! associated with [Pin]\
, we discuss some examples for how it might be used.
-//! Feel free to [skip to where the theoretical discussion continues](#drop-guarantee).
+//! [As discussed below][drop-guarantee], this has consequences for running
+//! destructors of pinned memory, too.
+//!
+//! ## [`Unpin`]
+//!
+//! The vast majority of Rust types are not address-sensitive; these types
+//! implement the [`Unpin`] auto-trait, which cancels the restrictive effects of
+//! [`Pin
`]. When [`T: Unpin`][Unpin], ` docs to clarify guarantees and uses)
+//!
+//! unsafe {
+//! (*self.pred).succ = self.succ;
+//! (*self.succ).pred = self.pred;
+//! }
+//! }
+//! }
+//! ```
+//!
+//! For this to work, a [`drop`-related guarantee][drop-guarantee] is required. If a node could
+//! be deallocated or otherwise invalidated without calling [`drop`], the pointers into it from its
+//! neighboring elements would become invalid, which would break the data structure.
+//!
+//! [`List`] itself is *not* address-sensitive.
+//!
+//! # Subtle details
+//! [subtle-details]: #subtle-details
+//!
+//! [`List::append`] above relies on both of [`Pin `]'s guarantees:
+//!
+//! 1. *Address Stability.* If [`unsafe`] code witnesses any [`p: Pin `][Pin] at any time then
+//! it may assume that `p.as_ref().get_ref() as *const _` will remain valid, pointing to the
+//! same object until the end of that object's lifetime.
+//! 2. *Notice of Destruction.* If `x: T` was ever reachable through any [`Pin `] type, its
+//! destructor must be run (until it either returns or panics) before `x`'s storage can be
+//! overwritten. The "until further notice" in (1) includes this mandatory destruction. This is
+//! often called the "[`Drop`] guarantee".
+//!
+//! ## Address Stability
+//! [address-stability]: #address-stability
+//!
+//! The precise meaning of "address stability" is subtle, because "the same object" is not well-defined.
+//! It is easiest to reason about it in terms of *visibility of mutations*. If [`unsafe`] code mutates
+//! through a [`Pin `], all code that stashed a raw pointer into it will see the mutation. In other
+//! words, [`unsafe`] code can rely on the same value in memory being updated by all uses of a particular
+//! [`Pin `], not to mention that those stashed raw pointers remain valid in the first place.
+//!
+//! When a [`List`] stores a [`Node`], it needs to assume that appending a second node will mutate the
+//! first node, so that later, when the first node is removed, it knows that its predecessor is the
+//! second node.
//!
-//! For example, you could implement [`Drop`][Drop] as follows:
+//! When writing generic code, it's not possible to know what [`unsafe`] code has recorded about the
+//! pointee's address, so it must be very careful to observe this invariant. Thankfully, most of this
+//! is already enforced by the [`Pin `] API, so only [`unsafe`] code needs to worry about this.
+//!
+//! ## Notice of Destruction
+//! [drop-guarantee]: #notice-of-destruction
+//!
+//! There needs to be a way for a pinned value to notify any [`unsafe`] code that recorded its address
+//! that it is about to be destroyed, so that they can remove its address from their data structures.
+//! Thus, in any situation where it would be safe to overwrite a pinned value, the destructor must
+//! be called beforehand.
+//!
+//! The most common storage-reuse situation is when a value on the stack is destroyed as part of a
+//! function return, or when heap storage is freed. In both cases, the destructor gets run for us
+//! by Rust. However, for heap storage, [`unsafe`] code must make sure to call [`ptr::drop_in_place`]
+//! if it wishes to use the [`std::alloc`] APIs manually.
+//!
+//! However, reuse can happen even if not storage is de-allocated. For example, when a [`Some`]
+//! is overwritten by [`None`] using [`ptr::write`], or when [`Vec::set_len`] is used to manually
+//! "kill" some elements of a vector. Both of these cases are somewhat contrived, but it is crucial
+//! to remember to run destructors of [`Pin`]ned data. As a corollary, the following code can *never* be
+//! made safe:
+//!
+//! ```rust
+//! # use std::mem::ManuallyDrop;
+//! # use std::pin::Pin;
+//! # struct Type;
+//! let mut pinned = Box::pin(ManuallyDrop::new(Type));
+//! let inner = unsafe {
+//! Pin::map_unchecked_mut(Pin::as_mut(&mut pinned), |x| &mut *x)
+//! };
+//! ```
+//!
+//! Because [`mem::ManuallyDrop`] inhibits the destructor of `Type`, it won't get run, even though
+//! normally [`Box `] in a generic
+//! way.
+//!
+//! ## Implementing [`Drop`] for an `!Unpin` Type
+//! [drop-impl]: #implementing-drop-for-an-unpin-type
+//!
+//! The [`drop`] function takes [`&mut self`], but this is called *even if your
+//! type was previously pinned*! Implementing [`Drop`] requires some care, since it is as if
+//! the compiler automatically called [`Pin::get_unchecked_mut`].
+//! This can never cause a problem in safe code, because implementing an address-sensitive type
+//! requires unsafe code (such as the [linked list above][linked-list]).
+//!
+//! Beware that deciding to make your type address-sensitive by implementing some operation on
+//! `], or assign from
+//! a [`Pin `], for the same reason that a *move* is invalid, there is no particular reason
+//! to disallow doing it with specialized functions, as long as they know how to update all
+//! uses of the pinned address (and any other `unsafe`-assumed invariants). For [`Unmovable`],
+//! we could write
+//!
+//! ```
+//! # use std::pin::Pin;
+//! # use std::marker::PhantomPinned;
+//! # use std::ptr::NonNull;
+//! # struct Unmovable {
+//! # data: [u8; 64],
+//! # slice: NonNull<[u8]>,
+//! # _pin: PhantomPinned,
+//! # }
+//! #
+//! impl Unmovable {
+//! // Copies the contents of `src` into `self`, fixing up the self-pointer
+//! // in the process.
+//! fn assign(self: Pin<&mut Self>, src: Pin<&mut Self>) {
+//! unsafe {
+//! let unpinned_self = Pin::into_inner_unchecked(self);
+//! let unpinned_src = Pin::into_inner_unchecked(src);
+//! *unpinned_self = Self {
+//! data: unpinned_src.data,
+//! slice: NonNull::from(&mut []),
+//! _pin: PhantomPinned,
+//! };
+//!
+//! let data_ptr = unpinned_src.data.as_ptr() as *const u8;
+//! let slice_ptr = unpinned_src.slice.as_ptr() as *const u8;
+//! let offset = slice_ptr.offset_from(data_ptr) as usize;
+//! let len = (*unpinned_src.slice.as_ptr()).len();
+//!
+//! unpinned_self.slice = NonNull::from(&mut unpinned_self.data[offset..offset+len]);
+//! }
+//! }
+//! }
+//! ```
+//!
+//! Even though we can't have the compiler do the assignment for us, it's possible to write
+//! such specialized functions for types that might need it. It wouldn't be too difficult
+//! implement such a function for the [`Node`], either.
+//!
+//! Note that it _is_ possible to assign through a [`Pin `] by way of [`Pin::set()`]. This does
+//! not violate any guarantees, since it will run the destructor of the pointee before assigning
+//! the new value.
+//!
+//! ## Projections and Structural Pinning
+//!
+//! With ordinary structs, it is natural that we want to add *projection* methods
+//! that select one of the fields:
+//!
+//! ```
+//! # struct Field;
+//! struct Struct {
+//! field: Field,
+//! // ...
+//! }
+//!
+//! impl Struct {
+//! fn field(&mut self) -> &mut Field { &mut self.field }
+//! }
+//! ```
+//!
+//! When working with address-sensitive types, it's not obvious what the signature of these
+//! functions should be. If `field` takes ` docs to clarify guarantees and uses)
//! [`unsafe`]: ../../std/keyword.unsafe.html "keyword unsafe"
+//! [packed]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked
#![stable(feature = "pin", since = "1.33.0")]
@@ -386,6 +769,14 @@ use crate::fmt;
use crate::hash::{Hash, Hasher};
use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
+#[allow(unused_imports)]
+use crate::{
+ cell::{RefCell, UnsafeCell},
+ future::Future,
+ marker::PhantomPinned,
+ mem, ptr,
+};
+
/// A pinned pointer.
///
/// This is a wrapper around a kind of pointer which makes that pointer "pin" its
[Pin]<[`Box
and
+//! [`Box[Pin]<[`&mut T`]>
and
+//! [`&mut T`].
+//!
+//! This includes all of the basic types, like [`bool`], [`i32`], and [`&T`][&],
+//! as well as any other type consisting only of those types. You can opt out of
+//! [`Unpin`] via the [`PhantomPinned`] marker type.
+//!
+//! Pinning and [`Unpin`] only affect the pointee type [`P::Target`][Target], not the pointer type
+//! `P` itself. For example, whether or not [`Box[Pin]<[`Box
because `T` is the pointee type.
+//!
+//! # Examples of address-sensitive types
+//! [address-sensitive-examples]: #examples-of-address-sensitive-types
+//!
+//! ## Self-referential struct
+//! [self-ref]: #a-self-referential-struct
+//! [`Unmovable`]: #a-self-referential-struct
+//!
+//! Self-referential structs are the simplest kind of address-sensitive type.
+//!
+//! It is often useful for a struct to hold a pointer back into itself, which
+//! allows the program to efficiently track subsections of the struct.
+//! Below, the `slice` field is a pointer into the `data` field, which
+//! we could imagine being used to track a sliding window of `data` in parser
+//! code.
+//!
+//! As mentioned before, this pattern is used extensively by compiler-generated
+//! [`Future`]s.
//!
//! ```rust
//! use std::pin::Pin;
//! use std::marker::PhantomPinned;
//! use std::ptr::NonNull;
//!
-//! // This is a self-referential struct because the slice field points to the data field.
-//! // We cannot inform the compiler about that with a normal reference,
-//! // as this pattern cannot be described with the usual borrowing rules.
-//! // Instead we use a raw pointer, though one which is known not to be null,
-//! // as we know it's pointing at the string.
+//! /// This is a self-referential struct because `self.slice` points into `self.data`.
//! struct Unmovable {
-//! data: String,
-//! slice: NonNull[Some]\(v)
by [`None`], or calling [`Vec::set_len`] to "kill" some
-//! elements off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without
-//! calling the destructor first. None of this is allowed for pinned data without calling [`drop`].
+//! /// Appends the pinned `node` to the end of the list.
+//! ///
+//! /// For this function to be correct, we need two guarantees:
+//! ///
+//! /// 1. `node` never moves again so that our raw pointers to it are always valid
+//! /// 2. If a `Node`'s memory would be re-used, its destructor gets run first, removing the
+//! /// would-be-dangling references from the list.
+//! fn append(&mut self, node: Pin<&mut Node>) {
+//! // We could make `List: !Unpin` and track *which* list owns a node if we were fancier.
+//! assert!(
+//! node.pred.is_null() && node.succ.is_null(),
+//! "Node must not already be in another list.",
+//! );
//!
-//! This is exactly the kind of guarantee that the intrusive linked list from the previous
-//! section needs to function correctly.
+//! unsafe {
+//! // Unpin the `&mut Node`. This is safe, because we're not actually
+//! // moving the value, only modifying the pointers inside. This
+//! // reference cannot escape this function.
+//! let node = Pin::get_unchecked_mut(node);
//!
-//! Notice that this guarantee does *not* mean that memory does not leak! It is still
-//! completely okay to not ever call [`drop`] on a pinned element (e.g., you can still
-//! call [`mem::forget`] on a [Pin]<[Box]\
). In the example of the doubly-linked
-//! list, that element would just stay in the list. However you must not free or reuse the storage
-//! *without calling [`drop`]*.
+//! // Rearrange the pointers as appropriate for a doubly-linked list.
+//! if self.start.is_null() {
+//! self.start = node;
+//! } else {
+//! (*self.end).succ = node;
+//! node.pred = self.end;
+//! }
+//! self.end = node;
+//! }
+//! }
//!
-//! # `Drop` implementation
+//! /// Allocates a node on the heap and appends it to the end of the list.
+//! fn append_boxed(&mut self) -> Pin[&mut] self
, but this
-//! is called *even if your type was previously pinned*! It is as if the
-//! compiler automatically called [`Pin::get_unchecked_mut`].
+//! # struct Data;
+//! # impl Data { fn new() -> Self { Data } }
+//! struct Node {
+//! pred: *mut Node,
+//! succ: *mut Node,
+//! data: Data,
+//! /// `Node: Unpin` because `List` expects `Pin`ned pointers to them to remain in place.
+//! _pin: PhantomPinned,
+//! }
//!
+<<<<<<< HEAD
//! This can never cause a problem in safe code because implementing a type that
//! relies on pinning requires unsafe code, but be aware that deciding to make
//! use of pinning in your type (for example by implementing some operation on
//! [Pin]<[&]Self>
or [Pin]<[&mut] Self>
) has consequences for your
//! [`Drop`][Drop] implementation as well: if an element of your type could have been pinned,
//! you must treat [`Drop`][Drop] as implicitly taking [Pin]<[&mut] Self>
.
+=======
+//! impl Drop for Node {
+//! /// Remove pointers to `self`, allowing reuse of this memory without clients seeing garbage.
+//! fn drop(&mut self) {
+//! if self.pred.is_null() || self.succ.is_null() {
+//! // Not included: code to remove `self` if it is the head or tail of the list.
+//! return;
+//! }
+>>>>>>> 389e1e2452d (Rewrite `Pin[Pin]<[&Self][&]>
or [Pin]<[`&mut Self`]>
has consequences for your
+//! [`Drop`] implementation as well: if an element of your type could have been pinned,
+//! you must treat [`Drop`] as implicitly taking [Pin]<[`&mut Self`]>
.
+//!
+//! You should implement [`Drop`] as follows:
//!
//! ```rust,no_run
//! # use std::pin::Pin;
-//! # struct Type { }
+//! # struct Type;
//! impl Drop for Type {
//! fn drop(&mut self) {
//! // `new_unchecked` is okay because we know this value is never used
@@ -195,72 +476,136 @@
//! }
//! ```
//!
-//! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that
+//! The function `inner_drop` has the type that [`drop`] *should* have. This makes sure that
//! you do not accidentally use `self`/`this` in a way that is in conflict with pinning.
//!
-//! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically
+//! Moreover, if your type is [`#[repr(packed)]`][packed], the compiler will automatically
//! move fields around to be able to drop them. It might even do
//! that for fields that happen to be sufficiently aligned. As a consequence, you cannot use
-//! pinning with a `#[repr(packed)]` type.
-//!
-//! # Projections and Structural Pinning
-//!
-//! When working with pinned structs, the question arises how one can access the
-//! fields of that struct in a method that takes just [Pin]<[&mut] Struct>
.
-//! The usual approach is to write helper methods (so called *projections*)
-//! that turn [Pin]<[&mut] Struct>
into a reference to the field, but what type should
-//! that reference have? Is it [Pin]<[&mut] Field>
or [&mut] Field
?
-//! The same question arises with the fields of an `enum`, and also when considering
-//! container/wrapper types such as [Vec]\
, [Box]\
,
-//! or [RefCell]\
. (This question applies to both mutable and shared references,
-//! we just use the more common case of mutable references here for illustration.)
-//!
-//! It turns out that it is actually up to the author of the data structure to decide whether
-//! the pinned projection for a particular field turns [Pin]<[&mut] Struct>
-//! into [Pin]<[&mut] Field>
or [&mut] Field
. There are some
-//! constraints though, and the most important constraint is *consistency*:
-//! every field can be *either* projected to a pinned reference, *or* have
-//! pinning removed as part of the projection. If both are done for the same field,
-//! that will likely be unsound!
-//!
-//! As the author of a data structure you get to decide for each field whether pinning
+//! pinning with a [`#[repr(packed)]`][packed] type.
+//!
+//! ## "Assigning" pinned data
+//!
+//! Although in general it is not valid to swap data through a [`Pinself: [Pin]<[&mut Struct][&mut]>
, should it return
+//! [`&mut Field`] or [Pin]<[`&mut Field`]>
? This question also arises with `enum`s and
+//! wrapper types like [`Vec[Pin]\<[&mut Struct][&mut]>
also needs to take note of
+//! the address of the field itself, it may be evidence that that field is structurally
+//! pinned. Unfortunately, there are no hard-and-fast rules.
//!
-//! It may seem counter-intuitive that the field of a pinned struct might not be pinned,
-//! but that is actually the easiest choice: if a [Pin]<[&mut] Field>
is never created,
-//! nothing can go wrong! So, if you decide that some field does not have structural pinning,
-//! all you have to ensure is that you never create a pinned reference to that field.
+//! ### When pinning *is not* structural for `field`...
+//!
+//! While counter-intuitive, it's actually the easier choice: if a [Pin]<[`&mut Field`]>
+//! is never created, nothing can go wrong! So, if you decide that some field does not have
+//! structural pinning, all you have to ensure is that you never create a pinned reference to that field.
//!
//! Fields without structural pinning may have a projection method that turns
-//! [Pin]<[&mut] Struct>
into [&mut] Field
:
+//! [Pin]<[&mut Struct][&mut]>
into [`&mut Field`]:
//!
//! ```rust,no_run
//! # use std::pin::Pin;
//! # type Field = i32;
//! # struct Struct { field: Field }
//! impl Struct {
-//! fn pin_get_field(self: Pin<&mut Self>) -> &mut Field {
+//! fn field(self: Pin<&mut Self>) -> &mut Field {
//! // This is okay because `field` is never considered pinned.
//! unsafe { &mut self.get_unchecked_mut().field }
//! }
//! }
//! ```
//!
-//! You may also impl [Unpin] for Struct
*even if* the type of `field`
+//! You may also impl [Unpin] for Struct {}
*even if* the type of `field`
//! is not [`Unpin`]. What that type thinks about pinning is not relevant
-//! when no [Pin]<[&mut] Field>
is ever created.
+//! when no [Pin]<[`&mut Field`]>
is ever created.
+//!
+//! For example, the `data` field of [`Node`] does *not* need
+//! to be structurally pinned, because neither [`List`] nor
+//! [`Node`] assume anything about it.
//!
-//! ## Pinning *is* structural for `field`
+//! ### When pinning *is* structural for `field`...
//!
//! The other option is to decide that pinning is "structural" for `field`,
//! meaning that if the struct is pinned then so is the field.
//!
-//! This allows writing a projection that creates a [Pin]<[&mut] Field>
, thus
+//! This allows writing a projection that creates a [Pin]<[`&mut Field`]>
, thus
//! witnessing that the field is pinned:
//!
//! ```rust,no_run
@@ -268,83 +613,98 @@
//! # type Field = i32;
//! # struct Struct { field: Field }
//! impl Struct {
-//! fn pin_get_field(self: Pin<&mut Self>) -> Pin<&mut Field> {
+//! fn field(self: Pin<&mut Self>) -> Pin<&mut Field> {
//! // This is okay because `field` is pinned when `self` is.
//! unsafe { self.map_unchecked_mut(|s| &mut s.field) }
//! }
//! }
//! ```
//!
-//! However, structural pinning comes with a few extra requirements:
+//! For example, the `prev` and `succ` fields of a [`Node`]
+//! are always either null or valid, so [`Node`] could provide a projection with
+//! type fn([Pin]<[`&mut Node`]>) -> [Pin]<[`&mut Node`]>
for each
+//! of them. These fields need to be structurally-pinned, since the outer [`List`]
+//! assumes every [`Node`] in it is pinned.
//!
-//! 1. The struct must only be [`Unpin`] if all the structural fields are
-//! [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of
-//! the struct it is your responsibility *not* to add something like
-//! impl\
. (Notice that adding a projection operation
-//! requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break
+//! Structural pinning comes with a few extra requirements:
+//!
+//! 1. *Structural [`Unpin`].* A struct can be [`Unpin`] if, and only if, all of its
+//! structurally-pinned fields are, too. This is [`Unpin`]'s behavior by default.
+//! However, as author, it is your responsibility to not write something like
+//! unsafe impl\
. (Adding *any* projection
+//! operation requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break
//! the principle that you only have to worry about any of this if you use [`unsafe`].)
-//! 2. The destructor of the struct must not move structural fields out of its argument. This
-//! is the exact point that was raised in the [previous section][drop-impl]: [`drop`] takes
-//! [&mut] self
, but the struct (and hence its fields) might have been pinned
-//! before. You have to guarantee that you do not move a field inside your [`Drop`][Drop]
-//! implementation. In particular, as explained previously, this means that your struct
-//! must *not* be `#[repr(packed)]`.
-//! See that section for how to write [`drop`] in a way that the compiler can help you
-//! not accidentally break pinning.
-//! 3. You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
-//! once your struct is pinned, the memory that contains the
-//! content is not overwritten or deallocated without calling the content's destructors.
-//! This can be tricky, as witnessed by [VecDeque]\
: the destructor of
-//! [VecDeque]\
can fail to call [`drop`] on all elements if one of the
-//! destructors panics. This violates the [`Drop`][Drop] guarantee, because it can lead to
-//! elements being deallocated without their destructor being called.
-//! ([VecDeque]\
has no pinning projections, so this
-//! does not cause unsoundness.)
-//! 4. You must not offer any other operations that could lead to data being moved out of
+//!
+//! 2. *Pinned Destruction.* As discussed [above][drop-impl], [`drop`] takes
+//! [`&mut self`], but the struct (and hence its fields) might have been pinned
+//! before. The destructor must be written as if its argument was
+//! self: [Pin]\<[`&mut Self`]>
, instead.
+//!
+//! As a consequence, the struct *must not* be [`#[repr(packed)]`][packed].
+//!
+//! 3. *Structural Notice of Destruction.* You must uphold the the [`Drop` guarantee][drop-guarantee]:
+//! once your struct is pinned, the struct's storage cannot be re-used without calling the
+//! structurally-pinned fields' destructors, too.
+//!
+//! This can be tricky, as witnessed by [`VecDeque[Option]\
and there is a [`take`][Option::take]-like operation with type
-//! fn([Pin]<[&mut] Struct\
,
-//! that operation can be used to move a `T` out of a pinned `Structfn([Pin]<[&mut Struct\
,
+//! then that operation can be used to move a `T` out of a pinned `Struct[RefCell]\
had a method
-//! fn get_pin_mut(self: [Pin]<[&mut] Self>) -> [Pin]<[&mut] T>
.
+//! imagine if [`RefCellfn get_pin_mut(self: [Pin]<[`&mut Self`]>) -> [Pin]<[`&mut T`]>
.
//! Then we could do the following:
//! ```compile_fail
+//! # use std::cell::RefCell;
+//! # use std::pin::Pin;
//! fn exploit_ref_cell[RefCell]\
(using [RefCell]::get_pin_mut
) and then move that
+//! This is catastrophic: it means we can first pin the content of the
+//! [`RefCell[RefCell]::get_pin_mut
) and then move that
//! content using the mutable reference we got later.
//!
-//! ## Examples
+//! ### Structural Pinning examples
//!
-//! For a type like [Vec]\
, both possibilities (structural pinning or not) make
-//! sense. A [Vec]\
with structural pinning could have `get_pin`/`get_pin_mut`
+//! For a type like [`Vec[Vec]\
because that would move the (structurally
+//! [`pop`][Vec::pop] on a pinned [`Vec[Vec]\
without structural pinning could
-//! impl\
, because the contents are never pinned
-//! and the [Vec]\
itself is fine with being moved as well.
+//! A [`Vecimpl\
, because the contents are never pinned
+//! and the [`Vec[Box]\
+//! and thus they do not offer pinning projections. This is why [`Box
//! holds for all `T`. It makes sense to do this for pointer types, because moving the
-//! [Box]\
does not actually move the `T`: the [Box]\
can be freely
-//! movable (aka [`Unpin`]) even if the `T` is not. In fact, even [Pin]<[Box]\
and
-//! [Pin]<[&mut] T>
are always [`Unpin`] themselves, for the same reason:
+//! [`Box[Pin]<[`Box
and
+//! [Pin]<[`&mut T`]>
are always [`Unpin`] themselves, for the same reason:
//! their contents (the `T`) are pinned, but the pointers themselves can be moved without moving
-//! the pinned data. For both [Box]\
and [Pin]<[Box]\
,
+//! the pinned data. For both [`Box[Pin]<[`Box
,
//! whether the content is pinned is entirely independent of whether the
//! pointer is pinned, meaning pinning is *not* structural.
//!
@@ -352,9 +712,29 @@
//! for the nested futures, as you need to get pinned references to them to call [`poll`].
//! But if your combinator contains any other data that does not need to be pinned,
//! you can make those fields not structural and hence freely access them with a
-//! mutable reference even when you just have [Pin]<[&mut] Self>
(such as in your own
-//! [`poll`] implementation).
+//! mutable reference even when you just have [Pin]<[`&mut Self`]>
+//! (such as in your own [`poll`] implementation).
//!
+//! [Target]: Deref::Target "ops::Deref::Target"
+//! [`drop`]: Drop::drop "ops::Drop::drop"
+//! [`poll`]: Future::poll "future::Future::poll"
+//!
+//!
+//! [`std::alloc`]: ../../std/alloc/index.html
+//! [`Box