Traits and Box dyn

Why is this wrong and what can I do to fix this?

pub trait A
{
    fn a(&self) -> ();
}

pub trait B
{
    fn b(&self) -> ();

    fn c(&self, a : impl A + 'static) -> ();
}

struct C {}

impl A for C
{}

impl B for C
{}

struct D
{
    c : Box<dyn B + 'static>
}

impl D
{
    fn new() -> Self
    {
        return Self {
            **// this line does not compile**
            c : Box::new(C{})
        };
    }
}

Compiler says move method "c" into another trait. How should I think about this?

error[E0038]: the trait `B` cannot be made into an object
  --> src/lib.rs:23:13
   |
23 |     c : Box<dyn B + 'static>
   |             ^^^^^^^^^^^^^^^ `B` cannot be made into an object
   |
   = help: consider moving `c` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
  --> src/lib.rs:10:8
   |
6  | pub trait B
   |           - this trait cannot be made into an object...
...
10 |     fn c(&self, a : impl A + 'static) -> ();
   |        ^ ...because method `c` has generic type parameters

For more information about this error, try `rustc --explain E0038`

You can't create a trait object with the trait B as it's method c is generic. You could make it accept Box<dyn A> instead of impl A + 'static instead.

As for why you can't have a generic method on a dyn Trait: that's because a trait object needs to have access to all the concrete methods which can ever be invoked on it. This is so because trait objects are implemented using a vtable, which is an array of pointers to each function of the trait.

The trouble is, you can't just realize new concrete instantiations of a generic function at runtime, because that would require at least a JIT (which is the smaller problem) and reified generic types, i.e. a complete run-time representation of all the knowledge the compiler has about the type system (which is the bigger problem).

2 Likes

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.