The compiler is unable to infer the return type of the closure.
Returning Ok(())
at the end lets the compiler infer what the type of a successful result is, but not what the error type would be. The return type of the ?
operator does include the full concrete type but it's guarantee is that this type can be converted into whatever the the surrounding function returns. So we need to fix that return type so all of the elided type annotations can be inferred.
Tyfingr's answer fixes the problem by removing the ?
, so that the return type of the closure is the same as the return type of File::create(tmp)
.
hellow's answer adds an annotation on the closure so that the compiler doesn't need to infer the type.
A third fix would be to put the type annotation on the return value:
let save_to_tmp_file = || {
let mut tmp_zip = File::create(tmp)?;
Ok(())
};
let result: Result<_, io::Error> = save_to_tmp_file();
Which is similar to hellow's edit, to put the type in the return value of main()
.
In general, you should use a Result
, and the compiler will warn you if you don't. When you handle the error, you are very likely to inadvertently provide the compiler with enough type information that none of these annotations are necessary.