pub struct Pin<Ptr> { /* private fields */ }Expand description
A pointer which pins its pointee in place.
Pin is a wrapper around some kind of pointer Ptr which makes that pointer “pin” its
pointee value in place, thus preventing the value referenced by that pointer from being moved
or otherwise invalidated at that place in memory unless it implements Unpin.
See the pin module documentation for a more thorough exploration of pinning.
§Pinning values with Pin<Ptr>
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. 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
Box, etc.) because its existence 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).
It is important to stress that the thing in the Pin is not the value which we want to pin
itself, but rather a pointer to that value! A Pin<Ptr> does not pin the Ptr but rather
the pointer’s pointee value.
The most common set of types which require pinning related guarantees for soundness are the
compiler-generated state machines that implement Future for the return value of
async fns. These compiler-generated Futures may contain self-referential 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 for the implementation of async fns 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-sourced Futures are only a small percentage of all
Futures that exist, yet we had to modify the signature of poll for all Futures
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.
The vast majority of Rust types have no reason to ever care about being pinned. These
types implement the Unpin trait, which entirely opts all values of that type out of
pinning-related guarantees. For values of these types, pinning a value by pointing to it with a
Pin<Ptr> will have no actual effect.
The reason this distinction exists is exactly to allow APIs like Future::poll to take a
Pin<Ptr> as an argument for all types while only forcing Future types that actually
care about pinning guarantees pay the ergonomics cost. For the majority of Future types
that don’t have a reason to care about being pinned and therefore implement Unpin, the
Pin<&mut Self> will act exactly like a regular &mut Self, allowing direct
access to the underlying value. Only types that don’t implement Unpin will be restricted.
§Pinning a value of a type that implements Unpin
If the type of the value you need to “pin” implements Unpin, you can trivially wrap any
pointer to that value in a Pin by calling Pin::new.
use std::pin::Pin;
// Create a value of a type that implements `Unpin`
let mut unpin_future = std::future::ready(5);
// Pin it by creating a pinning mutable reference to it (ready to be `poll`ed!)
let my_pinned_unpin_future: Pin<&mut _> = Pin::new(&mut unpin_future);§Pinning a value inside a Box
The simplest and most flexible way to pin a value that does not implement