Error: cannot be made into object when trying to implement an async function in parameter

Hello,

When I want to add an async function as parameter, then the dyn Trait cannot be made into an object.
I tried different kind of workaround, but without success...

Thank you in advance for your help.

Make sure you've read the error and the linked doc on object safety

7  |     async fn draw(&mut self, asyncfn: impl Fn(String) -> dyn Future<Output = String>);
   |              ^^^^ ...because method `draw` has generic type parameters

A trait is object safe if it has the following qualities (defined in RFC 255):

  • ...
  • Dispatchable functions require:
    • Not have any type parameters (although lifetime parameters are allowed),
    • ...

impl Fn(String) -> dyn Future<Output = String> is wrong in the first place, since the return type dyn Future, as a DST, must be put behind a pointer type. And impl Trait in argument position type is a generic type

impl Trait in argument position is syntactic sugar for a generic type parameter like <T: Trait> , except that the type is anonymous and doesn't appear in the GenericParams list.

Thus the error you saw because trait objects shouldn't have generic type parameters in their dispatchable functions.

One solution is to reduce the impl type to a non-generic type like function pointer type (i.e. fn()) but with capturing closures not allowed as per its documentation, They can be created via a coercion from both function items and non-capturing closures.
Rust Playground

Usually, if you want capturing closures to be supported, Box<dyn Fn> instead of fn() is the way to go. Rust Playground

5 Likes

I expect to become an expert for async dyn Trait like you, but I really hope it will be easier to use async as callback parameter in a function soon :wink: