Unpin

Trait Unpin 

1.33.0 · Source
pub auto trait Unpin { }
Expand description

Types that do not require any pinning guarantees.

For information on what “pinning” is, see the pin module documentation.

Implementing the Unpin trait for T expresses the fact that T is pinning-agnostic: it shall not expose nor rely on any pinning guarantees. This, in turn, means that a Pin-wrapped pointer to such a type can feature a fully unrestricted API. In other words, if T: Unpin, a value of type T will not be bound by the invariants which pinning otherwise offers, even when “pinned” by a Pin<Ptr> pointing at it. When a value of type T is pointed at by a Pin<Ptr>, Pin will not restrict access 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 Futures 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.

Unpin has no consequence at all for non-pinned data. In particular, mem::replace happily moves !Unpin data, which would be immovable when pinned (mem::replace works for any &mut T, not just when T: Unpin).

However, you cannot use mem::replace on !Unpin data which is pinned by being wrapped inside a Pin<Ptr> pointing at it. This is because you cannot (safely) use a Pin<Ptr> to get a &mut T to its pointee value, which you would need to call mem::replace, and that is what makes this system work.

So this, for example, can only be done on types implementing Unpin:

use std::mem;
use std::pin::Pin;

let mut string = "this".to_string();
let mut pinned_string = Pin::new(&mut string);

// We need a mutable reference to call `mem::replace`.
// We can obtain such a reference by (implicitly) invoking `Pin::deref_mut`,
// but that is only possible because `String` implements `Unpin`.
mem::replace(&mut *pinned_string, "other".to_string());

This trait is automatically implemented for almost every type. The compiler is free to take the conservative stance of marking types as Unpin so long as all of the types that compose its fields are also Unpin. This is because if a type implements Unpin, then it is unsound for that type’s implementation to rely on pinning-related guarantees for soundness, even when viewed through a “pinning” pointer! It is the responsibility of the implementor of a type that relies upon pinning for soundness to ensure that type is not marked as Unpin by adding [PhantomPinned] field. For more details, see the pin module docs.

Implementors§

Auto implementors§

§

impl Unpin for core::cmp::Ordering

§

impl Unpin for Infallible

§

impl Unpin for AtomicOrdering

§

impl Unpin for OneSidedRangeBound

§

impl Unpin for core::sync::atomic::Ordering

§

impl Unpin for bool

§

impl Unpin for f32

§

impl Unpin for f64

§

impl Unpin for i8

§

impl Unpin for i16

§

impl Unpin for i32

§

impl Unpin for i64

§

impl Unpin for i128

§

impl Unpin for isize

§

impl Unpin for !

§

impl Unpin for str

§

impl Unpin for u8

§

impl Unpin for u16

§

impl Unpin for u32

§

impl Unpin for u64

§

impl Unpin for u128

§

impl Unpin for ()

§

impl Unpin for usize

§

impl Unpin for Layout

§

impl Unpin for TypeId

§

impl Unpin for TryFromSliceError

§

impl Unpin for TryFromIntError

§

impl Unpin for RangeFull

§

impl Unpin for Alignment

§

impl Unpin for Utf8Error

§

impl Unpin for AtomicU32

§

impl Unpin for Duration

§

impl<'a> Unpin for Location<'a>

§

impl<'a> Unpin for PanicInfo<'a>

§

impl<'a, A> Unpin for core::option::Iter<'a, A>
where A: Unpin,

§

impl<'a, A> Unpin for core::option::IterMut<'a, A>
where A: Unpin,

§

impl<'a, T> Unpin for core::slice::Iter<'a, T>
where T: Unpin,

§

impl<'a, T> Unpin for core::slice::IterMut<'a, T>
where T: Unpin,

§

impl<A> Unpin for core::option::IntoIter<A>
where A: Unpin,

§

impl<B, C> Unpin for ControlFlow<B, C>
where C: Unpin, B: Unpin,

§

impl<Dyn> !Unpin for DynMetadata<Dyn>

§

impl<I> Unpin for Cloned<I>
where I: Unpin,

§

impl<I, F> Unpin for Map<I, F>
where I: Unpin, F: Unpin,

§

impl<Idx> Unpin for Range<Idx>
where Idx: Unpin,

§

impl<Idx> Unpin for RangeFrom<Idx>
where Idx: Unpin,

§

impl<Idx> Unpin for RangeInclusive<Idx>
where Idx: Unpin,

§

impl<Idx> Unpin for RangeTo<Idx>
where Idx: Unpin,

§

impl<Idx> Unpin for RangeToInclusive<Idx>
where Idx: Unpin,

§

impl<Ret, T> Unpin for fn(T₁, T₂, …, Tₙ) -> Ret

§

impl<T> Unpin for Bound<T>
where T: Unpin,

§

impl<T> Unpin for Option<T>
where T: Unpin,

§

impl<T> Unpin for *const T
where T: Unpin + ?Sized,

§

impl<T> Unpin for *mut T
where T: Unpin + ?Sized,

§

impl<T> Unpin for [T]
where T: Unpin,

§

impl<T> Unpin for (T₁, T₂, …, Tₙ)
where T: Unpin,

§

impl<T> Unpin for UnsafeCell<T>
where T: Unpin + ?Sized,

§

impl<T> Unpin for ManuallyDrop<T>
where T: Unpin + ?Sized,

§

impl<T> Unpin for NonNull<T>
where T: Unpin + ?Sized,

§

impl<T> Unpin for PhantomData<T>
where T: Unpin + ?Sized,

§

impl<T> Unpin for MaybeUninit<T>
where T: Unpin,

§

impl<T, E> Unpin for Result<T, E>
where T: Unpin, E: Unpin,

§

impl<T, const N: usize> Unpin for [T; N]
where T: Unpin,

§

impl<T, const N: usize> Unpin for core::array::IntoIter<T, N>
where T: Unpin,

§

impl<T, const N: usize> Unpin for [MaybeUninit<T>; N]
where T: Unpin,