Box<dyn Foo> vs &Foo, or: combining static and dynamic dispatch

I'm struggling with an error when I combine Trait objects with Trait bounds. Here's an example:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=46cf4f7050a066b6505b2d309c42d6a9

When I try to use a Box<dyn Foo> as a type parameter with bound Foo, I get:

the trait `Foo` is not implemented for `std::boxed::Box<dyn Foo>`

I feel caught in a Catch-22 here: I can't simply pass around a dyn Foo and apparently I can't use a Box<dyn Foo> in its place. Switching to references would make the lifetime management very complex. I've proposed a workaround, but it really doesn't seem like the right option.

Is there a more idiomatic way to deal with this? Or is the answer to simply not combine static and dynamic dispatch like this?

Add the impl to boxes too.

impl<T: Foo + ?Sized> Foo for Box<T> {
    fn bar(&self) -> &'static str {
        (&**self).bar()
    }
}

Note that you probably don't want to use &'static str, because that type can only be used for compile-time constants hard-coded in your codebase.

1 Like

Aha, so this is basically a less verbose version of my workaround. I didn't realize you could add Traits to shared types like that, good to know.

But is this actually idiomatic?

Yeah, if you want boxed trait objects to be usable like that, this is the way to do it.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.