Why Box<Box<dyn SomeTrait>> some scenarios will give `mismatched types` error?

trait Foo {
    fn say(&self){}
}

struct Bar;

impl Foo for Bar {}

fn test(_foo : Box<Box<dyn Foo>>) {}


fn main() {
    // Box::new on define var
    let bar = Box::new(Box::new(Bar));
    test(bar) // error[E0308]: mismatched types, expected trait object `dyn Foo`, found struct `Bar`
}

playground


trait Foo {
    fn say(&self){}
}

struct Bar;

impl Foo for Bar {}

fn test(_foo : Box<Box<dyn Foo>>) {}


fn main() {
    let bar = Bar;
    // Box::new on call function
    test(Box::new(Box::new(bar)))
}

playground

I'm confused by the compilation results of these two codes.

trait Foo {
    fn say(&self){}
}

struct Bar;

impl Foo for Bar {}

fn test(_foo : Box<Box<dyn Foo>>) {}


fn main() {
    let bar: Box<Box<dyn Foo>> = Box::new(Box::new(Bar));
    test(bar)
}

It works.

‘dyn Foo’ is its own type, distinct from any particular type that implements Foo. In your working version, the compiler can infer that the box needs to contain a dyn Foo object and constructs it automatically.

In the first version, the compiler doesn’t know the type you need and so does the straightforward thing of just making a plain Bar. If you specify the actual type you need, it also works correctly:

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

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.