Passing dyn Traits

Hey All,

I have a function that returns a boxed dyn trait, and another that takes an impl trait, and I can't figure out how to call one from the other, like:

trait Thing {}

fn get_thing(first: bool) -> Box<dyn Thing> { ... }

fn do_something(thing: impl Thing) { ... }

I've been playing with it here, but no luck:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=2b0bc6113ddc3a36a55277870eb6e736

Thanks

The problem is that Box<dyn Thing> does not automatically implement Thing. (dyn Thing does, but Box<dyn Thing> is a different type.) You could handle this by writing an explicit implementation: impl Thing for Box<dyn Thing> { ... }, or even impl<T: Thing> Thing for Box<T> { ... }. Here's an example of such an impl for std::error::Error in the standard library.

(That solution only works if Thing is a trait defined in your own crate; if it's somebody else's trait, then you can't write those impls yourself, and you will have to ask the other author to fix their interface or use a less elegant workaround.)

4 Likes

Alternatively, you can have do_something take a reference:

fn do_something<T: Thing+?Sized>(thing: &T) {}

fn main() {
    let thing = get_thing(true);
    do_something(&*thing);
}

Playground

3 Likes

Awesome. Thanks.

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.