Sergio Ivanuzzo
Sergio Ivanuzzo

Reputation: 1922

trait objects must include the `dyn` keyword when apply on vector of FnMut

I replaced fn(x) -> y typing with FnMut(x) -> y according to my needs and according to what was suggested for me here. But I got another error:

trait objects must include the dyn keyword

This is minimal sandbox that reproduces the error.

I tried to investigate the issue. So, I found this. After that I tried to add dyn. But since I got error that size in not known at compile time, I also tried to add Box to typing like:

-> vector<Box<dyn FnMut(HandlerInput) -> Result<HandlerResponse, Error>>>

and after that tried to wrap handlers with Box::new(), but still have no success. I feel like I do something wrong.

Could somebody explain me how to fix this issue ? Maybe dyn not what I should use ? (I also tried to use impl instead, but this not helped)

Upvotes: 7

Views: 6728

Answers (1)

jthulhu
jthulhu

Reputation: 8678

There is a huge difference between fn(x) -> y and FnMut(x) -> y: the former is a type (basically, it's a pointer to a function), while the second is a trait. This means that you can't switch the one for the other. Fortunately, there is a way (actually, multiple ways) to tell Rust that you want to accept any type that implements a given trait. One of these is trait objects, whose syntax is dyn Trait where Trait is a trait.

Trait objects

Traits objects use dynamic dispatch, which means that Rust allows any type that implements a given trait Trait to be passed where a dyn Trait was expected, and the information about where the different methods are found for a given value of type dyn Trait is provided by runtime information (ie. that value also has a little table included providing that information). This means that, for instance, Rust cannot know the size of dyn Trait at compile time, simply because it could be any value, as long as its type implements Trait. For this reason, you need to allocate it on the heap, and pass a pointer to the allocated data instead. This is the job of Box.

The solution is therefore to replace any occurence of Trait as a type declaration with Box<dyn Trait> (in your case, Box<dyn FnMut(HandlerInput) -> Result<HandlerResponse, Error>>>) and make the appropriate changes (ie. (un)box your closures).

Upvotes: 8

Related Questions