Change:
This compiles just fine: But this gives a compiler error: It seems really weird that the second statement is affected like this? Empty project (created with ), unmodified (so no extra dependencies): <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
It is actually that the first statement has type error, but somehow the error is reported to the second statement. The first statement alone reports the error correctly and by fixing the error, the following compiles fine
This happens on Nightly and on Stable.
Labeling as this was a regression introduced by 1.41.0.
Assigning .
Problem seems to be that we always assume the last closure was the source of the inference failure
Just sticking a return after is enough to get the correct diagnostic in this specific instance. However, we clearly need to be smarter than that, as in a sequence of closures, any of them could be the source of an inference error (current implementation always assumes last, just adding a return always assumes first).
Definitely not the case - looking into some alternative fixes. claim
Ok this is even more subtle than I first thought. There's just far too much ambiguity here for this diagnostic code to produce a sensible suggestion. Any time a sub-expression/local pattern/argument pattern/closure's type contains the inference target it immediately becomes a candidate for suggesting on. In this case though, the inference target is , so any code that has anything to do with strings will trip the diagnostic...
Compiling the above results in this - clearly the has nothing to do with the error...
I have a similar message to: But what I don't understand is: why does it complain it can't infer the type if it clearly knows the type?

Discussion:
if let (None, Some(ty)) = (self.found_local_pattern, self.node_ty_contains_target(local.hir_id)) { <ins> // FIXME: There's a trade-off here - we can either check that our target span // is contained in `local.span` or not. If we choose to check containment // we can avoid some spurious suggestions (see #72690), but we lose // the ability to report on things like: // // ``` // let x = vec![]; // ``` // // because the target span will be in the macro expansion of `vec![]`. // At present we choose not to check containment. </ins> self.found_local_pattern = Some(&*local.pat); self.found_node_ty = Some(ty); }

if let (None, Some(ty)) = (self.found_arg_pattern, self.node_ty_contains_target(param.hir_id)) { <del> self.found_arg_pattern = Some(&*param.pat); self.found_node_ty = Some(ty); </del> <ins> if self.target_span.contains(param.pat.span) { self.found_arg_pattern = Some(&*param.pat); self.found_node_ty = Some(ty); } </ins> } } intravisit::walk_body(self, body);

error[E0282]: type annotations needed <del> --> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27 </del> <ins> --> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:5 </ins> | LL |     with_closure(|x: u32, y| {}); <del> |                           ^ consider giving this closure parameter a type </del> <ins> |     ^^^^^^^^^^^^ cannot infer type for type parameter `B` declared on the function `with_closure` </ins> error: aborting due to previous error

} fn main() { <del> let ex = |x| { //~ ERROR type annotations needed let_(add(x,x), |y| { </del> <ins> let ex = |x| { let_(add(x,x), |y| { //~ ERROR type annotations needed </ins> let_(add(x, x), |x|x)})}; }

<del> error[E0282]: type annotations needed for `Expr<'_, VAR>` --> $DIR/issue-23046.rs:17:15 </del> <ins> error[E0282]: type annotations needed for the closure `fn(Expr<'_, _>) -> Expr<'_, _>` --> $DIR/issue-23046.rs:18:9 </ins> | <del> LL |     let ex = |x| { |               ^ consider giving this closure parameter the explicit type `Expr<'_, VAR>`, where the type parameter `VAR` is specified </del> <ins> LL |         let_(add(x,x), |y| { |         ^^^^ cannot infer type for type parameter `VAR` declared on the function `let_` | help: give this closure an explicit return type without `_` placeholders | LL |             let_(add(x, x), |x|-> Expr<'_, _> { x })})}; |                                ^^^^^^^^^^^^^^^^   ^ </ins> error: aborting due to previous error

<ins> fn no_err() { |x: String| x; let _ = String::from("x"); } fn err() { String::from("x".as_ref()); //~ ERROR type annotations needed } fn arg_pat_closure_err() { |x| String::from("x".as_ref()); //~ ERROR type annotations needed } fn local_pat_closure_err() { let _ = "x".as_ref(); //~ ERROR type annotations needed } fn err_first_arg_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed |x: String| x; } fn err_second_arg_pat() { |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed } fn err_mid_arg_pat() { |x: String| x; |x: String| x; |x: String| x; |x: String| x; String::from("x".as_ref()); //~ ERROR type annotations needed |x: String| x; |x: String| x; |x: String| x; |x: String| x; } fn err_first_local_pat() { String::from("x".as_ref()); //~ ERROR type annotations needed let _ = String::from("x"); } fn err_second_local_pat() { let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed } fn err_mid_local_pat() { let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); String::from("x".as_ref()); //~ ERROR type annotations needed let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); let _ = String::from("x"); } fn main() {} </ins>

<ins> error[E0283]: type annotations needed --> $DIR/issue-72690.rs:7:5 | LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0282]: type annotations needed --> $DIR/issue-72690.rs:11:6 | LL |     |x| String::from("x".as_ref()); |      ^ consider giving this closure parameter a type error[E0283]: type annotations needed --> $DIR/issue-72690.rs:15:17 | LL |     let _ = "x".as_ref(); |                 ^^^^^^ cannot infer type for type `str` | = note: cannot satisfy `str: std::convert::AsRef<_>` error[E0283]: type annotations needed --> $DIR/issue-72690.rs:19:5 | LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0283]: type annotations needed --> $DIR/issue-72690.rs:25:5 | LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0283]: type annotations needed --> $DIR/issue-72690.rs:33:5 | LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0283]: type annotations needed for `std::string::String` --> $DIR/issue-72690.rs:41:5 | LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` LL |     let _ = String::from("x"); |         - consider giving this pattern a type | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0283]: type annotations needed for `std::string::String` --> $DIR/issue-72690.rs:47:5 | LL |     let _ = String::from("x"); |         - consider giving this pattern a type LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error[E0283]: type annotations needed for `std::string::String` --> $DIR/issue-72690.rs:55:5 | LL |     let _ = String::from("x"); |         - consider giving this pattern a type ... LL |     String::from("x".as_ref()); |     ^^^^^^^^^^^^ cannot infer type for struct `std::string::String` | = note: cannot satisfy `std::string::String: std::convert::From<&_>` = note: required by `std::convert::From::from` error: aborting due to 9 previous errors Some errors have detailed explanations: E0282, E0283. For more information about an error, try `rustc --explain E0282`. </ins>