You see, the first argument is not &Self, not &mut Self, but Pin<&mut Self>,
so to call poll, you need Pin<&mut X>, where X: Future, while you have just impl Future,
so you need pin it before calling poll.
Okay, so how do I pin it? let p=std::pin::Pin::new(&mut x); gives the error:
the trait bound `std::future::GenFuture<[static generator@src/main.rs:1:13: 3:2 {}]>: std::marker::Unpin` is not satisfied in `impl std::future::Future`
Pin is a whole deal on its own - if you want to get into the intricacies of using it, we can, but I think the simplest option is to just use Box::pin to turn T into Pin<Box<T>>. Something in a Pin is guaranteed to never move, and using a box here gives that guarantee.
Then using Pin::as_mut can grab a Pin<&mut T> from Pin<Box<T>>.
If you want to dive deeper into this, the std::pin module docs have a lot of detail about pinning itself, and chapter 4.1 of the rust book describes how this interacts with futures and why we need it. This reddit post is also pretty nice advice on concretely using it.
If you want to just use futures, though, I'd recommend reading through the async book and using an existing executor, like tokio or async-std. Or if you want a super simple executor, something like embedded_executor.
It's expected that all most Future users use an existing executor, and that the only pieces of code calling Future::poll are executor implementations.
I tried pinning and then as_mut (see code below), but I'm still unable to poll it (see error below).
no method named `poll` found for type `std::pin::Pin<&mut impl std::future::Future>` in the current scope
async fn f(){
}
fn main(){
let afn=f();
let mut pbox=std::boxed::Box::pin(afn);
let mut p=pbox.as_mut();
p.poll();
}
I've yet to find a simple complete hello world example for async/await that doesn't use any external libraries, and it seems strange to me that Rust would make would be possible to easily define an async function, and then provide no way of actually calling (or awaiting) it. I figured there had to be a simple way to do it, but so far it seems like I'm wrong. In any case, I wanted to see if could construct a simple hello world program for async/await without having to get into choosing a library to get it to run. There are six different ones mentioned here: http://smallcultfollowing.com/babysteps/blog/2019/11/22/announcing-the-async-interviews/
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
3 | use std::future::Future;
|
And indeed, importing the Future trait lets you call the poll method. However, you can't call poll without a std::task::Context, which brings us to...
async/await is very new. There is still a plan to have a simple executor included in the standard library eventually, but at this early stage, the standard library only includes the bare minimum to enable third-party executors.
Good point. I actually had that use line in earlier, but it didn't seem to be helping (I had other errors at the time).
Thanks for the comments. I'll take a look at those last two links. I guess the simple async/await hello world will have to wait for the standard library executor.
It's worth noting that there is no plan for stdlib to have a executor. It's explicitly the plan that std has just enough to glue things together, and external crates do the job of executor and libraries.
Specifically, tokio has existed for a long time, and existed for a long time even before async/await was released. tokio 0.1 had no integration with std futures because it and the futures 0.1 crate were the base on which async fn and std::future::Future were designed.
It's always been the plan that you use one of these crates, tokio or otherwise, and std would only provide the glue to work between all the crates. If you're waiting for an std executor, you're probably going to be waiting a long time.
Oops, I mistakenly said there was, in my previous comment. I had misunderstood some of the previous discussions about this. Though, if I understand correctly, there are at least some people who hope to propose this again at some point.
Ah- sorry! I think I'm probably a bit wrong too here, then, if there are still proposals for it. I hadn't read through the whole thread.
I.. guess it isn't out of the question. I mostly just wanted to recommend against waiting for such an executor, given that it's explicitly designed to be used with out-of-std ones.