about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-02-07 22:54:20 -0500
committerGitHub <noreply@github.com>2017-02-07 22:54:20 -0500
commit19977911ce8411db27e24c93a581b856c82f5f06 (patch)
treec7220606b0297b506248fe3afa95da18fe96e306
parent4cde461bb037d816a2a004c23e6365babb0889e3 (diff)
parent3fa28cb206604fddf67a29e7cbd3a8b22da1edc2 (diff)
downloadrust-19977911ce8411db27e24c93a581b856c82f5f06.tar.gz
rust-19977911ce8411db27e24c93a581b856c82f5f06.zip
Rollup merge of #39361 - cengizIO:master, r=arielb1
Improve error message for uninferrable types #38812

Hello,

I tried to improve the error message for uninferrable types. The error code is `E0282`.

```rust

error[E0282]: type annotations needed
 --> /home/cengizIO/issue38812.rs:2:11
  |
2 |   let x = vec![];
  |       -   ^^^^^^ cannot infer type for `T`
  |       |
  |       consider giving `x` a type
  |
  = note: this error originates in a macro outside of the current crate
```

and

```rust

error[E0282]: type annotations needed
 --> /home/cengizIO/issue38812.rs:2:15
  |
2 |   let (x,) = (vec![],);
  |       ----    ^^^^^^ cannot infer type for `T`
  |       |
  |       consider giving a type to pattern
  |
  = note: this error originates in a macro outside of the current crate
```

Rust compiler now tries to find uninferred `local`s with type `_` and adds them into the error message.

I'm probably wrong on wording that I used. Please feel free to suggest better alternatives.

Thanks @nikomatsakis for mentoring 🍺

Any comments/feedback is more than welcome!

Thank you
-rw-r--r--src/librustc/traits/error_reporting.rs78
-rw-r--r--src/test/compile-fail/issue-12187-1.rs3
-rw-r--r--src/test/compile-fail/issue-12187-2.rs3
-rw-r--r--src/test/compile-fail/issue-16966.rs2
-rw-r--r--src/test/compile-fail/issue-17551.rs2
-rw-r--r--src/test/compile-fail/issue-18159.rs2
-rw-r--r--src/test/compile-fail/issue-23041.rs1
-rw-r--r--src/test/compile-fail/issue-23046.rs2
-rw-r--r--src/test/compile-fail/issue-24013.rs2
-rw-r--r--src/test/compile-fail/issue-5062.rs2
-rw-r--r--src/test/compile-fail/issue-6458-2.rs2
-rw-r--r--src/test/compile-fail/issue-6458-3.rs3
-rw-r--r--src/test/compile-fail/issue-6458.rs3
-rw-r--r--src/test/compile-fail/issue-7813.rs4
-rw-r--r--src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs2
-rw-r--r--src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs3
-rw-r--r--src/test/compile-fail/unconstrained-none.rs3
-rw-r--r--src/test/compile-fail/unconstrained-ref.rs3
-rw-r--r--src/test/compile-fail/vector-no-ann.rs4
-rw-r--r--src/test/ui/codemap_tests/issue-38812-2.rs13
-rw-r--r--src/test/ui/codemap_tests/issue-38812-2.stderr12
-rw-r--r--src/test/ui/codemap_tests/issue-38812.rs (renamed from src/test/ui/codemap_tests/repair_span_std_macros.rs)2
-rw-r--r--src/test/ui/codemap_tests/issue-38812.stderr12
-rw-r--r--src/test/ui/codemap_tests/repair_span_std_macros.stderr11
-rw-r--r--src/test/ui/missing-items/missing-type-parameter.rs2
-rw-r--r--src/test/ui/missing-items/missing-type-parameter.stderr4
26 files changed, 124 insertions, 56 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 661d47199df..024c14ce9d9 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -39,6 +39,8 @@ use util::nodemap::{FxHashMap, FxHashSet};
 use std::cmp;
 use std::fmt;
 use syntax::ast;
+use hir::{intravisit, Local, Pat};
+use hir::intravisit::{Visitor, NestedVisitorMap};
 use syntax_pos::{DUMMY_SP, Span};
 use errors::DiagnosticBuilder;
 
@@ -60,6 +62,30 @@ impl<'a, 'gcx, 'tcx> TraitErrorKey<'tcx> {
     }
 }
 
+struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+    target_ty: &'a Ty<'tcx>,
+    found_pattern: Option<&'a Pat>,
+}
+
+impl<'a, 'gcx, 'tcx> Visitor<'a> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'a> {
+        NestedVisitorMap::None
+    }
+
+    fn visit_local(&mut self, local: &'a Local) {
+        if let Some(&ty) = self.infcx.tables.borrow().node_types.get(&local.id) {
+            let ty = self.infcx.resolve_type_vars_if_possible(&ty);
+            let is_match = ty.walk().any(|t| t == *self.target_ty);
+
+            if is_match && self.found_pattern.is_none() {
+                self.found_pattern = Some(&*local.pat);
+            }
+        }
+        intravisit::walk_local(self, local);
+    }
+}
+
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     pub fn report_fulfillment_errors(&self, errors: &Vec<FulfillmentError<'tcx>>) {
         for error in errors {
@@ -775,7 +801,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             self.tcx.lang_items.sized_trait()
                             .map_or(false, |sized_id| sized_id == trait_ref.def_id())
                         {
-                            self.need_type_info(obligation.cause.span, self_ty);
+                            self.need_type_info(obligation, self_ty);
                         } else {
                             let mut err = struct_span_err!(self.tcx.sess,
                                                            obligation.cause.span, E0283,
@@ -793,7 +819,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 // Same hacky approach as above to avoid deluging user
                 // with error messages.
                 if !ty.references_error() && !self.tcx.sess.has_errors() {
-                    self.need_type_info(obligation.cause.span, ty);
+                    self.need_type_info(obligation, ty);
                 }
             }
 
@@ -857,27 +883,53 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         })
     }
 
