Midnight Exigent
Midnight Exigent

Reputation: 625

Why do I get "type annotations needed" when using the nightly implementation of try blocks?

I was playing around with try blocks but I can't figure out how to make this code work (Playground):

#![feature(try_blocks)]

fn get_val(vec: Vec<i32>) -> Result<i32, String> {
    let (v1, v2) =
        try { (vec.get(0)?, vec.get(1)?) }.ok_or("failed to collect elements".to_string())?;

    if v1 < v2 {
        return Err("condition failed".to_string());
    }
    Ok(v1 + v2)
}
error[E0282]: type annotations needed
 --> src/lib.rs:5:9
  |
5 |         try { (vec.get(0)?, vec.get(1)?) }.ok_or("failed to collect elements".to_string())?;
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
  |
  = note: type must be known at this point

Upvotes: 1

Views: 599

Answers (1)

Silvio Mayolo
Silvio Mayolo

Reputation: 70367

Rust can't infer the type of your try block. Your sample code looks like

let (v1, v2) =
    try { (vec.get(0)?, vec.get(1)?) }.ok_or("failed to collect elements".to_string())?;

In Rust, ? (and by extension the try { ... } nightly feature) can return a value of any type which implements the Try trait. Now, it's obvious to a human reader that you want Option<(&i32, &i32)>, but to the computer, you could also want some other type. Specifically, any type which implements Try and has an ok_or method would suffice.

You can make the code work with an explicit type signature

let tmp: Option<(&i32, &i32)> = try { (vec.get(0)?, vec.get(1)?) };
let (v1, v2) =
    tmp.ok_or("failed to collect elements".to_string())?;

Upvotes: 2

Related Questions