about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-08-25 13:34:57 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-08-25 13:39:11 -0700
commit8458eba41bb1ae7848143f33c610b59e9614ec9b (patch)
treec69ae79091b69e2281f4c811c3db844b43d80663
parent7b0085a613e69cb69fc9e4eb5d422fa4a39d5de1 (diff)
downloadrust-8458eba41bb1ae7848143f33c610b59e9614ec9b.tar.gz
rust-8458eba41bb1ae7848143f33c610b59e9614ec9b.zip
Point at method call on missing annotation error
Make it clearer where the type name that couldn't be infered comes from.
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs39
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs6
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.stderr4
-rw-r--r--src/test/ui/span/type-annotations-needed-expr.rs3
-rw-r--r--src/test/ui/span/type-annotations-needed-expr.stderr11
5 files changed, 51 insertions, 12 deletions
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 3267505708b..5e0f973fdd3 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -150,12 +150,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         &self,
         ty: Ty<'tcx>,
         highlight: Option<ty::print::RegionHighlightMode>,
-    ) -> String {
+    ) -> (String, Option<Span>) {
         if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
             let ty_vars = self.type_variables.borrow();
-            if let TypeVariableOriginKind::TypeParameterDefinition(name) =
-                ty_vars.var_origin(ty_vid).kind {
-                return name.to_string();
+            let var_origin = ty_vars.var_origin(ty_vid);
+            if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
+                return (name.to_string(), Some(var_origin.span));
             }
         }
 
@@ -165,7 +165,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             printer.region_highlight_mode = highlight;
         }
         let _ = ty.print(printer);
-        s
+        (s, None)
     }
 
     pub fn need_type_info_err(
@@ -175,7 +175,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty: Ty<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty, None);
+        let (name, name_sp) = self.extract_type_name(&ty, None);
 
         let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
         let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -200,6 +200,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
         let err_span = if let Some(pattern) = local_visitor.found_arg_pattern {
             pattern.span
+        } else if let Some(span) = name_sp {
+            // `span` here lets us point at `sum` instead of the entire right hand side expr:
+            // error[E0282]: type annotations needed
+            //  --> file2.rs:3:15
+            //   |
+            // 3 |     let _ = x.sum() as f64;
+            //   |               ^^^ cannot infer type for `S`
+            span
         } else {
             span
         };
@@ -325,6 +333,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             };
             err.span_label(pattern.span, msg);
         }
+        // Instead of the following:
+        // error[E0282]: type annotations needed
+        //  --> file2.rs:3:15
+        //   |
+        // 3 |     let _ = x.sum() as f64;
+        //   |             --^^^--------- cannot infer type for `S`
+        //   |
+        //   = note: type must be known at this point
+        // We want:
+        // error[E0282]: type annotations needed
+        //  --> file2.rs:3:15
+        //   |
+        // 3 |     let _ = x.sum() as f64;
+        //   |               ^^^ cannot infer type for `S`
+        //   |
+        //   = note: type must be known at this point
+        let span = name_sp.unwrap_or(span);
         if !err.span.span_labels().iter().any(|span_label| {
                 span_label.label.is_some() && span_label.span == span
             }) && local_visitor.found_arg_pattern.is_none()
@@ -342,7 +367,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty: Ty<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty, None);
+        let name = self.extract_type_name(&ty, None).0;
         let mut err = struct_span_err!(
             self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
         );
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index ca68b9e31b6..75a31628a54 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -413,7 +413,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> Option<RegionName> {
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(needle_fr, *counter);
-        let type_name = infcx.extract_type_name(&argument_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)).0;
 
         debug!(
             "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -695,7 +695,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *counter);
-        let type_name = infcx.extract_type_name(&return_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&return_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
 
@@ -758,7 +758,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *counter);
-        let type_name = infcx.extract_type_name(&yield_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
 
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
index 04c2870d832..30c9adb1dce 100644
--- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
@@ -1,10 +1,10 @@
 error[E0282]: type annotations needed for `std::option::Option<_>`
-  --> $DIR/issue-42234-unknown-receiver-type.rs:7:5
+  --> $DIR/issue-42234-unknown-receiver-type.rs:7:7
    |
 LL |     let x: Option<_> = None;
    |         - consider giving `x` the explicit type `std::option::Option<_>`, where the type parameter `T` is specified
 LL |     x.unwrap().method_that_could_exist_on_some_type();
-   |     ^^^^^^^^^^ cannot infer type for `T`
+   |       ^^^^^^ cannot infer type for `T`
    |
    = note: type must be known at this point
 
diff --git a/src/test/ui/span/type-annotations-needed-expr.rs b/src/test/ui/span/type-annotations-needed-expr.rs
new file mode 100644
index 00000000000..f64dab4d7bc
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
+}
diff --git a/src/test/ui/span/type-annotations-needed-expr.stderr b/src/test/ui/span/type-annotations-needed-expr.stderr
new file mode 100644
index 00000000000..e32a542bb7a
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/type-annotations-needed-expr.rs:2:39
+   |
+LL |     let _ = (vec![1,2,3]).into_iter().sum() as f64;
+   |                                       ^^^ cannot infer type for `S`
+   |
+   = note: type must be known at this point
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.