Would implicit `await` really be a bad idea?

Something like this should work (I did some light testing):

use std::pin::Pin;
use std::task::{Poll, LocalWaker};
use futures_util::future::FutureExt;

pub struct Force<A> {
    future: Option<Pin<Box<A>>>,
}

impl<A> Force<A> {
    #[inline]
    pub fn new(future: A) -> Self {
        Self {
            future: Some(Box::pin(future)),
        }
    }
}

impl<A> Unpin for Force<A> {}

impl<A> Future for Force<A> where A: Future {
    type Output = Deferred<A>;

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        let mut future = self.future.take().unwrap();

        match future.poll_unpin(lw) {
            Poll::Ready(value) => Poll::Ready(Deferred {
                state: DeferredState::Ready(Some(value)),
            }),

            Poll::Pending => Poll::Ready(Deferred {
                state: DeferredState::Pending(future),
            }),
        }
    }
}


enum DeferredState<A> where A: Future {
    Ready(Option<A::Output>),
    Pending(Pin<Box<A>>),
}

pub struct Deferred<A> where A: Future {
    state: DeferredState<A>,
}

impl<A> Unpin for Deferred<A> where A: Future {}

impl<A> Future for Deferred<A> where A: Future {
    type Output = A::Output;

    fn poll(mut self: Pin<&mut Self>, lw: &LocalWaker) -> Poll<Self::Output> {
        match &mut self.state {
            DeferredState::Ready(value) => Poll::Ready(value.take().unwrap()),
            DeferredState::Pending(future) => future.poll_unpin(lw),
        }
    }
}

You use it like this:

async fn foo() {
    let x = await!(Force::new(bar()));

    ...

    let y = await!(x);
}

Basically, Force::new returns a Future which immediately polls bar(), and then you can later retrieve the value by awaiting on x.

This does have some overhead (a Box heap allocation), but perhaps that can be fixed with some trickery.

I’m not actually sure how to express this with implicit await. Maybe something like this?

async fn foo() {
    let x = async { Force::new(bar()) };

    ...

    let y = await!(x);
}

I haven’t looked too deeply at the various implicit async proposals, so I’m not sure how they handle deferred Futures.

I know they usually use async { ... } to do the actual deferral, but then how do they await the deferred Future?