How can I poll a `Pin<Box<dyn Future>>`?

I've used futures quite a bit in the past, and now I'm trying to create my own (crappy) executor. I found that I can't poll a Pin<Box<dyn Future>>, since it doesn't actually implement Future, even though I would normally be able to await one. Is there anything I can do to poll it?

Demonstration:

async fn wait<'a>(fut: Pin<Box<dyn Future<Output = ()> + 'a>>) {
    fut.await;
}

// error[E0599]: no method named `poll` found for struct `Pin<Box<(dyn Future<Output = ()> + 'a)>>` in the current scope
fn poll<'a>(fut: Pin<Box<dyn Future<Output = ()> + 'a>>) {
    fut.poll(Context::from_waker(Waker::noop()));
}

Thank you!

With minimal changes your code compiles:

fn poll<'a>(mut fut: Pin<Box<dyn Future<Output = ()> + 'a>>) {
    fut.as_mut().poll(&mut Context::from_waker(Waker::noop()));
}

Playground.

Are you aware of pollster? It's a runtime in about 130 LoC, you might be able to get some inspiration from it.

5 Likes

The key thing to understand about why your original program didn't work is that ordinarily, when you have a variable of type Box<Foo> and you call a method that wants &mut Foo, the compiler will automatically insert a reborrow; but when you have Pin<Box<Foo>> and need Pin<&mut Foo>, that doesn’t happen (simply because there is no such rule for Pin types), so you have to explicitly ask for it with Pin::as_mut().

3 Likes

This worked, thank you both!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.