genericsrustdynamic-dispatch

How do I write a struct with dynamic generics?


Let's say I have the following struct

trait T{}
struct A<X:T>{
    ...
}

I'm wondering whether something like this is possible

Box<A<dyn T>>

Currently I get errors

the trait `Sized` is not implemented for `(dyn T + 'static)`

but when I add

trait T:Sized{}

I get

the trait cannot be made into an object because it requires `Self: Sized`

Solution

  • It is possible, but generics have the Sized bound by default, which prevents them from being instantiated by a trait object, which is unsized. You need to specify T: ?Sized:

    trait T {}
    struct A<X: ?Sized + T> {}
    

    E.g.:

    trait T {}
    impl T for () {}
    
    struct A<X: ?Sized + T> {
        value: X,
    }
    
    fn foo() {
        let _ = Box::<A<()>>::new(A { value: () }) as Box<A<dyn T>>;
    }
    

    Playground.