rusttype-inferencetype-deduction

How does type deduction for builtin method of integer types work in rust?


I'm quite confused about how Rust infers the exact type of an integer. Type deduction seems to work differently for builtin methods than for traits implemented for multiple integers.

For example:

trait Fun {
    fn fun(self, other: Self);
}

impl Fun for i64 {
    fn fun(self, other: Self){
        println!("i64");
    }
}

impl Fun for i32 {
    fn fun(self, other: Self){
        println!("i32");
    }
}

impl Fun for u32 {
    fn fun(self, other: Self) {
        println!("u32");
    }
}

fn main() {
    0.saturating_add(1); // fails
    0i32.saturating_add(1); // ok
    0.saturating_add(1i32); // fails

    0.fun(1); // ok, i32
    0.fun(1u32); // ok, u32
    0u32.fun(1); // ok, u32
}

I would have expected saturating_add to be able to deduce the type in all three cases, just as fun was able to. Where's the difference between the two?


Solution

  • The difference is that saturating_add() is not a trait method but an inherent method, and you can't call inherent methods on an ambiguous type - similar to <_>::method(value) not working using UFCS (Universal Function Call Syntax). fun(), on the other hand, is a trait method, and you can leave Self unknown if it can be inferred - similar to you being able to do <_ as Trait>::method(value).