From 8bb094dac596a98cd3347979984834fe67bf3fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 May 2019 10:19:58 -0700 Subject: [PATCH 1/6] Add more detail to type inference error When encountering code where type inference fails, add more actionable information: ``` fn main() { let foo = Vec::new(); } ``` ``` error[E0282]: type annotations needed for `std::vec::Vec<_>` --> $DIR/vector-no-ann.rs:2:16 | LL | let foo = Vec::new(); | --- ^^^^^^^^ cannot infer type for `T` | | | consider giving `foo` the type `std::vec::Vec<_>` with the type parameter `T` specified ``` We still need to modify type printing to optionally accept a `TypeVariableTable` in order to properly print `std::vec::Vec`. CC #25633. --- .../infer/error_reporting/need_type_info.rs | 70 +++++++++++++++---- src/test/ui/issues/issue-12187-1.rs | 2 +- src/test/ui/issues/issue-12187-1.stderr | 2 +- src/test/ui/issues/issue-12187-2.rs | 2 +- src/test/ui/issues/issue-12187-2.stderr | 2 +- src/test/ui/issues/issue-17551.stderr | 4 +- src/test/ui/issues/issue-20261.stderr | 2 +- src/test/ui/issues/issue-23046.stderr | 4 +- src/test/ui/issues/issue-25368.stderr | 2 +- src/test/ui/issues/issue-7813.stderr | 4 +- ...method-ambig-one-trait-unknown-int-type.rs | 2 +- ...od-ambig-one-trait-unknown-int-type.stderr | 4 +- .../issue-42234-unknown-receiver-type.stderr | 4 +- .../cannot_infer_local_or_array.stderr | 4 +- .../cannot_infer_local_or_vec.stderr | 4 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- ...oxed-closures-failed-recursive-fn-2.stderr | 4 +- src/test/ui/vector-no-ann.rs | 2 +- src/test/ui/vector-no-ann.stderr | 4 +- 19 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 972ffbe1820a5..173f916c2824d 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -15,17 +15,18 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { hir_map: &'a hir::map::Map<'gcx>, found_local_pattern: Option<&'gcx Pat>, found_arg_pattern: Option<&'gcx Pat>, + found_ty: Option>, } impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { - fn node_matches_type(&mut self, hir_id: HirId) -> bool { + fn node_matches_type(&mut self, hir_id: HirId) -> Option> { let ty_opt = self.infcx.in_progress_tables.and_then(|tables| { tables.borrow().node_type_opt(hir_id) }); match ty_opt { Some(ty) => { let ty = self.infcx.resolve_vars_if_possible(&ty); - ty.walk().any(|inner_ty| { + if ty.walk().any(|inner_ty| { inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) { (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => { self.infcx @@ -35,9 +36,13 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { } _ => false, } - }) + }) { + Some(ty) + } else { + None + } } - None => false, + None => None, } } } @@ -48,16 +53,21 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { } fn visit_local(&mut self, local: &'gcx Local) { - if self.found_local_pattern.is_none() && self.node_matches_type(local.hir_id) { + if let (None, Some(ty)) = (self.found_local_pattern, self.node_matches_type(local.hir_id)) { self.found_local_pattern = Some(&*local.pat); + self.found_ty = Some(ty); } intravisit::walk_local(self, local); } fn visit_body(&mut self, body: &'gcx Body) { for argument in &body.arguments { - if self.found_arg_pattern.is_none() && self.node_matches_type(argument.hir_id) { + if let (None, Some(ty)) = ( + self.found_arg_pattern, + self.node_matches_type(argument.hir_id), + ) { self.found_arg_pattern = Some(&*argument.pat); + self.found_ty = Some(ty); } } intravisit::walk_body(self, body); @@ -106,6 +116,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { hir_map: &self.tcx.hir(), found_local_pattern: None, found_arg_pattern: None, + found_ty: None, }; if let Some(body_id) = body_id { @@ -113,6 +124,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { local_visitor.visit_expr(expr); } + let ty_msg = match local_visitor.found_ty { + Some(ty) if &ty.to_string() != "_" => format!(" for `{}`", ty), + _ => String::new(), + }; if let Some(pattern) = local_visitor.found_arg_pattern { err_span = pattern.span; // We don't want to show the default label for closures. @@ -131,13 +146,35 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // ^ consider giving this closure parameter a type // ``` labels.clear(); - labels.push( - (pattern.span, "consider giving this closure parameter a type".to_owned())); + labels.push((pattern.span, format!( + "consider giving this closure parameter {}", + match local_visitor.found_ty { + Some(ty) if &ty.to_string() != "_" => format!( + "the type `{}` with the type parameter `{}` specified", + ty, + name, + ), + _ => "a type".to_owned(), + }, + ))); } else if let Some(pattern) = local_visitor.found_local_pattern { if let Some(simple_ident) = pattern.simple_ident() { match pattern.span.compiler_desugaring_kind() { - None => labels.push((pattern.span, - format!("consider giving `{}` a type", simple_ident))), + None => labels.push(( + pattern.span, + format!( + "consider giving `{}` {}", + simple_ident, + match local_visitor.found_ty { + Some(ty) if &ty.to_string() != "_" => format!( + "the type `{}` with the type parameter `{}` specified", + ty, + name, + ), + _ => "a type".to_owned(), + }, + ), + )), Some(CompilerDesugaringKind::ForLoop) => labels.push(( pattern.span, "the element type for this iterator is not specified".to_owned(), @@ -147,12 +184,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { labels.push((pattern.span, "consider giving the pattern a type".to_owned())); } - } + }; - let mut err = struct_span_err!(self.tcx.sess, - err_span, - E0282, - "type annotations needed"); + let mut err = struct_span_err!( + self.tcx.sess, + err_span, + E0282, + "type annotations needed{}", + ty_msg, + ); for (target_span, label_message) in labels { err.span_label(target_span, label_message); diff --git a/src/test/ui/issues/issue-12187-1.rs b/src/test/ui/issues/issue-12187-1.rs index 37ff468e03205..86128ed94bd71 100644 --- a/src/test/ui/issues/issue-12187-1.rs +++ b/src/test/ui/issues/issue-12187-1.rs @@ -4,5 +4,5 @@ fn new() -> &'static T { fn main() { let &v = new(); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed } diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index f8df4f82e7efd..77aa736873b5c 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `&_` --> $DIR/issue-12187-1.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-12187-2.rs b/src/test/ui/issues/issue-12187-2.rs index a1cdb84977907..080a6206be76d 100644 --- a/src/test/ui/issues/issue-12187-2.rs +++ b/src/test/ui/issues/issue-12187-2.rs @@ -4,5 +4,5 @@ fn new<'r, T>() -> &'r T { fn main() { let &v = new(); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed } diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index c40ae0461ec03..4953c2b11b50a 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `&_` --> $DIR/issue-12187-2.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 40e7727752b76..3e99d307b3b6a 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `B<_>` --> $DIR/issue-17551.rs:6:15 | LL | let foo = B(marker::PhantomData); | --- ^ cannot infer type for `T` | | - | consider giving `foo` a type + | consider giving `foo` the type `B<_>` with the type parameter `T` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20261.stderr b/src/test/ui/issues/issue-20261.stderr index 5665f5893f428..c6c3f32dfe7d8 100644 --- a/src/test/ui/issues/issue-20261.stderr +++ b/src/test/ui/issues/issue-20261.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `&(_,)` --> $DIR/issue-20261.rs:4:11 | LL | for (ref i,) in [].iter() { diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index aab90a9d4403a..2ce775764045a 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `Expr<'_, _>` --> $DIR/issue-23046.rs:17:15 | LL | let ex = |x| { - | ^ consider giving this closure parameter a type + | ^ consider giving this closure parameter the type `Expr<'_, _>` with the type parameter `VAR` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index 3ad6a2569be45..3b2c3bfe4ff95 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` --> $DIR/issue-25368.rs:11:17 | LL | let (tx, rx) = channel(); diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 45b9c915885b4..8e2a69dd9e30c 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `&[_; 0]` --> $DIR/issue-7813.rs:2:13 | LL | let v = &[]; | - ^^^ cannot infer type | | - | consider giving `v` a type + | consider giving `v` the type `&[_; 0]` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs index 590e98dc35365..e33f23c64dbe1 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs @@ -22,7 +22,7 @@ impl Foo for Vec { fn m1() { // we couldn't infer the type of the vector just based on calling foo()... let mut x = Vec::new(); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed x.foo(); } diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 063a4865b1987..bae675526bd1f 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `std::vec::Vec<_>` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); | ----- ^^^^^^^^ cannot infer type for `T` | | - | consider giving `x` a type + | consider giving `x` the type `std::vec::Vec<_>` with the type parameter `T` specified error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 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 8923de5705b18..9b0d56e38b768 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `std::option::Option<_>` --> $DIR/issue-42234-unknown-receiver-type.rs:7:5 | LL | let x: Option<_> = None; - | - consider giving `x` a type + | - consider giving `x` the type `std::option::Option<_>` with the type parameter `T` specified LL | x.unwrap().method_that_could_exist_on_some_type(); | ^^^^^^^^^^ cannot infer type for `T` | diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index 17be67c6c3a0d..115808b3b3e8e 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `[_; 0]` --> $DIR/cannot_infer_local_or_array.rs:2:13 | LL | let x = []; | - ^^ cannot infer type | | - | consider giving `x` a type + | consider giving `x` the type `[_; 0]` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 8215947d49cdd..49b4330b51e2d 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `std::vec::Vec<_>` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; | - ^^^^^^ cannot infer type for `T` | | - | consider giving `x` a type + | consider giving `x` the type `std::vec::Vec<_>` with the type parameter `T` specified | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 1065d49c26b2d..57eb185a36af2 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `(std::vec::Vec<_>,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index bd58e241f0cb0..d0d8aed0cb8d8 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `std::option::Option<_>` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; - | ------------ consider giving `closure0` a type + | ------------ consider giving `closure0` the type `std::option::Option<_>` with the type parameter `_` specified ... LL | return c(); | ^^^ cannot infer type diff --git a/src/test/ui/vector-no-ann.rs b/src/test/ui/vector-no-ann.rs index 200364a5d937e..1f11d9c8dffc7 100644 --- a/src/test/ui/vector-no-ann.rs +++ b/src/test/ui/vector-no-ann.rs @@ -1,4 +1,4 @@ fn main() { let _foo = Vec::new(); - //~^ ERROR type annotations needed [E0282] + //~^ ERROR type annotations needed } diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index 01b569f97f910..6aa925e07157f 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed +error[E0282]: type annotations needed for `std::vec::Vec<_>` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); | ---- ^^^^^^^^ cannot infer type for `T` | | - | consider giving `_foo` a type + | consider giving `_foo` the type `std::vec::Vec<_>` with the type parameter `T` specified error: aborting due to previous error From 65c2a7b18bb34547de7c716ace2e8878c2676794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 May 2019 12:15:39 -0700 Subject: [PATCH 2/6] Alternative wording for inference failure --- .../infer/error_reporting/need_type_info.rs | 36 +++++++------------ src/test/ui/issues/issue-12187-1.stderr | 2 +- src/test/ui/issues/issue-12187-2.stderr | 2 +- src/test/ui/issues/issue-17551.stderr | 6 ++-- src/test/ui/issues/issue-20261.stderr | 2 +- src/test/ui/issues/issue-23046.stderr | 2 +- src/test/ui/issues/issue-25368.stderr | 4 +-- src/test/ui/issues/issue-7813.stderr | 4 +-- ...od-ambig-one-trait-unknown-int-type.stderr | 6 ++-- .../issue-42234-unknown-receiver-type.stderr | 6 ++-- .../cannot_infer_local_or_array.stderr | 4 +-- .../cannot_infer_local_or_vec.stderr | 6 ++-- ...cannot_infer_local_or_vec_in_tuples.stderr | 4 +-- ...oxed-closures-failed-recursive-fn-2.stderr | 4 +-- src/test/ui/vector-no-ann.stderr | 6 ++-- 15 files changed, 42 insertions(+), 52 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 173f916c2824d..aae7b5e1202d4 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -15,7 +15,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { hir_map: &'a hir::map::Map<'gcx>, found_local_pattern: Option<&'gcx Pat>, found_arg_pattern: Option<&'gcx Pat>, - found_ty: Option>, + found_ty: Option, } impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { @@ -55,7 +55,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { fn visit_local(&mut self, local: &'gcx Local) { if let (None, Some(ty)) = (self.found_local_pattern, self.node_matches_type(local.hir_id)) { self.found_local_pattern = Some(&*local.pat); - self.found_ty = Some(ty); + self.found_ty = Some(ty.to_string()); } intravisit::walk_local(self, local); } @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { self.node_matches_type(argument.hir_id), ) { self.found_arg_pattern = Some(&*argument.pat); - self.found_ty = Some(ty); + self.found_ty = Some(ty.to_string()); } } intravisit::walk_body(self, body); @@ -108,7 +108,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let name = self.extract_type_name(&ty, None); let mut err_span = span; - let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))]; let mut local_visitor = FindLocalByTypeVisitor { infcx: &self, @@ -124,10 +123,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { local_visitor.visit_expr(expr); } - let ty_msg = match local_visitor.found_ty { - Some(ty) if &ty.to_string() != "_" => format!(" for `{}`", ty), + let ty_msg = match &local_visitor.found_ty { + Some(ty) if &ty[..] != "_" && ty != &name => format!(" in `{}`", ty), _ => String::new(), }; + let mut labels = vec![(span, InferCtxt::missing_type_msg(&name, &ty_msg))]; + if let Some(pattern) = local_visitor.found_arg_pattern { err_span = pattern.span; // We don't want to show the default label for closures. @@ -148,8 +149,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { labels.clear(); labels.push((pattern.span, format!( "consider giving this closure parameter {}", - match local_visitor.found_ty { - Some(ty) if &ty.to_string() != "_" => format!( + match &local_visitor.found_ty { + Some(ty) if &ty[..] != "_" && ty != &name => format!( "the type `{}` with the type parameter `{}` specified", ty, name, @@ -162,18 +163,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { match pattern.span.compiler_desugaring_kind() { None => labels.push(( pattern.span, - format!( - "consider giving `{}` {}", - simple_ident, - match local_visitor.found_ty { - Some(ty) if &ty.to_string() != "_" => format!( - "the type `{}` with the type parameter `{}` specified", - ty, - name, - ), - _ => "a type".to_owned(), - }, - ), + format!("consider giving `{}` a type", simple_ident), )), Some(CompilerDesugaringKind::ForLoop) => labels.push(( pattern.span, @@ -213,15 +203,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span, E0698, "type inside generator must be known in this context"); - err.span_label(span, InferCtxt::missing_type_msg(&name)); + err.span_label(span, InferCtxt::missing_type_msg(&name, "")); err } - fn missing_type_msg(type_name: &str) -> String { + fn missing_type_msg(type_name: &str, postfix: &str) -> String { if type_name == "_" { "cannot infer type".to_owned() } else { - format!("cannot infer type for `{}`", type_name) + format!("cannot infer type for `{}`{}", type_name, postfix) } } } diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 77aa736873b5c..510eeb4b9bbd7 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `&_` +error[E0282]: type annotations needed in `&_` --> $DIR/issue-12187-1.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 4953c2b11b50a..8b12ff5f9d8c5 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `&_` +error[E0282]: type annotations needed in `&_` --> $DIR/issue-12187-2.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 3e99d307b3b6a..0d7a31fc60de6 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `B<_>` +error[E0282]: type annotations needed in `B<_>` --> $DIR/issue-17551.rs:6:15 | LL | let foo = B(marker::PhantomData); - | --- ^ cannot infer type for `T` + | --- ^ cannot infer type for `T` in `B<_>` | | - | consider giving `foo` the type `B<_>` with the type parameter `T` specified + | consider giving `foo` a type error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20261.stderr b/src/test/ui/issues/issue-20261.stderr index c6c3f32dfe7d8..c234bce4aaac8 100644 --- a/src/test/ui/issues/issue-20261.stderr +++ b/src/test/ui/issues/issue-20261.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `&(_,)` +error[E0282]: type annotations needed in `&(_,)` --> $DIR/issue-20261.rs:4:11 | LL | for (ref i,) in [].iter() { diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index 2ce775764045a..1363a6f963fe0 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed for `Expr<'_, _>` +error[E0282]: type annotations needed in `Expr<'_, _>` --> $DIR/issue-23046.rs:17:15 | LL | let ex = |x| { diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index 3b2c3bfe4ff95..5fc9ab2696970 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,11 +1,11 @@ -error[E0282]: type annotations needed for `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` +error[E0282]: type annotations needed in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` --> $DIR/issue-25368.rs:11:17 | LL | let (tx, rx) = channel(); | -------- consider giving the pattern a type ... LL | tx.send(Foo{ foo: PhantomData }); - | ^^^ cannot infer type for `T` + | ^^^ cannot infer type for `T` in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 8e2a69dd9e30c..7338032098bde 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `&[_; 0]` +error[E0282]: type annotations needed in `&[_; 0]` --> $DIR/issue-7813.rs:2:13 | LL | let v = &[]; | - ^^^ cannot infer type | | - | consider giving `v` the type `&[_; 0]` with the type parameter `_` specified + | consider giving `v` a type error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index bae675526bd1f..e8871efc5b271 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec<_>` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ----- ^^^^^^^^ cannot infer type for `T` + | ----- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` | | - | consider giving `x` the type `std::vec::Vec<_>` with the type parameter `T` specified + | consider giving `x` a type error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 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 9b0d56e38b768..2ae942e48e68a 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<_>` +error[E0282]: type annotations needed in `std::option::Option<_>` --> $DIR/issue-42234-unknown-receiver-type.rs:7:5 | LL | let x: Option<_> = None; - | - consider giving `x` the type `std::option::Option<_>` with the type parameter `T` specified + | - consider giving `x` a type LL | x.unwrap().method_that_could_exist_on_some_type(); - | ^^^^^^^^^^ cannot infer type for `T` + | ^^^^^^^^^^ cannot infer type for `T` in `std::option::Option<_>` | = note: type must be known at this point diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index 115808b3b3e8e..d3c726cf8e731 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `[_; 0]` +error[E0282]: type annotations needed in `[_; 0]` --> $DIR/cannot_infer_local_or_array.rs:2:13 | LL | let x = []; | - ^^ cannot infer type | | - | consider giving `x` the type `[_; 0]` with the type parameter `_` specified + | consider giving `x` a type error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 49b4330b51e2d..59a8b52a66d32 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec<_>` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | - ^^^^^^ cannot infer type for `T` + | - ^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` | | - | consider giving `x` the type `std::vec::Vec<_>` with the type parameter `T` specified + | consider giving `x` a type | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 57eb185a36af2..294b6d93211b1 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed for `(std::vec::Vec<_>,)` +error[E0282]: type annotations needed in `(std::vec::Vec<_>,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ----- ^^^^^^ cannot infer type for `T` + | ----- ^^^^^^ cannot infer type for `T` in `(std::vec::Vec<_>,)` | | | consider giving the pattern a type | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index d0d8aed0cb8d8..142975144d47d 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed for `std::option::Option<_>` +error[E0282]: type annotations needed in `std::option::Option<_>` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; - | ------------ consider giving `closure0` the type `std::option::Option<_>` with the type parameter `_` specified + | ------------ consider giving `closure0` a type ... LL | return c(); | ^^^ cannot infer type diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index 6aa925e07157f..2431927f2ac8c 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed for `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec<_>` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ---- ^^^^^^^^ cannot infer type for `T` + | ---- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` | | - | consider giving `_foo` the type `std::vec::Vec<_>` with the type parameter `T` specified + | consider giving `_foo` a type error: aborting due to previous error From 74fb3bbee45d54e1680832ba064fa1af8d344bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 30 May 2019 15:33:13 -0700 Subject: [PATCH 3/6] On type inference errors use the type argument name when possible ``` error[E0282]: type annotations needed in `std::result::Result` --> file7.rs:3:13 | 3 | let b = Ok(4); | - ^^ cannot infer type for `E` in `std::result::Result` | | | consider giving `b` a type` ``` --- .../infer/error_reporting/need_type_info.rs | 52 +++++++++++++++---- src/librustc/ty/print/pretty.rs | 23 +++++++- src/test/ui/issues/issue-12187-1.stderr | 2 +- src/test/ui/issues/issue-12187-2.stderr | 2 +- src/test/ui/issues/issue-17551.stderr | 4 +- src/test/ui/issues/issue-23046.stderr | 4 +- src/test/ui/issues/issue-25368.stderr | 4 +- ...od-ambig-one-trait-unknown-int-type.stderr | 4 +- .../cannot_infer_local_or_vec.stderr | 4 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 4 +- ...oxed-closures-failed-recursive-fn-2.stderr | 2 +- src/test/ui/vector-no-ann.stderr | 4 +- 12 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index aae7b5e1202d4..85ff1cbc9e4d6 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -15,7 +15,7 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { hir_map: &'a hir::map::Map<'gcx>, found_local_pattern: Option<&'gcx Pat>, found_arg_pattern: Option<&'gcx Pat>, - found_ty: Option, + found_ty: Option>, } impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { @@ -55,7 +55,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { fn visit_local(&mut self, local: &'gcx Local) { if let (None, Some(ty)) = (self.found_local_pattern, self.node_matches_type(local.hir_id)) { self.found_local_pattern = Some(&*local.pat); - self.found_ty = Some(ty.to_string()); + self.found_ty = Some(ty); } intravisit::walk_local(self, local); } @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> { self.node_matches_type(argument.hir_id), ) { self.found_arg_pattern = Some(&*argument.pat); - self.found_ty = Some(ty.to_string()); + self.found_ty = Some(ty); } } intravisit::walk_body(self, body); @@ -117,14 +117,43 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { found_arg_pattern: None, found_ty: None, }; + let ty_to_string = |ty: Ty<'tcx>| -> String { + let mut s = String::new(); + let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS); + let ty_vars = self.type_variables.borrow(); + let getter = move |ty_vid| { + if let TypeVariableOrigin::TypeParameterDefinition(_, name) = + *ty_vars.var_origin(ty_vid) { + return Some(name.to_string()); + } + None + }; + printer.name_resolver = Some(Box::new(&getter)); + let _ = ty.print(printer); + s + }; if let Some(body_id) = body_id { let expr = self.tcx.hir().expect_expr_by_hir_id(body_id.hir_id); local_visitor.visit_expr(expr); } + // When `name` corresponds to a type argument, show the path of the full type we're + // trying to infer. In the following example, `ty_msg` contains + // " in `std::result::Result`": + // ``` + // error[E0282]: type annotations needed in `std::result::Result` + // --> file.rs:L:CC + // | + // L | let b = Ok(4); + // | - ^^ cannot infer type for `E` in `std::result::Result` + // | | + // | consider giving `b` a type + // ``` let ty_msg = match &local_visitor.found_ty { - Some(ty) if &ty[..] != "_" && ty != &name => format!(" in `{}`", ty), + Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { + format!(" in `{}`", ty_to_string(ty)) + } _ => String::new(), }; let mut labels = vec![(span, InferCtxt::missing_type_msg(&name, &ty_msg))]; @@ -144,17 +173,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // After clearing, it looks something like this: // ``` // let x = |_| { }; - // ^ consider giving this closure parameter a type + // ^ consider giving this closure parameter the type `[_; 0]` + // with the type parameter `_` specified // ``` labels.clear(); labels.push((pattern.span, format!( "consider giving this closure parameter {}", match &local_visitor.found_ty { - Some(ty) if &ty[..] != "_" && ty != &name => format!( - "the type `{}` with the type parameter `{}` specified", - ty, - name, - ), + Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { + format!( + "the type `{}` with the type parameter `{}` specified", + ty_to_string(ty), + name, + ) + } _ => "a type".to_owned(), }, ))); diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index a246d9652f2f0..cd617a9368d85 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -483,7 +483,17 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: ty::FnPtr(ref bare_fn) => { p!(print(bare_fn)) } - ty::Infer(infer_ty) => p!(write("{}", infer_ty)), + ty::Infer(infer_ty) => { + if let ty::TyVar(ty_vid) = infer_ty { + if let Some(name) = self.infer_ty_name(ty_vid) { + p!(write("{}", name)) + } else { + p!(write("{}", infer_ty)) + } + } else { + p!(write("{}", infer_ty)) + } + }, ty::Error => p!(write("[type error]")), ty::Param(ref param_ty) => p!(write("{}", param_ty)), ty::Bound(debruijn, bound_ty) => { @@ -681,6 +691,10 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>: Ok(self) } + fn infer_ty_name(&self, _: ty::TyVid) -> Option { + None + } + fn pretty_print_dyn_existential( mut self, predicates: &'tcx ty::List>, @@ -931,6 +945,8 @@ pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> { binder_depth: usize, pub region_highlight_mode: RegionHighlightMode, + + pub name_resolver: Option Option>>, } impl Deref for FmtPrinter<'a, 'gcx, 'tcx, F> { @@ -957,6 +973,7 @@ impl FmtPrinter<'a, 'gcx, 'tcx, F> { region_index: 0, binder_depth: 0, region_highlight_mode: RegionHighlightMode::default(), + name_resolver: None, })) } } @@ -1206,6 +1223,10 @@ impl Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { } impl PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { + fn infer_ty_name(&self, id: ty::TyVid) -> Option { + self.0.name_resolver.as_ref().and_then(|func| func(id)) + } + fn print_value_path( mut self, def_id: DefId, diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 510eeb4b9bbd7..5f07dbc6673d9 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed in `&_` +error[E0282]: type annotations needed in `&T` --> $DIR/issue-12187-1.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 8b12ff5f9d8c5..5b44278359cdf 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed in `&_` +error[E0282]: type annotations needed in `&T` --> $DIR/issue-12187-2.rs:6:10 | LL | let &v = new(); diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 0d7a31fc60de6..95af1e41b58ef 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `B<_>` +error[E0282]: type annotations needed in `B` --> $DIR/issue-17551.rs:6:15 | LL | let foo = B(marker::PhantomData); - | --- ^ cannot infer type for `T` in `B<_>` + | --- ^ cannot infer type for `T` in `B` | | | consider giving `foo` a type diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index 1363a6f963fe0..102cfe0085fc0 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `Expr<'_, _>` +error[E0282]: type annotations needed in `Expr<'_, VAR>` --> $DIR/issue-23046.rs:17:15 | LL | let ex = |x| { - | ^ consider giving this closure parameter the type `Expr<'_, _>` with the type parameter `VAR` specified + | ^ consider giving this closure parameter the type `Expr<'_, VAR>` with the type parameter `VAR` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index 5fc9ab2696970..a386fc946284f 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,11 +1,11 @@ -error[E0282]: type annotations needed in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` +error[E0282]: type annotations needed in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` --> $DIR/issue-25368.rs:11:17 | LL | let (tx, rx) = channel(); | -------- consider giving the pattern a type ... LL | tx.send(Foo{ foo: PhantomData }); - | ^^^ cannot infer type for `T` in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` + | ^^^ cannot infer type for `T` in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index e8871efc5b271..b9fa36041b19e 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ----- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` + | ----- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | | consider giving `x` a type diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 59a8b52a66d32..a491d4516cc78 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | - ^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` + | - ^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | | consider giving `x` a type | diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 294b6d93211b1..1c5b750b9b4a9 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `(std::vec::Vec<_>,)` +error[E0282]: type annotations needed in `(std::vec::Vec,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ----- ^^^^^^ cannot infer type for `T` in `(std::vec::Vec<_>,)` + | ----- ^^^^^^ cannot infer type for `T` in `(std::vec::Vec,)` | | | consider giving the pattern a type | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 142975144d47d..dda453870dcef 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed in `std::option::Option<_>` +error[E0282]: type annotations needed in `std::option::Option` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index 2431927f2ac8c..a6c805c0c2679 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `std::vec::Vec<_>` +error[E0282]: type annotations needed in `std::vec::Vec` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ---- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec<_>` + | ---- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | | consider giving `_foo` a type From ebbe725dd0dcd5289efd80c0c99127b1518da5ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 31 May 2019 20:48:09 -0700 Subject: [PATCH 4/6] Tweak wording --- .../infer/error_reporting/need_type_info.rs | 32 ++++++++----------- src/test/ui/issues/issue-12187-1.stderr | 2 +- src/test/ui/issues/issue-12187-2.stderr | 2 +- src/test/ui/issues/issue-17551.stderr | 2 +- src/test/ui/issues/issue-25368.stderr | 2 +- src/test/ui/issues/issue-7813.stderr | 2 +- ...od-ambig-one-trait-unknown-int-type.stderr | 2 +- .../issue-42234-unknown-receiver-type.stderr | 2 +- .../cannot_infer_local_or_array.stderr | 2 +- .../cannot_infer_local_or_vec.stderr | 2 +- ...cannot_infer_local_or_vec_in_tuples.stderr | 2 +- ...oxed-closures-failed-recursive-fn-2.stderr | 2 +- src/test/ui/vector-no-ann.stderr | 2 +- 13 files changed, 25 insertions(+), 31 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 85ff1cbc9e4d6..bfe2cbbd1cdd6 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -148,13 +148,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // L | let b = Ok(4); // | - ^^ cannot infer type for `E` in `std::result::Result` // | | - // | consider giving `b` a type + // | consider giving `b` the type `std::result::Result` with the type + // | parameter `E` specified // ``` - let ty_msg = match &local_visitor.found_ty { + let (ty_msg, suffix) = match &local_visitor.found_ty { Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { - format!(" in `{}`", ty_to_string(ty)) + let ty = ty_to_string(ty); + (format!(" in `{}`", ty), + format!( "the type `{}` with the type parameter `{}` specified", ty, name)) } - _ => String::new(), + _ => (String::new(), "a type".to_owned()), }; let mut labels = vec![(span, InferCtxt::missing_type_msg(&name, &ty_msg))]; @@ -177,25 +180,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // with the type parameter `_` specified // ``` labels.clear(); - labels.push((pattern.span, format!( - "consider giving this closure parameter {}", - match &local_visitor.found_ty { - Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { - format!( - "the type `{}` with the type parameter `{}` specified", - ty_to_string(ty), - name, - ) - } - _ => "a type".to_owned(), - }, - ))); + labels.push(( + pattern.span, + format!("consider giving this closure parameter {}", suffix), + )); } else if let Some(pattern) = local_visitor.found_local_pattern { if let Some(simple_ident) = pattern.simple_ident() { match pattern.span.compiler_desugaring_kind() { None => labels.push(( pattern.span, - format!("consider giving `{}` a type", simple_ident), + format!("consider giving `{}` {}", simple_ident, suffix), )), Some(CompilerDesugaringKind::ForLoop) => labels.push(( pattern.span, @@ -204,7 +198,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { _ => {} } } else { - labels.push((pattern.span, "consider giving the pattern a type".to_owned())); + labels.push((pattern.span, format!("consider giving this pattern {}", suffix))); } }; diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 5f07dbc6673d9..25340a2e24276 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -5,7 +5,7 @@ LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving the pattern a type + | consider giving this pattern the type `&T` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 5b44278359cdf..e0f060b26e69a 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -5,7 +5,7 @@ LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving the pattern a type + | consider giving this pattern the type `&T` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 95af1e41b58ef..11dd66129d21e 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `B` LL | let foo = B(marker::PhantomData); | --- ^ cannot infer type for `T` in `B` | | - | consider giving `foo` a type + | consider giving `foo` the type `B` with the type parameter `T` specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index a386fc946284f..3f0beaee3b1ab 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed in `(std::sync::mpsc::Sender>, std: --> $DIR/issue-25368.rs:11:17 | LL | let (tx, rx) = channel(); - | -------- consider giving the pattern a type + | -------- consider giving this pattern the type `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` with the type parameter `T` specified ... LL | tx.send(Foo{ foo: PhantomData }); | ^^^ cannot infer type for `T` in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 7338032098bde..65088079476b7 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `&[_; 0]` LL | let v = &[]; | - ^^^ cannot infer type | | - | consider giving `v` a type + | consider giving `v` the type `&[_; 0]` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index b9fa36041b19e..842aa8a1f3859 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `std::vec::Vec` LL | let mut x = Vec::new(); | ----- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | - | consider giving `x` a type + | consider giving `x` the type `std::vec::Vec` with the type parameter `T` specified error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 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 2ae942e48e68a..5e05216532126 100644 --- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr +++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed in `std::option::Option<_>` --> $DIR/issue-42234-unknown-receiver-type.rs:7:5 | LL | let x: Option<_> = None; - | - consider giving `x` a type + | - consider giving `x` the type `std::option::Option<_>` with the type parameter `T` specified LL | x.unwrap().method_that_could_exist_on_some_type(); | ^^^^^^^^^^ cannot infer type for `T` in `std::option::Option<_>` | diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index d3c726cf8e731..428ea6de6ed9c 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `[_; 0]` LL | let x = []; | - ^^ cannot infer type | | - | consider giving `x` a type + | consider giving `x` the type `[_; 0]` with the type parameter `_` specified error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index a491d4516cc78..8d0dc18ab90dd 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `std::vec::Vec` LL | let x = vec![]; | - ^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | - | consider giving `x` a type + | consider giving `x` the type `std::vec::Vec` with the type parameter `T` specified | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 1c5b750b9b4a9..5cd898f3fefc7 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `(std::vec::Vec,)` LL | let (x, ) = (vec![], ); | ----- ^^^^^^ cannot infer type for `T` in `(std::vec::Vec,)` | | - | consider giving the pattern a type + | consider giving this pattern the type `(std::vec::Vec,)` with the type parameter `T` specified | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index dda453870dcef..4804983b8618b 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed in `std::option::Option` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; - | ------------ consider giving `closure0` a type + | ------------ consider giving `closure0` the type `std::option::Option` with the type parameter `_` specified ... LL | return c(); | ^^^ cannot infer type diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index a6c805c0c2679..3ece3063cd032 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed in `std::vec::Vec` LL | let _foo = Vec::new(); | ---- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` | | - | consider giving `_foo` a type + | consider giving `_foo` the type `std::vec::Vec` with the type parameter `T` specified error: aborting due to previous error From 9616b333b229d31943d88d871a3075a041c4f58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Jun 2019 14:47:15 -0700 Subject: [PATCH 5/6] review comment: tweak wording --- .../infer/error_reporting/need_type_info.rs | 22 +++++++++++-------- src/test/ui/issues/issue-12187-1.stderr | 4 ++-- src/test/ui/issues/issue-12187-2.stderr | 4 ++-- src/test/ui/issues/issue-17551.stderr | 6 ++--- src/test/ui/issues/issue-20261.stderr | 2 +- src/test/ui/issues/issue-23046.stderr | 4 ++-- src/test/ui/issues/issue-25368.stderr | 6 ++--- src/test/ui/issues/issue-7813.stderr | 4 ++-- ...od-ambig-one-trait-unknown-int-type.stderr | 6 ++--- .../issue-42234-unknown-receiver-type.stderr | 6 ++--- .../cannot_infer_local_or_array.stderr | 4 ++-- .../cannot_infer_local_or_vec.stderr | 6 ++--- ...cannot_infer_local_or_vec_in_tuples.stderr | 6 ++--- ...oxed-closures-failed-recursive-fn-2.stderr | 4 ++-- src/test/ui/vector-no-ann.stderr | 6 ++--- 15 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index bfe2cbbd1cdd6..51c69f98d978d 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -142,24 +142,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // trying to infer. In the following example, `ty_msg` contains // " in `std::result::Result`": // ``` - // error[E0282]: type annotations needed in `std::result::Result` + // error[E0282]: type annotations needed for `std::result::Result` // --> file.rs:L:CC // | // L | let b = Ok(4); // | - ^^ cannot infer type for `E` in `std::result::Result` // | | - // | consider giving `b` the type `std::result::Result` with the type - // | parameter `E` specified + // | consider giving `b` the explicit type `std::result::Result`, where + // | the type parameter `E` is specified // ``` let (ty_msg, suffix) = match &local_visitor.found_ty { Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { let ty = ty_to_string(ty); - (format!(" in `{}`", ty), - format!( "the type `{}` with the type parameter `{}` specified", ty, name)) + (format!(" for `{}`", ty), + format!( + "the explicit type `{}`, where the type parameter `{}` is specified", + ty, + name, + )) } _ => (String::new(), "a type".to_owned()), }; - let mut labels = vec![(span, InferCtxt::missing_type_msg(&name, &ty_msg))]; + let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))]; if let Some(pattern) = local_visitor.found_arg_pattern { err_span = pattern.span; @@ -229,15 +233,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { span, E0698, "type inside generator must be known in this context"); - err.span_label(span, InferCtxt::missing_type_msg(&name, "")); + err.span_label(span, InferCtxt::missing_type_msg(&name)); err } - fn missing_type_msg(type_name: &str, postfix: &str) -> String { + fn missing_type_msg(type_name: &str) -> String { if type_name == "_" { "cannot infer type".to_owned() } else { - format!("cannot infer type for `{}`{}", type_name, postfix) + format!("cannot infer type for `{}`", type_name) } } } diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 25340a2e24276..850e61a9cc2df 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -1,11 +1,11 @@ -error[E0282]: type annotations needed in `&T` +error[E0282]: type annotations needed for `&T` --> $DIR/issue-12187-1.rs:6:10 | LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving this pattern the type `&T` with the type parameter `_` specified + | consider giving this pattern the explicit type `&T`, where the type parameter `_` is specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index e0f060b26e69a..4cf2b9010a846 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -1,11 +1,11 @@ -error[E0282]: type annotations needed in `&T` +error[E0282]: type annotations needed for `&T` --> $DIR/issue-12187-2.rs:6:10 | LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving this pattern the type `&T` with the type parameter `_` specified + | consider giving this pattern the explicit type `&T`, where the type parameter `_` is specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17551.stderr b/src/test/ui/issues/issue-17551.stderr index 11dd66129d21e..ce16f0f58eaf0 100644 --- a/src/test/ui/issues/issue-17551.stderr +++ b/src/test/ui/issues/issue-17551.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `B` +error[E0282]: type annotations needed for `B` --> $DIR/issue-17551.rs:6:15 | LL | let foo = B(marker::PhantomData); - | --- ^ cannot infer type for `T` in `B` + | --- ^ cannot infer type for `T` | | - | consider giving `foo` the type `B` with the type parameter `T` specified + | consider giving `foo` the explicit type `B`, where the type parameter `T` is specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20261.stderr b/src/test/ui/issues/issue-20261.stderr index c234bce4aaac8..c6c3f32dfe7d8 100644 --- a/src/test/ui/issues/issue-20261.stderr +++ b/src/test/ui/issues/issue-20261.stderr @@ -1,4 +1,4 @@ -error[E0282]: type annotations needed in `&(_,)` +error[E0282]: type annotations needed for `&(_,)` --> $DIR/issue-20261.rs:4:11 | LL | for (ref i,) in [].iter() { diff --git a/src/test/ui/issues/issue-23046.stderr b/src/test/ui/issues/issue-23046.stderr index 102cfe0085fc0..12b2eb48e7eaa 100644 --- a/src/test/ui/issues/issue-23046.stderr +++ b/src/test/ui/issues/issue-23046.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `Expr<'_, VAR>` +error[E0282]: type annotations needed for `Expr<'_, VAR>` --> $DIR/issue-23046.rs:17:15 | LL | let ex = |x| { - | ^ consider giving this closure parameter the type `Expr<'_, VAR>` with the type parameter `VAR` specified + | ^ consider giving this closure parameter the explicit type `Expr<'_, VAR>`, where the type parameter `VAR` is specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-25368.stderr b/src/test/ui/issues/issue-25368.stderr index 3f0beaee3b1ab..0b890b573da13 100644 --- a/src/test/ui/issues/issue-25368.stderr +++ b/src/test/ui/issues/issue-25368.stderr @@ -1,11 +1,11 @@ -error[E0282]: type annotations needed in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` +error[E0282]: type annotations needed for `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` --> $DIR/issue-25368.rs:11:17 | LL | let (tx, rx) = channel(); - | -------- consider giving this pattern the type `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` with the type parameter `T` specified + | -------- consider giving this pattern the explicit type `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)`, where the type parameter `T` is specified ... LL | tx.send(Foo{ foo: PhantomData }); - | ^^^ cannot infer type for `T` in `(std::sync::mpsc::Sender>, std::sync::mpsc::Receiver>)` + | ^^^ cannot infer type for `T` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 65088079476b7..813b41663eebb 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `&[_; 0]` +error[E0282]: type annotations needed for `&[_; 0]` --> $DIR/issue-7813.rs:2:13 | LL | let v = &[]; | - ^^^ cannot infer type | | - | consider giving `v` the type `&[_; 0]` with the type parameter `_` specified + | consider giving `v` the explicit type `&[_; 0]`, where the type parameter `_` is specified error: aborting due to previous error diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 842aa8a1f3859..b1bd749bef4a2 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `std::vec::Vec` +error[E0282]: type annotations needed for `std::vec::Vec` --> $DIR/method-ambig-one-trait-unknown-int-type.rs:24:17 | LL | let mut x = Vec::new(); - | ----- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` + | ----- ^^^^^^^^ cannot infer type for `T` | | - | consider giving `x` the type `std::vec::Vec` with the type parameter `T` specified + | consider giving `x` the explicit type `std::vec::Vec`, where the type parameter `T` is specified error[E0308]: mismatched types --> $DIR/method-ambig-one-trait-unknown-int-type.rs:33:20 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 5e05216532126..04c2870d83297 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 in `std::option::Option<_>` +error[E0282]: type annotations needed for `std::option::Option<_>` --> $DIR/issue-42234-unknown-receiver-type.rs:7:5 | LL | let x: Option<_> = None; - | - consider giving `x` the type `std::option::Option<_>` with the type parameter `T` specified + | - 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` in `std::option::Option<_>` + | ^^^^^^^^^^ cannot infer type for `T` | = note: type must be known at this point diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index 428ea6de6ed9c..06b757b0398f0 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `[_; 0]` +error[E0282]: type annotations needed for `[_; 0]` --> $DIR/cannot_infer_local_or_array.rs:2:13 | LL | let x = []; | - ^^ cannot infer type | | - | consider giving `x` the type `[_; 0]` with the type parameter `_` specified + | consider giving `x` the explicit type `[_; 0]`, where the type parameter `_` is specified error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr index 8d0dc18ab90dd..6524bf5dd2bc5 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `std::vec::Vec` +error[E0282]: type annotations needed for `std::vec::Vec` --> $DIR/cannot_infer_local_or_vec.rs:2:13 | LL | let x = vec![]; - | - ^^^^^^ cannot infer type for `T` in `std::vec::Vec` + | - ^^^^^^ cannot infer type for `T` | | - | consider giving `x` the type `std::vec::Vec` with the type parameter `T` specified + | consider giving `x` the explicit type `std::vec::Vec`, where the type parameter `T` is specified | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr index 5cd898f3fefc7..6d1ef240da60c 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `(std::vec::Vec,)` +error[E0282]: type annotations needed for `(std::vec::Vec,)` --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18 | LL | let (x, ) = (vec![], ); - | ----- ^^^^^^ cannot infer type for `T` in `(std::vec::Vec,)` + | ----- ^^^^^^ cannot infer type for `T` | | - | consider giving this pattern the type `(std::vec::Vec,)` with the type parameter `T` specified + | consider giving this pattern the explicit type `(std::vec::Vec,)`, where the type parameter `T` is specified | = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 4804983b8618b..acd82a397f651 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -1,8 +1,8 @@ -error[E0282]: type annotations needed in `std::option::Option` +error[E0282]: type annotations needed for `std::option::Option` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; - | ------------ consider giving `closure0` the type `std::option::Option` with the type parameter `_` specified + | ------------ consider giving `closure0` the explicit type `std::option::Option`, where the type parameter `_` is specified ... LL | return c(); | ^^^ cannot infer type diff --git a/src/test/ui/vector-no-ann.stderr b/src/test/ui/vector-no-ann.stderr index 3ece3063cd032..28100d7c89e71 100644 --- a/src/test/ui/vector-no-ann.stderr +++ b/src/test/ui/vector-no-ann.stderr @@ -1,10 +1,10 @@ -error[E0282]: type annotations needed in `std::vec::Vec` +error[E0282]: type annotations needed for `std::vec::Vec` --> $DIR/vector-no-ann.rs:2:16 | LL | let _foo = Vec::new(); - | ---- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec` + | ---- ^^^^^^^^ cannot infer type for `T` | | - | consider giving `_foo` the type `std::vec::Vec` with the type parameter `T` specified + | consider giving `_foo` the explicit type `std::vec::Vec`, where the type parameter `T` is specified error: aborting due to previous error From e420f4410ba44b3e39f54c755f456f4f65406e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 Jun 2019 15:33:31 -0700 Subject: [PATCH 6/6] Account for cases where we can find the type arg name, but the local name is `_` --- src/librustc/infer/error_reporting/need_type_info.rs | 5 +++++ src/test/ui/issues/issue-12187-1.stderr | 2 +- src/test/ui/issues/issue-12187-2.stderr | 2 +- src/test/ui/issues/issue-7813.stderr | 2 +- .../ui/type/type-check/cannot_infer_local_or_array.stderr | 2 +- .../unboxed-closures-failed-recursive-fn-2.stderr | 2 +- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 51c69f98d978d..b3ff25a695f2f 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -152,6 +152,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // | the type parameter `E` is specified // ``` let (ty_msg, suffix) = match &local_visitor.found_ty { + Some(ty) if &ty.to_string() != "_" && name == "_" => { + let ty = ty_to_string(ty); + (format!(" for `{}`", ty), + format!("the explicit type `{}`, with the type parameters specified", ty)) + } Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => { let ty = ty_to_string(ty); (format!(" for `{}`", ty), diff --git a/src/test/ui/issues/issue-12187-1.stderr b/src/test/ui/issues/issue-12187-1.stderr index 850e61a9cc2df..3ea15439df25a 100644 --- a/src/test/ui/issues/issue-12187-1.stderr +++ b/src/test/ui/issues/issue-12187-1.stderr @@ -5,7 +5,7 @@ LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving this pattern the explicit type `&T`, where the type parameter `_` is specified + | consider giving this pattern the explicit type `&T`, with the type parameters specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12187-2.stderr b/src/test/ui/issues/issue-12187-2.stderr index 4cf2b9010a846..a5e65c65beb2f 100644 --- a/src/test/ui/issues/issue-12187-2.stderr +++ b/src/test/ui/issues/issue-12187-2.stderr @@ -5,7 +5,7 @@ LL | let &v = new(); | -^ | || | |cannot infer type - | consider giving this pattern the explicit type `&T`, where the type parameter `_` is specified + | consider giving this pattern the explicit type `&T`, with the type parameters specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr index 813b41663eebb..59be0f3be11e6 100644 --- a/src/test/ui/issues/issue-7813.stderr +++ b/src/test/ui/issues/issue-7813.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `&[_; 0]` LL | let v = &[]; | - ^^^ cannot infer type | | - | consider giving `v` the explicit type `&[_; 0]`, where the type parameter `_` is specified + | consider giving `v` the explicit type `&[_; 0]`, with the type parameters specified error: aborting due to previous error diff --git a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr index 06b757b0398f0..8edec6e0ea3fd 100644 --- a/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr +++ b/src/test/ui/type/type-check/cannot_infer_local_or_array.stderr @@ -4,7 +4,7 @@ error[E0282]: type annotations needed for `[_; 0]` LL | let x = []; | - ^^ cannot infer type | | - | consider giving `x` the explicit type `[_; 0]`, where the type parameter `_` is specified + | consider giving `x` the explicit type `[_; 0]`, with the type parameters specified error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index acd82a397f651..18af3dc640d1c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed for `std::option::Option` --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32 | LL | let mut closure0 = None; - | ------------ consider giving `closure0` the explicit type `std::option::Option`, where the type parameter `_` is specified + | ------------ consider giving `closure0` the explicit type `std::option::Option`, with the type parameters specified ... LL | return c(); | ^^^ cannot infer type