about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_infer/infer/error_reporting/need_type_info.rs17
-rw-r--r--src/test/ui/closure-expected-type/expect-two-infer-vars-supply-ty-with-bound-region.stderr4
-rw-r--r--src/test/ui/issues/issue-23046.rs4
-rw-r--r--src/test/ui/issues/issue-23046.stderr13
-rw-r--r--src/test/ui/issues/issue-72690.rs62
-rw-r--r--src/test/ui/issues/issue-72690.stderr88
6 files changed, 178 insertions, 10 deletions
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`.