19
votes

Rust performs type inference in fairly advanced situations. Could someone please explain (or point to) the rules that describe what can and cannot be inferred?

The first one is simple: The type of a binding is the type of the bound expression:

let n = 10u32;

// Same as:
//   vvvvv
let n: u32 = 10u32;

This next one is more surprising to me: The generic parameter on the right is deduced from the binding type on the left:

let n: u32 = "10".parse().unwrap();

// same as:            vvvvvvv
let n: u32 = "10".parse::<u32>().unwrap();

This also works for "member functions" of generic types:

let b = Box::new(10u32);

// same as:
//        vvvvv      vvvvvvv
let b: Box<u32> = Box::<u32>::new(10u32);

But the strangest of all is type inference across statements:

let v = Vec::new();   // no type!
v.push(10u32);        // apparently v is Vec<u32>?!
// v.push(10i32);     // type error

What are the rules for type inference and type deduction?

1
It is based on Hindler-Milner. The implementation is explained in github.com/rust-lang/rust/blob/master/src/librustc/infer/… but it is pretty outdated (still using pre-1.0 syntax). - kennytm
@kennytm: HM doesn't have a notion of "statement", does it? How does that explain something like vec!? - Kerrek SB
HM does have let x = e₁ in e₂. - kennytm
@KerrekSB: I always thought of it as basically a constraint-solver (with some Deref bonuses thrown in); I am afraid that attempting to pin-point it more is likely to become outdated in the future. - Matthieu M.
@MatthieuM.: Yeah, I can see that it works in practice as long in a way that it tries to figure out the only type assignments that make sense, but I couldn't find a systematic treatment anywhere. Code like Box::new(5) is everywhere, but it's never stated anywhere why that works. - Kerrek SB

1 Answers

10
votes

Rust uses Hindley-Milner type system. It is a set of rules about establishing types of expressions based on their usage.

Formal description and explanation for it can be found there:

"What part of Hindley-Milner do you not understand?"