Boxed closure returning impl Future

I am trying to store an async closure in a struct. I would normally just store the future, but the function needs to be run multiple times.

Essentially I am trying to do the following:

struct Foo { bar : Box<dyn Fn() -> impl Future<Output = ()>> }

but I'm getting the following error:

impl Trait not allowed outside of function and inherent method return types

Is there a more idiomatic method than writing the whole Future out like:
struct Foo { bar : Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()>>>> }
?

This compiles until I try to instantiate the struct. The code:
Foo { bar : Box::new(|| async { println!("Hello Async!") }) }

gives the error: expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = ()> + 'static)>>` found opaque type `impl std::future::Future

The correct type is Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>

Thanks for the response. I've adjusted the code as you said and it still gives the error:
expected struct `std::pin::Pin<std::boxed::Box<(dyn std::future::Future<Output = ()> + std::marker::Send + 'static)>>` found opaque type `impl std::future::Future

You need to do something special when creating the boxed closure. If you post the current code, I can show how to change it.

Thanks again.

I should be able to figure it out from the following:

struct Foo { bar : Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync> }

fn main()
{
    let f = Foo { bar : Box::new(|| async { println!("Hello Async!") }) };
}


I've put it together in this playground

Thanks for your help Alice, found the solution by reading a little better!

This compiles correctly:

struct Foo { bar : Box<dyn Fn() -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync> }

fn main()
{
    let f = Foo { bar : Box::new(|| Box::pin(async { println!("Hello Async!") })) };
}
2 Likes