Working of str parse method

New to Rust. Implementation of parse method in str is like this:

    pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
        FromStr::from_str(self)
    }

For example if I call "4".parse::<u32>() or "4".parse::<i32>(), how does it know which type's from_str() method to call using this single line > FromStr::from_str(self)?

2 Likes

The compiler will try to narrow it down if possible. If the compiler can't narrow it to a single type, a compilation error will be shown asking you, the developer, to disambiguate it.

4 Likes

It's type inference. The syntax FromStr::from_str(self) is a shorthand, the fully explicit notation for the function from_str of the implementation of a type Foo for the trait FromStr is <Foo as FromStr>::from_str(…).

In this case, the compiler does not know the right choice for the place where Foo stands in advance, so it's something of the form <??Unknown?? as FromStr>::from_str(…), but it knows the trait and the method,

pub trait FromStr: Sized {
    type Err;

    fn from_str(s: &str) -> Result<Self, Self::Err>;
}

and thus that the signature of <??Unknown?? as FromStr>::from_str must be

fn(&str) -> Result<??Unknown??, ??Unknown??::Err>;

where all occurrences of ??Unknown?? refer to the same not-yet-inferred type. If you match the return type, in this signature, which is the type of the expression FromStr::from_str(self), with the expected return type of the parse function, it thus knows to expect

Result<??Unknown??, ??Unknown??::Err>

to be the same type as

Result<F, F::Err>

so that, in the left type argument of the Result type, ??Unknown?? must clearly be F - mystery solved (type inferred)!

So, replacing the formerly unknown type, the call is thus ultimately <F as FromStr>::from_str(self).

7 Likes

Got it, it's the return type that's used for type inference. Thanks