How does async differ from a Rc<dyn Fn () -> T>?

Perhaps this would be a good example:

async fn foo() {
    // n1 is not async, so no await needed
    n1();
}

fn n1() {
    n2();
}

fn n2() {
    // you cannot use await here
    bar();
    println!("Got to n2");
}

async fn bar() {
    println!("Got to bar!");
}

playground

Try running the above. Notice how bar doesn't print anything like you might expect it to. Instead you just get this warning:

warning: unused implementer of `core::future::future::Future` that must be used
  --> src/main.rs:11:5
   |
11 |     bar();
   |     ^^^^^^
   |
   = note: `#[warn(unused_must_use)]` on by default
   = note: futures do nothing unless you `.await` or poll them

The warning correctly informs you that the future returned by bar is immediately dropped, but you have to poll it somehow before it calls println. The easiest way to poll a future is to await it from another async function, but n2 is not async, so that is not possible in this case.

alice
That is a sweet example.

However I have no idea where I would go with it.

Could you possibly, maybe, expand on it into a most minimal example of waiting on a couple of futures. Say just simple timeouts that print something when done.

That might give me the confidence to look into this whole async/await rabbit hole further.

I think this is a good point for me to stop making bad analogies and start reading documentation.

There seems to have been many proposals floating around (and lots of outdated info?).

Is there a definitive documentation / examples on how the current async/await works ?

Did you check those videos I liked to above already? They are recent and seem to be describing the state of the art.

pending macro is what I would describe as just a breakpoint. Futures rely on wake to be useful. No idea if there is a practical use of this macro.

async fn foo() {
    futures::pending!();
    println!("passed");
}
fn main() {
    futures::executor::block_on(foo());
}