{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreif4pxrysjzcpf6o7xi2ncooxl6mf2uxjlpocxnux3zd777wooe5wm",
"uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mlg5ewbtz2v2"
},
"path": "/t/type-inference-breaks-when-a-loop-is-added-between-inference-points/24232#post_7",
"publishedAt": "2026-05-09T10:09:47.000Z",
"site": "https://internals.rust-lang.org",
"textContent": "Here is another minimal example similar to the original:\n\n\n struct S {\n elem: i32\n }\n\n fn foo(a: Vec<S>) -> Vec<S> {\n let result = a.into_iter().collect();\n for s in &result {\n println!(\"{}\", s.elem);\n }\n result\n }\n\n\n\n error[E0282]: type annotations needed\n --> src/lib.rs:8:24\n |\n 8 | println!(\"{}\", s.elem);\n | ^ cannot infer type\n\n\nThe 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.\n\nAt `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.\n\nOnly later, in the last line (where we return `result`) does the compiler realize that `result` must be `Vec<S>` and thus that `X = &S`.\n\nI 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.",
"title": "Type inference breaks when a loop is added between inference points"
}