Nikhil Navin
Nikhil Navin

Reputation: 71

Why can't rust infer types specified after arithmetic operators?

Can anyone tell me why code 1 works but code2 doesn't?

code 1

let guess: u32 = match guess.trim().parse() {
            Ok(num) => {num},
            Err(e) => {println!("{}",e);0},
        };

code 2

let guess: u32 = match guess.trim().parse() {
            Ok(num) => {num * 2},
            Err(e) => {println!("{}",e);0},
        };

error

error[E0282]: type annotations needed
  --> src/main.rs:18:16
   |
18 |             Ok(num) => {num * 2},
   |                ^^^ cannot infer type
   |
help: consider specifying the type argument in the method call
   |
17 |         let guess: u32 = match guess.trim().parse::<F>() {
   |                                                  +++++

Upvotes: 0

Views: 124

Answers (1)

mousetail
mousetail

Reputation: 8010

You could create a ambiguous type easily in this way. The Result of a operator is not unique. Consider if this existed somewhere in your code.

struct A;

// Allow this struct to be used in Parse
impl FromStr for A {
    ... // implementation of FromStr
}

// Allow this struct to be used in add
impl Add<u32> for A {
    type Output = u32;

    // implementation of Add
}

fn main() {
    let k:u32 = "".parse().unwrap() + 5
}

What variant of parse should be used? u32 or A? There is no way to tell, both would be valid. A could be defined in some external crate and thus modify code based on a situation that's hard to control.

For this reason, rust can't infer types past operators.

You can easily clarify the variant used with the turbofish (::<>) operator:

fn main() {
    let k:u32 = "".parse::<u32>().unwrap() + 5
}

Upvotes: 1

Related Questions