Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Failure to apply turbofish notation on (boxed) trait objects

I can create a Write trait object that points to a (heap-stored) File object as such:

let a : Box<dyn Write> = Box::new(File::open("/dev/null").unwrap());  // Compiles fine.

Using the turbofish notation, however, produces an error (Rust 1.56.1):

let a : Box<dyn Write> = Box::<dyn Write>::new(File::open("/dev/null").unwrap());  // Fails to compile.

The error being:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

error[E0599]: the function or associated item `new` exists for struct `Box<dyn std::io::Write>`, but its trait bounds were not satisfied
    --> src/main.rs:37:48
     |
37   |     let a : Box<dyn Write> = Box::<dyn Write>::new(File::open("/dev/null").unwrap());  // Fails to compile.
     |                                                ^^^ function or associated item cannot be called on `Box<dyn std::io::Write>` due to unsatisfied trait bounds
     |
    ::: /home/daniel/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:1368:1
     |
1368 | pub trait Write {
     | --------------- doesn't satisfy `dyn std::io::Write: Sized`
     |
     = note: the following trait bounds were not satisfied:
             `dyn std::io::Write: Sized`

I’ve been poking at the problem for the better part of a day. Either I’m missing something fundamental, or the special language treatment of Box is at play here (but I don’t see how).

>Solution :

Your code is actually quite deceptive.

let a: Box<dyn Write> = Box::new(File::open("/dev/null").unwrap());

doesn’t actually create a Box<dyn Write> like you think. It first creates a Box<File>, then the Box<File> is cast into a Box<dyn Write>. If you turbofish with File, then it works:

let a: Box<dyn Write> = Box::<File>::new(File::open("/dev/null").unwrap());

So, if you want to be explicit about the type, use an as cast instead of turbofish:

// a is Box<dyn Write>
let a = Box::new(File::open("/dev/null").unwrap()) as Box<dyn Write>;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading