Can't infer type

In the following code , line A does not work. In my understanding , Ok and Err are symmetric , Ok should be inferred the same way as Err. But why does not? Or what's the magic?

fn seh() {
  match try {
    Err(1)?;
    Ok(1)?;  // A not work
    1
  } {
    Err(0) => println!("err 0"),
    Err(..) => println!("err"),    
    Ok(0) => println!("ok 0"),
    Ok(..) => println!("ok"),
  };
}
1 Like

The problem is that the ? operator converts errors to a different type using Into::into before returning them. The operand of Ok(1)? could therefore be any type Result<i32, E> where E implements Into<i32>. For example, both of these lines are valid within your try block:

    Ok::<i32, u8>(1)?;
    Ok::<i32, i16>(1)?;

(Playground)

Type inference is mentioned as an open problem in the try blocks tracking issue. Some solutions have been discussed, such as fallbacks that attempt to use the same error type for all ? expressions and for the try block itself.

2 Likes

Note that there's nothing try-block specific going on here. You'll see the same thing if you just do it in a function:

pub fn seh() -> Result<i32, i32> {
    Err(1)?;
    Ok(1)?;  // A not work
    Ok(1)
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=637d8300f2ec42e15f1bb0076b2a1f58

error[E0282]: type annotations needed
 --> src/lib.rs:3:5
  |
3 |     Ok(1)?;  // A not work
  |     ^^ cannot infer type for type parameter `E` declared on the enum `Result`
2 Likes

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.