Struct Pin
struct Pin<Ptr> { ... }
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 Pin;
// Create a value of a type that implements `Unpin`
let mut unpin_future = ready;
// Pin it by creating a pinning mutable reference to it (ready to be `poll`ed!)
let my_pinned_unpin_future: = new;
Pinning a value inside a Box
The simplest and most flexible way to pin a value that does not implement Unpin is to put
that value inside a Box and then turn that Box into a "pinning Box" by wrapping it
in a Pin. You can do both of these in a single step using Box::pin. Let's see an
example of using this flow to pin a Future returned from calling an async fn, a common
use case as described above.
use Pin;
async
// Call the async function to get a future back
let fut = add_one;
// Pin the future inside a pinning box
let pinned_fut: = Boxpin;
If you have a value which is already boxed, for example a Box<dyn Future>, you can pin
that value in-place at its current memory address using Box::into_pin.
use Pin;
use Future;
async
let boxed_fut = boxed_add_one;
// Pin the future inside the existing box
let pinned_fut: = Boxinto_pin;
There are similar pinning methods offered on the other standard library smart pointer types
as well, like Rc and Arc.
Pinning a value on the stack using pin!
There are some situations where it is desirable or even required (for example, in a #[no_std]
context where you don't have access to the standard library or allocation in general) to
pin a value which does not implement Unpin to its location on the stack. Doing so is
possible using the pin! macro. See its documentation for more.
Layout and ABI
[Pin<Ptr>] is guaranteed to have the same memory layout and ABI1 as Ptr.
-
There is a bit of nuance here that is still being decided about whether the aliasing semantics of
Pin<&mut T>should be different than&mut T, but this is true as of today. ↩
Implementations
impl<'a, T: ?Sized> Pin<&'a T>
unsafe fn map_unchecked<U, F>(self: Self, func: F) -> Pin<&'a U> where U: ?Sized, F: FnOnce(&T) -> &UConstructs a new pin by mapping the interior value.
For example, if you wanted to get a
Pinof a field of something, you could use this to get access to that field in one line of code. However, there are several gotchas with these "pinning projections"; see thepinmodule documentation for further details on that topic.Safety
This function is unsafe. You must guarantee that the data you return will not move so long as the argument value does not move (for example, because it is one of the fields of that value), and also that you do not move out of the argument you receive to the interior function.
const fn get_ref(self: Self) -> &'a TGets a shared reference out of a pin.
This is safe because it is not possible to move out of a shared reference. It may seem like there is an issue here with interior mutability: in fact, it is possible to move a
Tout of a&RefCell<T>. However, this is not a problem as long as there does not also exist aPin<&T>pointing to the innerTinside theRefCell, andRefCell<T>does not let you get aPin<&T>pointer to its contents. See the discussion on "pinning projections" for further details.Note:
Pinalso implementsDerefto the target, which can be used to access the inner value. However,Derefonly provides a reference that lives for as long as the borrow of thePin, not the lifetime of the reference contained in thePin. This method allows turning thePininto a reference with the same lifetime as the reference it wraps.
impl<'a, T: ?Sized> Pin<&'a mut T>
const fn into_ref(self: Self) -> Pin<&'a T>Converts this
Pin<&mut T>into aPin<&T>with the same lifetime.const fn get_mut(self: Self) -> &'a mut T where T: UnpinGets a mutable reference to the data inside of this
Pin.This requires that the data inside this
PinisUnpin.Note:
Pinalso implementsDerefMutto the data, which can be used to access the inner value. However,DerefMutonly provides a reference that lives for as long as the borrow of thePin, not the lifetime of thePinitself. This method allows turning thePininto a reference with the same lifetime as the originalPin.unsafe const fn get_unchecked_mut(self: Self) -> &'a mut TGets a mutable reference to the data inside of this
Pin.Safety
This function is unsafe. You must guarantee that you will never move the data out of the mutable reference you receive when you call this function, so that the invariants on the
Pintype can be upheld.If the underlying data is
Unpin,Pin::get_mutshould be used instead.unsafe fn map_unchecked_mut<U, F>(self: Self, func: F) -> Pin<&'a mut U> where U: ?Sized, F: FnOnce(&mut T) -> &mut UConstructs a new pin by mapping the interior value.
For example, if you wanted to get a
Pinof a field of something, you could use this to get access to that field in one line of code. However, there are several gotchas with these "pinning projections"; see thepinmodule documentation for further details on that topic.Safety
This function is unsafe. You must guarantee that the data you return will not move so long as the argument value does not move (for example, because it is one of the fields of that value), and also that you do not move out of the argument you receive to the interior function.
impl<Ptr: Deref> Pin<Ptr>
unsafe const fn new_unchecked(pointer: Ptr) -> Pin<Ptr>Constructs a new
Pin<Ptr>around a reference to some data of a type that may or may not implementUnpin.If
pointerdereferences to anUnpintype,Pin::newshould be used instead.Safety
This constructor is unsafe because we cannot guarantee that the data pointed to by
pointeris pinned. At its core, pinning a value means making the guarantee that the value's data will not be moved nor have its storage invalidated until it gets dropped. For a more thorough explanation of pinning, see thepinmodule docs.If the caller that is constructing this
Pin<Ptr>does not ensure that the dataPtrpoints to is pinned, that is a violation of the API contract and may lead to undefined behavior in later (even safe) operations.By using this method, you are also making a promise about the
Deref,DerefMut, andDropimplementations ofPtr, if they exist. Most importantly, they must not move out of theirselfarguments:Pin::as_mutandPin::as_refwill callDerefMut::deref_mutandDeref::derefon the pointer typePtrand expect these methods to uphold the pinning invariants. Moreover, by calling this method you promise that the referencePtrdereferences to will not be moved out of again; in particular, it must not be possible to obtain a&mut Ptr::Targetand then move out of that reference (using, for examplemem::swap).For example, calling
Pin::new_uncheckedon an&'a mut Tis unsafe because while you are able to pin it for the given lifetime'a, you have no control over whether it is kept pinned once'aends, and therefore cannot uphold the guarantee that a value, once pinned, remains pinned until it is dropped:use mem; use Pin;A value, once pinned, must remain pinned until it is dropped (unless its type implements
Unpin). BecausePin<&mut T>does not own the value, dropping thePinwill not drop the value and will not end the pinning contract. So moving the value after dropping thePin<&mut T>is still a violation of the API contract.Similarly, calling
Pin::new_uncheckedon anRc<T>is unsafe because there could be aliases to the same data that are not subject to the pinning restrictions:use Rc; use Pin;Pinning of closure captures
Particular care is required when using
Pin::new_uncheckedin a closure:Pin::new_unchecked(&mut var)wherevaris a by-value (moved) closure capture implicitly makes the promise that the closure itself is pinned, and that all uses of this closure capture respect that pinning.use Pin; use Context; use Future;When passing a closure to another API, it might be moving the closure any time, so
Pin::new_uncheckedon closure captures may only be used if the API explicitly documents that the closure is pinned.The better alternative is to avoid all that trouble and do the pinning in the outer function instead (here using the [
pin!][crate::pin::pin] macro):use pin; use Context; use Future;const fn as_ref(self: &Self) -> Pin<&<Ptr as >::Target> where Ptr: ~const DerefGets a shared reference to the pinned value this
Pinpoints to.This is a generic method to go from
&Pin<Pointer<T>>toPin<&T>. It is safe because, as part of the contract ofPin::new_unchecked, the pointee cannot move afterPin<Pointer<T>>got created. "Malicious" implementations ofPointer::Derefare likewise ruled out by the contract ofPin::new_unchecked.
impl<Ptr: Deref> Pin<Ptr>
unsafe const fn into_inner_unchecked(pin: Pin<Ptr>) -> PtrUnwraps this
Pin<Ptr>, returning the underlyingPtr.Safety
This function is unsafe. You must guarantee that you will continue to treat the pointer
Ptras pinned after you call this function, so that the invariants on thePintype can be upheld. If the code using the resultingPtrdoes not continue to maintain the pinning invariants that is a violation of the API contract and may lead to undefined behavior in later (safe) operations.Note that you must be able to guarantee that the data pointed to by
Ptrwill be treated as pinned all the way until itsdrophandler is complete!For more information, see the [
pinmodule docs][self]If the underlying data is
Unpin,Pin::into_innershould be used instead.
impl<Ptr: Deref<Target: Unpin>> Pin<Ptr>
const fn new(pointer: Ptr) -> Pin<Ptr>Constructs a new
Pin<Ptr>around a pointer to some data of a type that implementsUnpin.Unlike
Pin::new_unchecked, this method is safe because the pointerPtrdereferences to anUnpintype, which cancels the pinning guarantees.Examples
use Pin; let mut val: u8 = 5; // Since `val` doesn't care about being moved, we can safely create a "facade" `Pin` // which will allow `val` to participate in `Pin`-bound apis without checking that // pinning guarantees are actually upheld. let mut pinned: = new;const fn into_inner(pin: Pin<Ptr>) -> PtrUnwraps this
Pin<Ptr>, returning the underlying pointer.Doing this operation safely requires that the data pointed at by this pinning pointer implements
Unpinso that we can ignore the pinning invariants when unwrapping it.Examples
use Pin; let mut val: u8 = 5; let pinned: = new; // Unwrap the pin to get the underlying mutable reference to the value. We can do // this because `val` doesn't care about being moved, so the `Pin` was just // a "facade" anyway. let r = into_inner; assert_eq!;
impl<Ptr: DerefMut> Pin<Ptr>
const fn as_mut(self: &mut Self) -> Pin<&mut <Ptr as >::Target> where Ptr: ~const DerefMutGets a mutable reference to the pinned value this
Pin<Ptr>points to.This is a generic method to go from
&mut Pin<Pointer<T>>toPin<&mut T>. It is safe because, as part of the contract ofPin::new_unchecked, the pointee cannot move afterPin<Pointer<T>>got created. "Malicious" implementations ofPointer::DerefMutare likewise ruled out by the contract ofPin::new_unchecked.This method is useful when doing multiple calls to functions that consume the pinning pointer.
Example
use Pin; #const fn as_deref_mut(self: Pin<&mut Self>) -> Pin<&mut <Ptr as >::Target> where Ptr: ~const DerefMutGets
Pin<&mut T>to the underlying pinned value from this nestedPin-pointer.This is a generic method to go from
Pin<&mut Pin<Pointer<T>>>toPin<&mut T>. It is safe because the existence of aPin<Pointer<T>>ensures that the pointee,T, cannot move in the future, and this method does not enable the pointee to move. "Malicious" implementations ofPtr::DerefMutare likewise ruled out by the contract ofPin::new_unchecked.fn set(self: &mut Self, value: <Ptr as >::Target) where <Ptr as >::Target: SizedAssigns a new value to the memory location pointed to by the
Pin<Ptr>.This overwrites pinned data, but that is okay: the original pinned value's destructor gets run before being overwritten and the new value is also a valid value of the same type, so no pinning invariant is violated. See the
pinmodule documentation for more information on how this upholds the pinning invariants.Example
use Pin; let mut val: u8 = 5; let mut pinned: = new; println!; // 5 pinned.set; println!; // 10
impl<T: ?Sized> Pin<&'static T>
const fn static_ref(r: &'static T) -> Pin<&'static T>Gets a pinning reference from a
&'staticreference.This is safe because
Tis borrowed immutably for the'staticlifetime, which never ends.
impl<T: ?Sized> Pin<&'static mut T>
const fn static_mut(r: &'static mut T) -> Pin<&'static mut T>Gets a pinning mutable reference from a static mutable reference.
This is safe because
Tis borrowed for the'staticlifetime, which never ends.
impl<F> IntoFuture for Pin<Ptr>
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture
impl<G: ?Sized + Coroutine<R>, R> Coroutine for crate::pin::Pin<&mut G>
fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState<<Self as >::Yield, <Self as >::Return>
impl<I> IntoAsyncIterator for Pin<Ptr>
fn into_async_iter(self: Self) -> <I as IntoAsyncIterator>::IntoAsyncIter
impl<P> AsyncIterator for crate::pin::Pin<P>
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<<Self as >::Item>>fn size_hint(self: &Self) -> (usize, Option<usize>)
impl<P> Future for crate::pin::Pin<P>
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<<Self as >::Output>
impl<P, T> Receiver for Pin<Ptr>
impl<Ptr> DerefMut for Pin<Ptr>
fn deref_mut(self: &mut Self) -> &mut <Ptr as >::Target
impl<Ptr> Freeze for Pin<Ptr>
impl<Ptr> RefUnwindSafe for Pin<Ptr>
impl<Ptr> Send for Pin<Ptr>
impl<Ptr> Sync for Pin<Ptr>
impl<Ptr> Unpin for Pin<Ptr>
impl<Ptr> UnwindSafe for Pin<Ptr>
impl<Ptr, U> CoerceUnsized for Pin<Ptr>
impl<Ptr, U> DispatchFromDyn for Pin<Ptr>
impl<Ptr: $crate::clone::Clone> Clone for Pin<Ptr>
fn clone(self: &Self) -> Pin<Ptr>
impl<Ptr: $crate::marker::Copy> Copy for Pin<Ptr>
impl<Ptr: Deref<Target: Eq>> Eq for Pin<Ptr>
impl<Ptr: Deref<Target: Hash>> Hash for Pin<Ptr>
fn hash<H: Hasher>(self: &Self, state: &mut H)
impl<Ptr: Deref<Target: Ord>> Ord for Pin<Ptr>
fn cmp(self: &Self, other: &Self) -> cmp::Ordering
impl<Ptr: Deref, Q: Deref> PartialEq for Pin<Ptr>
fn eq(self: &Self, other: &Pin<Q>) -> boolfn ne(self: &Self, other: &Pin<Q>) -> bool
impl<Ptr: Deref, Q: Deref> PartialOrd for Pin<Ptr>
fn partial_cmp(self: &Self, other: &Pin<Q>) -> Option<cmp::Ordering>fn lt(self: &Self, other: &Pin<Q>) -> boolfn le(self: &Self, other: &Pin<Q>) -> boolfn gt(self: &Self, other: &Pin<Q>) -> boolfn ge(self: &Self, other: &Pin<Q>) -> bool
impl<Ptr: DerefPure> DerefPure for Pin<Ptr>
impl<Ptr: fmt::Debug> Debug for Pin<Ptr>
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl<Ptr: fmt::Display> Display for Pin<Ptr>
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl<Ptr: fmt::Pointer> Pointer for Pin<Ptr>
fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result
impl<Ptr: ~const Deref> Deref for Pin<Ptr>
fn deref(self: &Self) -> &<Ptr as >::Target
impl<T> Any for Pin<Ptr>
fn type_id(self: &Self) -> TypeId
impl<T> Borrow for Pin<Ptr>
fn borrow(self: &Self) -> &T
impl<T> BorrowMut for Pin<Ptr>
fn borrow_mut(self: &mut Self) -> &mut T
impl<T> CloneToUninit for Pin<Ptr>
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)
impl<T> From for Pin<Ptr>
fn from(t: T) -> TReturns the argument unchanged.
impl<T, U> Into for Pin<Ptr>
fn into(self: Self) -> UCalls
U::from(self).That is, this conversion is whatever the implementation of
[From]<T> for Uchooses to do.
impl<T, U> TryFrom for Pin<Ptr>
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
impl<T, U> TryInto for Pin<Ptr>
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>