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