Calling non-async fn from async fn

#1

I’m porting some code to be async and I’m having some issues.

#![feature(async_await, futures_api, await_macro)]

use std::future::Future;

struct Error;
struct State;

async fn call<F: 'static, R, S: 'static>(mut state: S, mut callback: F) -> Result<S, Error>
where
    F: FnMut(&mut S) -> R,
    R: Future<Output = Result<(), Error>>
{
    unimplemented!()
}

fn dispatch(s: &mut State) -> Result<(), Error> {
    unimplemented!()
}

async fn callback(s: &mut State) -> Result<(), Error> {
    dispatch(&mut*s)
}

async fn a() -> Result<(), Error> {
    // NB shadows fn callback above
    let callback = async move |s: &mut State|  { dispatch(&mut*s) };
    let state = State;
    let state: State = await!(call(state, callback))?;
    Ok(())
}

This gives me the following error:

error: borrowed data cannot be stored outside of its closure
  --> src/lib.rs:26:48
   |
26 |     let callback = async move |s: &mut State|  { dispatch(&mut*s) };
   |                    --------------------------  ^^^^^^^^^^^^^^^^^^^^ cannot be stored outside of its closure
   |                    |
   |                    ...because it cannot outlive this closure
27 |     let state = State;
28 |     let state: State = await!(enter(state, callback))?;
   |                        ------------------------------ borrowed data cannot be stored into here...

I don’t quite understand the issue, AFAICT this closure stores no data. In fact, I can implement the closure as a function (shown just above). If I comment out the line let callback = ... to use the function, I get a different error that I don’t understand:

error[E0271]: type mismatch resolving `for<'r> <for<'s> fn(&'s mut State) -> impl std::future::Future {callback} as std::ops::FnOnce<(&'r mut State,)>>::Output == _`
  --> src/lib.rs:28:31
   |
28 |     let state: State = await!(enter(state, callback))?;
   |                               ^^^^^ expected bound lifetime parameter, found concrete lifetime
   |
note: required by `enter`
#2

I’ve found the hidden state by writing callback out as a state machine:

enum Callback<'a> {
    Init(&'a mut State),
    Done
}

impl<'a> Future for Callback<'a> {
    type Output = Result<(), Error>;
    fn poll(self: Pin<&mut Self>, w: &Waker) -> Poll<Self::Output> {
        match replace(self.get_mut(), Callback::Done) {
            Callback::Init(s) => Poll::Ready(dispatch(&mut*s)),
            Callback::Done => panic!("re-polled finished future")
        }
    }
}