Problem about future, please help

I am studying future, and test simple code as following

pub fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

async fn test_future_1()-> f32 {
    100.
}
fn main() {
    let mut f1 = test_future_1();
    println!("type of f1 is {}", type_of(f1));
    // f1.poll();    //error
}

This code will print

type of f1 is: "core::future::from_generator::GenFuture<future::test_future_1::{{closure}}>"

And I review code of std::future::future.rs, struct GenFuture has been implement fn poll(...) of trait Future

I change code as follow

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Waker, RawWaker, RawWakerVTable};

pub fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

fn do_nothing(ptr: *const()) {}
fn clone(ptr: *const())-> RawWaker {
    RawWaker::new(ptr, &VTABLE)
}
static VTABLE: RawWakerVTable = RawWakerVTable::new (
    clone,
    do_nothing,
    do_nothing,
    do_nothing,
);


async fn test_future_1()-> f32 {
    100.
}
fn main() {
    let mut f1 = test_future_1();
    //println!("type of f1 is {}", type_of(f1));

    let pinned = Box::pin(f1);

    //waker does nothing
    let raw = RawWaker::new(std::ptr::null(), &VTABLE);
    let waker = unsafe {Waker::from_raw(raw)};
    let cx = Context::from_waker(&waker);

    pinned.poll(&mut cx);

    //also error: error[E0599]: no method named `poll` found for mutable reference `&mut impl Future` in the current scope
    //unsafe{pinned.as_mut().get_unchecked_mut().poll(&mut cx)};

}

It still compile error:

error[E0599]: no method named `poll` found for struct `Pin<Box<impl Future>>` in the current scope
 | pinned.poll(&mut cx);
 |        ^^^^ method not found in `Pin<Box<impl Future>>`

Why is this error, pls help, thanks.

The poll method takes self: Pin<&mut Self>, so you need to pin the future before you are able to call poll on it. Here are a few ways to pin it:

let pinned = unsafe { Pin::new_unchecked(&mut f1) };
let pinned = Box::pin(f1);
tokio::pin!(f1);

Note that this is only safe if you can guarantee that f1 is never moved before it is dropped and if it isn't dropped that the memory location is never re-used again.

See std::pin - Rust for an explanation of what pinning is and why it is necessary.

Although @alice is right, this is not enough: you need to use std::future::Future.

Thanks for your and @chrefr @bjorn3's reply
I change code as follow

use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Waker, RawWaker, RawWakerVTable};

pub fn type_of<T>(_: T) -> &'static str {
    std::any::type_name::<T>()
}

fn do_nothing(ptr: *const()) {}
fn clone(ptr: *const())-> RawWaker {
    RawWaker::new(ptr, &VTABLE)
}
static VTABLE: RawWakerVTable = RawWakerVTable::new (
    clone,
    do_nothing,
    do_nothing,
    do_nothing,
);


async fn test_future_1()-> f32 {
    100.
}
fn main() {
    let mut f1 = test_future_1();
    //println!("type of f1 is {}", type_of(f1));

    let pinned = Box::pin(f1);

    //waker does nothing
    let raw = RawWaker::new(std::ptr::null(), &VTABLE);
    let waker = unsafe {Waker::from_raw(raw)};
    let cx = Context::from_waker(&waker);

    pinned.as_mut().poll(&mut cx);

}

It is ok, thanks all.

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.