As far as I know, Rust's await
called on a future seems to call the poll method of the future. However, the poll method needs a context parameter, if I manually call the poll method on a future, I need an executor to produce a context so a waker can be produced to call wake() on. But how the compiler knows how to get a context?
Since await
is only allowed inside async
functions (or blocks), you already have a context. It is hidden from you, but the compiler can access it.
If you're interested in the exact way this works, you can inspect the HIR. A function like that:
async fn bar() {
foo().await;
}
Generates something like the following (you can choose "Show HIR" in the playground):
fn bar() -> impl Future {
std::future::from_generator(move |mut _task_context| {
let _t = {
match std::future::IntoFuture::into_future(foo()) {
mut __awaitee => loop {
match unsafe {
std::future::Future::poll(
std::pin::Pin::new_unchecked(&mut __awaitee),
std::future::get_context(_task_context),
)
} {
std::task::Poll::Ready { 0: result } => break result,
std::task::Poll::Pending {} => {}
}
_task_context = (yield ());
},
};
};
_t
})
}
You can see the compiler uses the hidden _task_context
parameter.
The code in the compiler that is responsible for await
lowering can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With