-
-    fn need_type_info(&self, span: Span, ty: Ty<'tcx>) {
-        let ty = self.resolve_type_vars_if_possible(&ty);
-        let name = if let ty::TyInfer(ty::TyVar(ty_vid)) = ty.sty {
+    fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
+        if let ty::TyInfer(ty::TyVar(ty_vid)) = (*ty).sty {
             let ty_vars = self.type_variables.borrow();
             if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
-                    *ty_vars.var_origin(ty_vid)
-            {
+                *ty_vars.var_origin(ty_vid) {
                 name.to_string()
             } else {
                 ty.to_string()
             }
         } else {
             ty.to_string()
+        }
+    }
+
+    fn need_type_info(&self, obligation: &PredicateObligation<'tcx>, ty: Ty<'tcx>) {
+        let ty = self.resolve_type_vars_if_possible(&ty);
+        let name = self.extract_type_name(&ty);
+        let ref cause = obligation.cause;
+
+        let mut err = struct_span_err!(self.tcx.sess,
+                                       cause.span,
+                                       E0282,
+                                       "type annotations needed");
+
+        err.span_label(cause.span, &format!("cannot infer type for `{}`", name));
+
+        let expr = self.tcx.hir.expect_expr(cause.body_id);
+
+        let mut local_visitor = FindLocalByTypeVisitor {
+            infcx: &self,
+            target_ty: &ty,
+            found_pattern: None,
         };
 
-        let mut err = struct_span_err!(self.tcx.sess, span, E0282,
-                                       "unable to infer enough type information about `{}`",
-                                       name);
-        err.note("type annotations or generic parameter binding required");
-        err.span_label(span, &format!("cannot infer type for `{}`", name));
+        local_visitor.visit_expr(expr);
+
+        if let Some(pattern) = local_visitor.found_pattern {
+            let pattern_span = pattern.span;
+            if let Some(simple_name) = pattern.simple_name() {
+                err.span_label(pattern_span,
+                               &format!("consider giving `{}` a type",
+                                        simple_name));
+            } else {
+                err.span_label(pattern_span, &format!("consider giving a type to pattern"));
+            }
+        }
+
         err.emit();
     }
 
diff --git a/src/test/compile-fail/issue-12187-1.rs b/src/test/compile-fail/issue-12187-1.rs
index 001e4b51beb..346fae11070 100644
--- a/src/test/compile-fail/issue-12187-1.rs
+++ b/src/test/compile-fail/issue-12187-1.rs
@@ -14,7 +14,6 @@ fn new<T>() -> &'static T {
 
 fn main() {
     let &v = new();
-    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     //~| NOTE cannot infer type for `_`
-    //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/compile-fail/issue-12187-2.rs b/src/test/compile-fail/issue-12187-2.rs
index 7cbee402b36..848174d6fe1 100644
--- a/src/test/compile-fail/issue-12187-2.rs
+++ b/src/test/compile-fail/issue-12187-2.rs
@@ -14,7 +14,6 @@ fn new<'r, T>() -> &'r T {
 
 fn main() {
     let &v = new();
-    //~^ ERROR unable to infer enough type information about `_` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     //~| NOTE cannot infer type for `_`
-    //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/compile-fail/issue-16966.rs b/src/test/compile-fail/issue-16966.rs
index 508442fcb94..ecf81c8af17 100644
--- a/src/test/compile-fail/issue-16966.rs
+++ b/src/test/compile-fail/issue-16966.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:type annotations or generic parameter binding required
+// error-pattern:type annotations needed
 fn main() {
     panic!(
         std::default::Default::default()
diff --git a/src/test/compile-fail/issue-17551.rs b/src/test/compile-fail/issue-17551.rs
index 5e69553d3a4..b55863f0dda 100644
--- a/src/test/compile-fail/issue-17551.rs
+++ b/src/test/compile-fail/issue-17551.rs
@@ -13,6 +13,6 @@ use std::marker;
 struct B<T>(marker::PhantomData<T>);
 
 fn main() {
-    let foo = B(marker::PhantomData); //~ ERROR unable to infer enough type information
+    let foo = B(marker::PhantomData); //~ ERROR type annotations needed
     let closure = || foo;
 }
diff --git a/src/test/compile-fail/issue-18159.rs b/src/test/compile-fail/issue-18159.rs
index e46bcf46cc3..8991eded3d6 100644
--- a/src/test/compile-fail/issue-18159.rs
+++ b/src/test/compile-fail/issue-18159.rs
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn main() {
-    let x; //~ ERROR unable to infer enough type information
+    let x; //~ ERROR type annotations needed
 }
diff --git a/src/test/compile-fail/issue-23041.rs b/src/test/compile-fail/issue-23041.rs
index 1be082ba9bb..4dfad4ee3c3 100644
--- a/src/test/compile-fail/issue-23041.rs
+++ b/src/test/compile-fail/issue-23041.rs
@@ -15,5 +15,4 @@ fn main()
     let b:Box<Any> = Box::new(bar as fn(_)->_);
     b.downcast_ref::<fn(_)->_>(); //~ ERROR E0282
                                   //~| NOTE cannot infer type for `_`
-                                  //~| NOTE type annotations or generic parameter binding required
 }
diff --git a/src/test/compile-fail/issue-23046.rs b/src/test/compile-fail/issue-23046.rs
index c274665530f..28109747b75 100644
--- a/src/test/compile-fail/issue-23046.rs
+++ b/src/test/compile-fail/issue-23046.rs
@@ -25,6 +25,6 @@ pub fn let_<'var, VAR, F: for<'v: 'var> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>>
 
 fn main() {
     let ex = |x| {
-        let_(add(x,x), |y| { //~ ERROR unable to infer enough type information about `VAR`
+        let_(add(x,x), |y| { //~ ERROR type annotations needed
             let_(add(x, x), |x|x)})};
 }
diff --git a/src/test/compile-fail/issue-24013.rs b/src/test/compile-fail/issue-24013.rs
index df857a2e6eb..a7232781f6f 100644
--- a/src/test/compile-fail/issue-24013.rs
+++ b/src/test/compile-fail/issue-24013.rs
@@ -13,5 +13,5 @@ fn main() {
     let a = 1;
     let b = 2;
     unsafe {swap::<&mut _>(transmute(&a), transmute(&b))};
-    //~^ ERROR unable to infer enough type information about `_`
+    //~^ ERROR type annotations needed
 }
diff --git a/src/test/compile-fail/issue-5062.rs b/src/test/compile-fail/issue-5062.rs
index cf78d6d8c0a..ebfa4975d4d 100644
--- a/src/test/compile-fail/issue-5062.rs
+++ b/src/test/compile-fail/issue-5062.rs
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 fn main() { format!("{:?}", None); }
-    //~^ ERROR unable to infer enough type information about `T` [E0282]
+    //~^ ERROR type annotations needed [E0282]
diff --git a/src/test/compile-fail/issue-6458-2.rs b/src/test/compile-fail/issue-6458-2.rs
index 3816896d43d..87cf2b3f740 100644
--- a/src/test/compile-fail/issue-6458-2.rs
+++ b/src/test/compile-fail/issue-6458-2.rs
@@ -11,5 +11,5 @@
 fn main() {
     // Unconstrained type:
     format!("{:?}", None);
-    //~^ ERROR unable to infer enough type information about `T` [E0282]
+    //~^ ERROR type annotations needed [E0282]
 }
diff --git a/src/test/compile-fail/issue-6458-3.rs b/src/test/compile-fail/issue-6458-3.rs
index 8029522f5d3..1503da2baa7 100644
--- a/src/test/compile-fail/issue-6458-3.rs
+++ b/src/test/compile-fail/issue-6458-3.rs
@@ -12,7 +12,6 @@ use std::mem;
 
 fn main() {
     mem::transmute(0);
-    //~^ ERROR unable to infer enough type information about `U` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     //~| NOTE cannot infer type for `U`
-    //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/compile-fail/issue-6458.rs b/src/test/compile-fail/issue-6458.rs
index f8354ddbf12..db4d4e76c11 100644
--- a/src/test/compile-fail/issue-6458.rs
+++ b/src/test/compile-fail/issue-6458.rs
@@ -17,9 +17,8 @@ pub fn foo<State>(_: TypeWithState<State>) {}
 
 pub fn bar() {
    foo(TypeWithState(marker::PhantomData));
-   //~^ ERROR unable to infer enough type information about `State` [E0282]
+   //~^ ERROR type annotations needed [E0282]
    //~| NOTE cannot infer type for `State`
-   //~| NOTE type annotations or generic parameter binding
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-7813.rs b/src/test/compile-fail/issue-7813.rs
index e37a8816423..fdd89058fd3 100644
--- a/src/test/compile-fail/issue-7813.rs
+++ b/src/test/compile-fail/issue-7813.rs
@@ -10,7 +10,7 @@
 
 fn main() {
     let v = &[];
-    let it = v.iter(); //~ ERROR unable to infer enough type information about `T` [E0282]
+    let it = v.iter(); //~ ERROR type annotations needed [E0282]
                        //~| NOTE cannot infer type for `T`
-                       //~| NOTE type annotations or generic parameter binding
+                       //~| NOTE consider giving `it` a type
 }
diff --git a/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs
index 1cf41f95a2d..9acf5a52166 100644
--- a/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs
+++ b/src/test/compile-fail/method-ambig-one-trait-unknown-int-type.rs
@@ -32,7 +32,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 unable to infer enough type information about `T` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     x.foo();
 }
 
diff --git a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs
index ed2ffa995e5..2e115431c92 100644
--- a/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs
+++ b/src/test/compile-fail/traits-multidispatch-convert-ambig-dest.rs
@@ -34,9 +34,8 @@ where T : Convert<U>
 
 fn a() {
     test(22, std::default::Default::default());
-    //~^ ERROR unable to infer enough type information about `U` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     //~| NOTE cannot infer type for `U`
-    //~| NOTE type annotations or generic parameter binding
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/unconstrained-none.rs b/src/test/compile-fail/unconstrained-none.rs
index 88080bc70ca..52ca91e62f8 100644
--- a/src/test/compile-fail/unconstrained-none.rs
+++ b/src/test/compile-fail/unconstrained-none.rs
@@ -11,7 +11,6 @@
 // Issue #5062
 
 fn main() {
-    None; //~ ERROR unable to infer enough type information about `T` [E0282]
+    None; //~ ERROR type annotations needed [E0282]
           //~| NOTE cannot infer type for `T`
-          //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/compile-fail/unconstrained-ref.rs b/src/test/compile-fail/unconstrained-ref.rs
index 12278549215..6aaed789716 100644
--- a/src/test/compile-fail/unconstrained-ref.rs
+++ b/src/test/compile-fail/unconstrained-ref.rs
@@ -13,7 +13,6 @@ struct S<'a, T:'a> {
 }
 
 fn main() {
-    S { o: &None }; //~ ERROR unable to infer enough type information about `T` [E0282]
+    S { o: &None }; //~ ERROR type annotations needed [E0282]
                     //~| NOTE cannot infer type for `T`
-                    //~| NOTE type annotations or generic parameter binding
 }
diff --git a/src/test/compile-fail/vector-no-ann.rs b/src/test/compile-fail/vector-no-ann.rs
index d559caf77a1..de229ded463 100644
--- a/src/test/compile-fail/vector-no-ann.rs
+++ b/src/test/compile-fail/vector-no-ann.rs
@@ -11,7 +11,7 @@
 
 fn main() {
     let _foo = Vec::new();
-    //~^ ERROR unable to infer enough type information about `T` [E0282]
+    //~^ ERROR type annotations needed [E0282]
     //~| NOTE cannot infer type for `T`
-    //~| NOTE type annotations or generic parameter binding
+    //~| NOTE consider giving `_foo` a type
 }
diff --git a/src/test/ui/codemap_tests/issue-38812-2.rs b/src/test/ui/codemap_tests/issue-38812-2.rs
new file mode 100644
index 00000000000..c476657d207
--- /dev/null
+++ b/src/test/ui/codemap_tests/issue-38812-2.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let (x,) = (vec![],);
+}
diff --git a/src/test/ui/codemap_tests/issue-38812-2.stderr b/src/test/ui/codemap_tests/issue-38812-2.stderr
new file mode 100644
index 00000000000..156a6bdee99
--- /dev/null
+++ b/src/test/ui/codemap_tests/issue-38812-2.stderr
@@ -0,0 +1,12 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-38812-2.rs:12:17
+   |
+12 |     let (x,) = (vec![],);
+   |         ----    ^^^^^^ cannot infer type for `T`
+   |         |
+   |         consider giving a type to pattern
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/codemap_tests/repair_span_std_macros.rs b/src/test/ui/codemap_tests/issue-38812.rs
index 3abc91d4f5f..a9943f75336 100644
--- a/src/test/ui/codemap_tests/repair_span_std_macros.rs
+++ b/src/test/ui/codemap_tests/issue-38812.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
diff --git a/src/test/ui/codemap_tests/issue-38812.stderr b/src/test/ui/codemap_tests/issue-38812.stderr
new file mode 100644
index 00000000000..6365e761453
--- /dev/null
+++ b/src/test/ui/codemap_tests/issue-38812.stderr
@@ -0,0 +1,12 @@
+error[E0282]: type annotations needed
+  --> $DIR/issue-38812.rs:12:13
+   |
+12 |     let x = vec![];
+   |         -   ^^^^^^ cannot infer type for `T`
+   |         |
+   |         consider giving `x` a type
+   |
+   = note: this error originates in a macro outside of the current crate
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/codemap_tests/repair_span_std_macros.stderr b/src/test/ui/codemap_tests/repair_span_std_macros.stderr
deleted file mode 100644
index 7e0d778a3b2..00000000000
--- a/src/test/ui/codemap_tests/repair_span_std_macros.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0282]: unable to infer enough type information about `T`
-  --> $DIR/repair_span_std_macros.rs:12:13
-   |
-12 |     let x = vec![];
-   |             ^^^^^^ cannot infer type for `T`
-   |
-   = note: type annotations or generic parameter binding required
-   = note: this error originates in a macro outside of the current crate
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/missing-items/missing-type-parameter.rs b/src/test/ui/missing-items/missing-type-parameter.rs
index 3671abd6624..79368587062 100644
--- a/src/test/ui/missing-items/missing-type-parameter.rs
+++ b/src/test/ui/missing-items/missing-type-parameter.rs
@@ -1,4 +1,4 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
diff --git a/src/test/ui/missing-items/missing-type-parameter.stderr b/src/test/ui/missing-items/missing-type-parameter.stderr
index 2d007af4980..a16ae5538bf 100644
--- a/src/test/ui/missing-items/missing-type-parameter.stderr
+++ b/src/test/ui/missing-items/missing-type-parameter.stderr
@@ -1,10 +1,8 @@
-error[E0282]: unable to infer enough type information about `X`
+error[E0282]: type annotations needed
   --> $DIR/missing-type-parameter.rs:14:5
    |
 14 |     foo();
    |     ^^^ cannot infer type for `X`
-   |
-   = note: type annotations or generic parameter binding required
 
 error: aborting due to previous error