Is it possible to do something like this? If not why?
use std::error::Error;
use std::io::{self, Read};
fn main() {
if let Err(e) = foo() {
println!("Error: {}", e);
}
}
fn foo() -> Result<(), impl Error> {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer)?;
let _: i32 = buffer.parse()?;
Ok(())
}
I get this error:
error[E0282]: type annotations needed
--> src/main.rs:10:24
|
10 | fn foo() -> Result<(), impl Error> {
| ^^^^^^^^^^ cannot infer type for `_`
There are two issues here:
impl Traits
are resolved to a concrete type statically, at compile-time. Here you are trying to return two different types which implement Error
: std::io::Error
and std::num::ParseIntError
. Since the impl Trait
has to be resolved to only one type during compilation, there is no way this can be done.
The ?
operator calls From::from
to convert between error types, which means it is flexible with regard to the target type. Here, the target type is an impl Trait
, so the compiler does not have enough information to know which exact type to choose.
For these reasons, impl Traits
are not really the right tool to use here. You can solve this by one of:
Box<dyn Error>
as the return type. This implements From<E>
for Error
types so the conversion will work automatically. But it will require a dynamic allocation.From<ErrType>
for each of those types.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With