Why do we need 2 functions for either static or dynamic dispatch ?
Let's say I have a function for static dispatch
fn <T: trait_method> (x: T) {
x.method();
}
I would like this method to work also for a trait object &trait_method, otherwise I have to define another function with the same code (but a different profile):
fn f (x: &trait_method) {
x.method();
}
Why can't rust be clever and call the static or dynamic version depending if he knows the type at compile time or not (for trait objects) ?
Does it do exactly what I want ? I mean it does an optimised static dispatch with no overhead when possible (when type is known), right ?
I am a bit surprised because there is no mention in the doc. I think this is really interesting to write a single function to handle static + dynamic, but the doc shows them separately.
Yes; as @bjorn3 mentioned, dyn Trait objects implement Trait, so you just need to allow an unsized object to fill the type parameter. Each type that’s used will trigger its own code generation here, and the dyn Trait type will be the dynamic dispatch version.
In all cases the type is "known", and the dispatch is "static".
It just happens that for !Sized types such as dyn Trait, the statically dispatched method is one whose logic is to perform a dynamic dispatch on the type-erased value.
And similarly, dyn Trait is a "known" type, one that is encapsulating a type-erased value.
It may look like a formal / legal / nitpick distinction to say that it statically dispatches to a dynamic dispatch, rather than saying that it performs a dynamic dispatch directly, but this difference is what allows the generic function to Just Work: the generic function does not need to special case trait objects; it's the trait objects themselves that "special case themselves".