about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs101
-rw-r--r--src/librustc/ty/print/pretty.rs23
-rw-r--r--src/test/ui/issues/issue-12187-1.rs2
-rw-r--r--src/test/ui/issues/issue-12187-1.stderr4
-rw-r--r--src/test/ui/issues/issue-12187-2.rs2
-rw-r--r--src/test/ui/issues/issue-12187-2.stderr4
-rw-r--r--src/test/ui/issues/issue-17551.stderr4
-rw-r--r--src/test/ui/issues/issue-20261.stderr2
-rw-r--r--src/test/ui/issues/issue-23046.stderr4
-rw-r--r--src/test/ui/issues/issue-25368.stderr4
-rw-r--r--src/test/ui/issues/issue-7813.stderr4
-rw-r--r--src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs2
-rw-r--r--src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr4
-rw-r--r--src/test/ui/span/issue-42234-unknown-receiver-type.stderr4
-rw-r--r--src/test/ui/type/type-check/cannot_infer_local_or_array.stderr4
-rw-r--r--src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr4
-rw-r--r--src/test/ui/type/type-check/cannot_infer_local_or_vec_in_tuples.stderr4
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr4
-rw-r--r--src/test/ui/vector-no-ann.rs2
-rw-r--r--src/test/ui/vector-no-ann.stderr4
20 files changed, 136 insertions, 50 deletions
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 972ffbe1820..b3ff25a695f 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<Ty<'tcx>>,
 }
 
 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<Ty<'tcx>> {
         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);
@@ -98,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,
@@ -106,6 +115,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             hir_map: &self.tcx.hir(),
             found_local_pattern: None,
             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 {
@@ -113,6 +138,38 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             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<i32, E>`":
+        // ```
+        // error[E0282]: type annotations needed for `std::result::Result<i32, E>`
+        //  --> file.rs:L:CC
+        //   |
+        // L |     let b = Ok(4);
+        //   |         -   ^^ cannot infer type for `E` in `std::result::Result<i32, E>`
+        //   |         |
+        //   |         consider giving `b` the explicit type `std::result::Result<i32, E>`, where
+        //   |         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),
+                 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))];
+
         if let Some(pattern) = local_visitor.found_arg_pattern {
             err_span = pattern.span;
             // We don't want to show the default label for closures.
@@ -128,16 +185,21 @@ 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, "consider giving this closure parameter 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))),
+                    None => labels.push((
+                        pattern.span,
+                        format!("consider giving `{}` {}", simple_ident, suffix),
+                    )),
                     Some(CompilerDesugaringKind::ForLoop) => labels.push((
                         pattern.span,
                         "the element type for this iterator is not specified".to_owned(),
@@ -145,14 +207,17 @@ 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)));
             }
-        }
+        };
 
-        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/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index a8a6bca4fd4..513ffd69cca 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<String> {
+        None
+    }
+
     fn pretty_print_dyn_existential(
         mut self,
         predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
@@ -931,6 +945,8 @@ pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> {
     binder_depth: usize,
 
     pub region_highlight_mode: RegionHighlightMode,
+
+    pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
 }
 
 impl<F> Deref for FmtPrinter<'a, 'gcx, 'tcx, F> {
@@ -957,6 +973,7 @@ impl<F> FmtPrinter<'a, 'gcx, 'tcx, F> {
             region_index: 0,
             binder_depth: 0,
             region_highlight_mode: RegionHighlightMode::default(),
+            name_resolver: None,
         }))
     }
 }
@@ -1206,6 +1223,10 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
 }
 
 impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
+    fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
+        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.rs b/src/test/ui/issues/issue-12187-1.rs
index 37ff468e032..86128ed94bd 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<T>() -> &'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 f8df4f82e7e..3ea15439df2 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
+error[E0282]: type annotations needed for `&T`
   --> $DIR/issue-12187-1.rs:6:10
    |
 LL |     let &v = new();
    |         -^
    |         ||
    |         |cannot infer type
-   |         consider giving the pattern a type
+   |         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.rs b/src/test/ui/issues/issue-12187-2.rs
index a1cdb849779..080a6206be7 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 c40ae0461ec..a5e65c65beb 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
+error[E0282]: type annotations needed for `&T`
   --> $DIR/issue-12187-2.rs:6:10
    |
 LL |     let &v = new();
    |         -^
    |         ||
    |         |cannot infer type
-   |         consider giving the pattern a type
+   |         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-17551.stderr b/src/test/ui/issues/issue-17551.stderr
index 40e7727752b..ce16f0f58ea 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<T>`
   --> $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 explicit type `B<T>`, 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 5665f5893f4..c6c3f32dfe7 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 aab90a9d440..12b2eb48e7e 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<'_, VAR>`
   --> $DIR/issue-23046.rs:17:15
    |
 LL |     let ex = |x| {
-   |               ^ consider giving this closure parameter a type
+   |               ^ 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 3ad6a2569be..0b890b573da 100644
--- a/src/test/ui/issues/issue-25368.stderr
+++ b/src/test/ui/issues/issue-25368.stderr
@@ -1,8 +1,8 @@
-error[E0282]: type annotations needed
+error[E0282]: type annotations needed for `(std::sync::mpsc::Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`
   --> $DIR/issue-25368.rs:11:17
    |
 LL |     let (tx, rx) = channel();
-   |         -------- consider giving the pattern a type
+   |         -------- consider giving this pattern the explicit type `(std::sync::mpsc::Sender<Foo<T>>, std::sync::mpsc::Receiver<Foo<T>>)`, where the type parameter `T` is specified
 ...
 LL |         tx.send(Foo{ foo: PhantomData });
    |                 ^^^ cannot infer type for `T`
diff --git a/src/test/ui/issues/issue-7813.stderr b/src/test/ui/issues/issue-7813.stderr
index 45b9c915885..59be0f3be11 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 explicit type `&[_; 0]`, with the type parameters 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 590e98dc353..e33f23c64db 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<isize> {
 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 063a4865b19..b1bd749bef4 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<T>`
   --> $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 explicit type `std::vec::Vec<T>`, 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 8923de5705b..04c2870d832 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 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`
    |
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 17be67c6c3a..8edec6e0ea3 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 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_vec.stderr b/src/test/ui/type/type-check/cannot_infer_local_or_vec.stderr
index 8215947d49c..6524bf5dd2b 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<T>`
   --> $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 explicit type `std::vec::Vec<T>`, 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 1065d49c26b..6d1ef240da6 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
+error[E0282]: type annotations needed for `(std::vec::Vec<T>,)`
   --> $DIR/cannot_infer_local_or_vec_in_tuples.rs:2:18
    |
 LL |     let (x, ) = (vec![], );
    |         -----    ^^^^^^ cannot infer type for `T`
    |         |
-   |         consider giving the pattern a type
+   |         consider giving this pattern the explicit type `(std::vec::Vec<T>,)`, 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 bd58e241f0c..18af3dc640d 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<T>`
   --> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32
    |
 LL |     let mut closure0 = None;
-   |         ------------ consider giving `closure0` a type
+   |         ------------ consider giving `closure0` the explicit type `std::option::Option<T>`, with the type parameters 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 200364a5d93..1f11d9c8dff 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 01b569f97f9..28100d7c89e 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<T>`
   --> $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 explicit type `std::vec::Vec<T>`, where the type parameter `T` is specified
 
 error: aborting due to previous error