kvarn_async::prelude::compact_str::core::pin

Macro pin

1.68.0 · source
pub macro pin($value:expr $(,)?) {
    ...
}
Expand description

Constructs a Pin<&mut T>, by pinning a value: T locally.

Unlike Box::pin, this does not create a new heap allocation. As explained below, the element might still end up on the heap however.

The local pinning performed by this macro is usually dubbed “stack”-pinning. Outside of async contexts locals do indeed get stored on the stack. In async functions or blocks however, any locals crossing an .await point are part of the state captured by the Future, and will use the storage of those. That storage can either be on the heap or on the stack. Therefore, local pinning is a more accurate term.

If the type of the given value does not implement Unpin, then this macro pins the value in memory in a way that prevents moves. On the other hand, if the type does implement Unpin, Pin<&mut T> behaves like &mut T, and operations such as mem::replace() or mem::take() will allow moves of the value. See the Unpin section of the pin module for details.

§Examples

§Basic usage

use core::pin::{pin, Pin};

fn stuff(foo: Pin<&mut Foo>) {
    // …
}

let pinned_foo = pin!(Foo { /* … */ });
stuff(pinned_foo);
// or, directly:
stuff(pin!(Foo { /* … */ }));

§Manually polling a Future (without Unpin bounds)

use std::{
    future::Future,
    pin::pin,
    task::{Context, Poll},
    thread,
};

/// Runs a future to completion.
fn block_on<Fut: Future>(fut: Fut) -> Fut::Output {
    let waker_that_unparks_thread = // …
    let mut cx = Context::from_waker(&waker_that_unparks_thread);
    // Pin the future so it can be polled.
    let mut pinned_fut = pin!(fut);
    loop {
        match pinned_fut.as_mut().poll(&a