No warning when using Err(()).unwrap()?

Recently I made a typo in my code, and I have been a bit disturbed by the behaviour of the compiler, which was either a bit too clever, or a bit too quiet about the code I wrote.

Here is an example of the problem:

// The following function compiles, without even a warning:
fn my_func() -> Result<String, String> {
    Err(()).unwrap()
}

// As expected, the following function does not compile:
fn my_func2(n: i32) -> Result<String, String> {
    let e = match n {
        0 => Ok(()),
        _ => Err(()),
    };
    e.unwrap() // error[E0308]: mismatched types
}

fn main() {
    println!("{:?}", my_func());
    println!("{:?}", my_func2(0));
}

As far as I understand, in the function my_func() the compiler is smart enough to detect that Err(()).unwrap() will always return ! by panicking, so the code, indeed, is valid.

But maybe at least a warning is missing in this case? I mean: who would write Err(()).unwrap() with the aim of raising a panick? For my part I discovered my typo a long time after having written it, whereas the compiler could have warned me about a potential problem.

The code is valid, but for a slightly different reason: Result has two type parameters, T which represents the success case and U which represents the failure case. unwrap returns T and Err contains U. Because you’re returning the result, the function’s return type must be T, and the type inference engine has enough information to deduce that Err(()) has the type

Result<Result<String, String>, ()>
4 Likes

Now it makes much more sense, thank you

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.