From 8458eba41bb1ae7848143f33c610b59e9614ec9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Aug 2019 13:34:57 -0700 Subject: [PATCH] Point at method call on missing annotation error Make it clearer where the type name that couldn't be infered comes from. --- .../infer/error_reporting/need_type_info.rs | 39 +++++++++++++++---- .../error_reporting/region_name.rs | 6 +-- .../issue-42234-unknown-receiver-type.stderr | 4 +- .../ui/span/type-annotations-needed-expr.rs | 3 ++ .../span/type-annotations-needed-expr.stderr | 11 ++++++ 5 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/span/type-annotations-needed-expr.rs create mode 100644 src/test/ui/span/type-annotations-needed-expr.stderr 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, - ) -> String { + ) -> (String, Option) { 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 { 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`.