The Rust compiler complains that that "type annotations needed" (E0282) on the declaration of variable array. It seems to me that Rust should be able to unambiguously infer the type of array:
The return value is known to be of type Struct because of -> Self in the new signature
This return value is expressed as Self(array) in the function body.
Therefore array must be of type [usize; 10] because no other type satisfies the struct definition for field 0 which is explicitly defined as [usize; 10] in the struct definition for Struct
I'm confused as to why the Rust compiler can't figure this out and insists on type annotations in the declaration of variable array. What's more perplexing, is that if I remove the call to [T]::sort like so:
impl Struct {
pub fn new(slice: &[usize]) -> Struct {
let array = slice.try_into().expect("not enough elements in data");
Self(array)
}
}
The compiler seemingly has no problem inferring that variable array is of type [usize; 10], presumably using the logic I listed above. Why is it that the introduction of the call to [T]::sort suddenly ambiguates the type of array?
the type checker needs to know the type of a method call. it only accept method call on a (yet fully inferred) generic type when the method is resolvable as an inherent method on the given type, or it is an trait method where the bound is known.
the method .sort() cannot be resolved for the generic type T in <[usize] as TryInto<T>>::try_into(), but the type checker requires methods to be resolved before going to next line of code. the next line does fully resolve the type T, but the inference doesn't look ahead.
Also, I have noticed that in cases like this, when the annotation is needed to resolve the method call, often only top-level type constructor (just enough to resolve the impl/method) is needed, so this is sufficient:
let mut array: [_; _] = slice.try_into().expect("not enough elements in data");
While it's not strictly impossible, it does complicate type checking a lot and worsens its performance by making it essentially fixed-point. I am not sure if there is a language with Hindley-Milner type inference that allows this.