Anyhow::Result fails to compile 'expected struct'

I am trying to use the anyhow crate, specifically anyhow::Result

The sample code is

use anyhow::Result;

fn main() -> Result<()> {
    std::fs::read_to_string("hello.json").map(|s| ())
}

But it fails to compile with the message

error[E0308]: mismatched types
 --> src/main.rs:4:5
  |
3 | fn main() -> Result<()> {
  |              ---------- expected `std::result::Result<(), anyhow::Error>` because of return type
4 |     std::fs::read_to_string("hello.json").map(|s| ())
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `anyhow::Error`, found struct `std::io::Error`
  |
  = note: expected enum `std::result::Result<_, anyhow::Error>`
             found enum `std::result::Result<_, std::io::Error>`

But it should compile right? Because any type of Error can be converted to anyhow::Error.

tldr Just because the compiler knows how to convert them doesn't mean that this conversion happens if you don't tell the compiler to perform the conversion.

The read_to_string method returns a Result containing an io error, but you told the compiler that main should return a Result containing an anyhow error. Since the types don't match, it fails to compile.

To fix this, convert the error. To use the style in your post, you can use map_err to do it. Here I convert the error using into(), because the compiler knows how to convert an io error into an anyhow error.

use anyhow::Result;

fn main() -> Result<()> {
    std::fs::read_to_string("hello.json")
        .map(|s| ())
        .map_err(|err| err.into())
}

You can also use the question mark operator.

use anyhow::Result;

fn main() -> Result<()> {
    let contents = std::fs::read_to_string("hello.json")?;
}

The question mark operator contains an implicit call to .into() on the error when it returns it, so that also works.

1 Like

Thanks @alice for such a detailed answer.

The question mark operator contains an implicit call to .into() on the error when it returns it, so that also works.

This being the key piece of information.