External Publication
Visit Post

Type inference breaks when a loop is added between inference points

Rust Internals [Unofficial] May 9, 2026
Source

Here is another minimal example similar to the original:

struct S {
    elem: i32
}

fn foo(a: Vec<S>) -> Vec<S> {
    let result = a.into_iter().collect();
    for s in &result {
        println!("{}", s.elem);
    }
    result
}



error[E0282]: type annotations needed
 --> src/lib.rs:8:24
  |
8 |         println!("{}", s.elem);
  |                        ^ cannot infer type

The problem is that field accesses and method calls have to be resolved based on information known before the call. This is just a limitation of the current type checker.

At println, the compiler knows that result is FromIterator<S>, and that &result is IntoIterator<Item=X> for some unknown type X. It only knows that s is of type X, and can't figure out what s.elem refers to because X is unknown.

Only later, in the last line (where we return result) does the compiler realize that result must be Vec<S> and thus that X = &S.

I think this could be fixed by having all the field accesses and method calls resolved later, when the necessary information becomes available after type checking the rest of the function.

Discussion in the ATmosphere

Loading comments...