diff --git a/src/librustc_infer/infer/error_reporting/need_type_info.rs b/src/librustc_infer/infer/error_reporting/need_type_info.rs index 1361d5bede6..1687bcc1556 100644 --- a/src/librustc_infer/infer/error_reporting/need_type_info.rs +++ b/src/librustc_infer/infer/error_reporting/need_type_info.rs @@ -88,6 +88,17 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> { if let (None, Some(ty)) = (self.found_local_pattern, self.node_ty_contains_target(local.hir_id)) { + // 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. self.found_local_pattern = Some(&*local.pat); self.found_node_ty = Some(ty); } @@ -99,8 +110,10 @@ impl<'a, 'tcx> Visitor<'tcx> for FindHirNodeVisitor<'a, 'tcx> { if let (None, Some(ty)) = (self.found_arg_pattern, self.node_ty_contains_target(param.hir_id)) { - self.found_arg_pattern = Some(&*param.pat); - self.found_node_ty = Some(ty); + if self.target_span.contains(param.pat.span) { + self.found_arg_pattern = Some(&*param.pat); + self.found_node_ty = Some(ty); + } } } intravisit::walk_body(self, body); diff --git a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr index 2005bd4dd5c..0c6d11cd321 100644 --- a/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr +++ b/src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:27 + --> $DIR/expect-two-infer-vars-supply-ty-with-bound-region.rs:8:5 | LL | with_closure(|x: u32, y| {}); - | ^ consider giving this closure parameter a type + | ^^^^^^^^^^^^ cannot infer type for type parameter `B` declared on the function `with_closure` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23046.rs b/src/test/ui/issues/issue-23046.rs index a68369616d8..75be4a11efd 100644 --- a/src/test/ui/issues/issue-23046.rs +++ b/src/test/ui/issues/issue-23046.rs @@ -14,7 +14,7 @@ pub fn let_<'var, VAR, F: for<'v> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>> } fn main() { - let ex = |x| { //~ ERROR type annotations needed - let_(add(x,x), |y| { + let ex = |x| { + let_(add(x,x), |y| { //~ ERROR type annotations needed let_(add(x, x), |x|x)})}; } diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index 12b2eb48e7e..77555fce7c4 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -1,8 +1,13 @@ -error[E0282]: type annotations needed for `Expr<'_, VAR>` - --> $DIR/issue-23046.rs:17:15 +error[E0282]: type annotations needed for the closure `fn(Expr<'_, _>) -> Expr<'_, _>` + --> $DIR/issue-23046.rs:18:9 | -LL | let ex = |x| { - | ^ consider giving this closure parameter the explicit type `Expr<'_, VAR>`, where the type parameter `VAR` is specified +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 })})}; + | ^^^^^^^^^^^^^^^^ ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-72690.rs b/src/test/ui/issues/issue-72690.rs new file mode 100644 index 00000000000..4edbd9ca15d --- /dev/null +++ b/src/test/ui/issues/issue-72690.rs @@ -0,0 +1,62 @@ +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() {} diff --git a/src/test/ui/issues/issue-72690.stderr b/src/test/ui/issues/issue-72690.stderr new file mode 100644 index 00000000000..64e78ddf604 --- /dev/null +++ b/src/test/ui/issues/issue-72690.stderr @@ -0,0 +1,88 @@ +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`.