Hello there!
I was absolutely staggered to find out that this is valid code:
trait SomeTrait {}
fn by_trait_obj(st: &dyn SomeTrait) {
by_generic(st);
}
fn by_generic<T: SomeTrait + ?Sized>(st: &T) {
}
How on earth does the Rust compiler know which T
is by_generic
going to be called with?
Is the function monophormized with every possible &T
such that T: SomeTrait
?
dyn Trait
implements Trait
itself, it's that simple.
2 Likes
H2CO3
August 17, 2021, 5:01pm
3
It doesn't. The very point of dyn Trait
is that it uses dynamic dispatch and a vtable to "remember" which concrete function it needs to forward to.
Here's a different way to say the same thing. Maybe it will be helpful.
dyn SomeTrait
is itself a type, so the compiler generates a monomorphized version of by_generic
for dyn SomeTrait
, which will forward all calls through the vtable.
4 Likes
Thank you! That's what I was missing. I thought I could get something like this to work:
use std::any::TypeId;
trait MyTrait: 'static {}
struct MyStruct;
impl MyTrait for MyStruct {}
fn get_type_id<T: MyTrait + ?Sized>(_: &T) -> TypeId {
TypeId::of::<T>()
}
fn main() {
assert_eq!(
get_type_id(&MyStruct),
get_type_id(&MyStruct as &dyn MyTrait),
);
}
But I was clearly missing the fact that dyn MyTrait
is its own type.
system
Closed
November 15, 2021, 7:41pm
6
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.