How does Rust allow calling a generic function with a trait object?

Hello there!
I was absolutely staggered to find out that this is valid code:

trait SomeTrait {}

fn by_trait_obj(st: &dyn SomeTrait) {

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.


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.


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 {

fn main() {
        get_type_id(&MyStruct as &dyn MyTrait),

But I was clearly missing the fact that dyn MyTrait is its own type.

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.