Reputation: 1011
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?
Upvotes: 4
Views: 861
Reputation: 71300
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.
Upvotes: 7