Reputation: 21420
Take the following code snippet:
fn main() -> std::result::Result<(), std::io::Error> {
println!("Bonjour le Monde");
Ok(())
}
This is perfectly fine code, but I wondered what would happen if I changed the type of the error to std::error::Error:
fn main() -> std::result::Result<(), std::error::Error> {
println!("Bonjour le Monde");
Ok(())
}
This is not good anymore:
error[E0277]: the size for values of type
(dyn std::error::Error + 'static)
cannot be known at compilation time
I fixed it like this:
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Bonjour le Monde");
Ok(())
}
So why does the main function require Box<> for standard errors, but not for io errors?
Upvotes: 3
Views: 634
Reputation: 14433
std::error::Error
is a trait included in the standard library. As Rust points out, it cannot determine how much memory will be need to store an Error
at compiled time since a structure of any size could potentially be used. As such, you need to use some form of indirection, such as a reference, a pointer, or, in this case, a Box
. See TRPL Ch.17 for more information about using trait objects.
In contrast, std::io::Error
is a structure from the std::io
module (which also happens to implement std::error::Error
). Rust does know large this structure is, so it can create a monomorphization of Result
that uses it.
Upvotes: 4