Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust: Method "poll" not found in `impl std::future::Future`

Tags:

rust

I'm trying to learn async programming, but this very basic example doesn't work:

use std::future::Future;

fn main() {
    let t = async {
        println!("Hello, world!");
    };
    t.poll();
}

Everything I've read from the specs says this should work, but cargo complains that method "poll" can't be found in "impl std::future::Future". What am I doing wrong?

like image 541
devvoid Avatar asked Apr 21 '20 12:04

devvoid


1 Answers

poll has this signature:

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;

There are two problems with calling this in the way you do:

  1. poll is not implement on a future Fut, but on Pin<&mut Fut>, so you need to get a pinned reference first. pin_mut! is often useful, and if the future implements Unpin, you can use Pin::new as well.

  2. The bigger problem however is that poll takes a &mut Context<'_> argument. The context is created by the asynchronous runtime and passed in to the poll function of the outermost future. This means that you can't just poll a future like that, you need to be in an asynchronous runtime to do it.

Instead, you can use a crate like tokio or async-std to run a future in a synchronous context:

// tokio
use tokio::runtime::Runtime;
let runtime = Runtime::new().unwrap();
let result = runtime.block_on(async {
  // ...
});

// async-std
let result = async_std::task::block_on(async {
  // ...
})

Or even better, you can use #[tokio::main] or #[async_std::main] to convert your main function into an asynchronous function:

// tokio
#[tokio::main]
async fn main() {
  // ...
}

// async-std
#[async_std::main]
async fn main() {
  // ...
}
like image 118
Frxstrem Avatar answered Nov 15 '22 09:11

Frxstrem