Hi all,
I'm struggling around dynamic representation of generic traits. Specifically closure in my example, but I guess the example will hold for other generic traits.
Here's a simplified example:
Some trait and structs:
trait Speaks {
fn speak(&self);
}
struct Dog {}
struct Cow {}
impl Speaks for Dog {
fn speak(&self) {
println!("woof");
}
}
impl Speaks for Cow {
fn speak(&self) {
println!("moo");
}
}
I want to create a struct that will hold a function that gets a "Speaker". This is my best effort:
This is not possible if your Runner needs to be generic. There is no way to make a dyn Whatever with generic methods, because there's no way to put the method pointers in the vtable at compilation time (not all possible materializations of the type parameters can be known upfront).
It's not entirely clear what you want to have in the end. In particular, your two Runners contain closures which are specific to Dog and Cow. Do you want a vector of Runners which each require specific types, or do you want a vector of Runners each of which can accept any Speaks? What kind of different things are Runners going to do?
For example, this non-generic fully dynamic definition compiles (and has no PhantomData),
Whenever you want some code to start from a generic/dynamic context, and then do something that's specific to a type, this must be done via the interface to that type provided by some trait. (In the extreme case, that trait would be Any.) So, you may need to expand Speaks to be more expressive to support what you need to do, rather than providing only an opaque "do your thing" operation.