about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/lowering.rs4
-rw-r--r--src/librustc/infer/opaque_types/mod.rs13
-rw-r--r--src/librustc/traits/error_reporting.rs71
-rw-r--r--src/librustc/traits/mod.rs13
-rw-r--r--src/librustc/traits/select.rs2
-rw-r--r--src/librustc/traits/structural_impls.rs3
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc_typeck/check/coercion.rs2
-rw-r--r--src/librustc_typeck/check/expr.rs12
-rw-r--r--src/librustc_typeck/check/mod.rs82
-rw-r--r--src/librustc_typeck/check/wfcheck.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding.rs4
-rw-r--r--src/test/ui/associated-types/associated-types-overridden-binding.stderr13
-rw-r--r--src/test/ui/associated-types/associated-types-unconstrained.rs2
-rw-r--r--src/test/ui/associated-types/associated-types-unconstrained.stderr2
-rw-r--r--src/test/ui/error-codes/E0283.stderr2
-rw-r--r--src/test/ui/error-codes/E0401.rs2
-rw-r--r--src/test/ui/error-codes/E0401.stderr11
-rw-r--r--src/test/ui/error-codes/E0661.rs2
-rw-r--r--src/test/ui/error-codes/E0661.stderr9
-rw-r--r--src/test/ui/impl-trait/where-allowed.rs6
-rw-r--r--src/test/ui/impl-trait/where-allowed.stderr100
-rw-r--r--src/test/ui/issues/issue-12028.rs2
-rw-r--r--src/test/ui/issues/issue-12028.stderr2
-rw-r--r--src/test/ui/issues/issue-21974.rs2
-rw-r--r--src/test/ui/issues/issue-21974.stderr2
-rw-r--r--src/test/ui/issues/issue-24424.rs2
-rw-r--r--src/test/ui/issues/issue-24424.stderr2
-rw-r--r--src/test/ui/issues/issue-29147.stderr2
-rw-r--r--src/test/ui/issues/issue-54954.rs4
-rw-r--r--src/test/ui/issues/issue-54954.stderr25
-rw-r--r--src/test/ui/methods/method-ambig-one-trait-unknown-int-type.rs2
-rw-r--r--src/test/ui/parser/raw/raw-literal-self.rs2
-rw-r--r--src/test/ui/parser/raw/raw-literal-self.stderr2
-rw-r--r--src/test/ui/parser/raw/raw-literal-underscore.rs2
-rw-r--r--src/test/ui/parser/raw/raw-literal-underscore.stderr2
-rw-r--r--src/test/ui/pattern/rest-pat-semantic-disallowed.rs1
-rw-r--r--src/test/ui/pattern/rest-pat-semantic-disallowed.stderr37
-rw-r--r--src/test/ui/question-mark-type-infer.rs2
-rw-r--r--src/test/ui/question-mark-type-infer.stderr2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr4
-rw-r--r--src/test/ui/traits/trait-static-method-generic-inference.rs2
-rw-r--r--src/test/ui/traits/trait-static-method-generic-inference.stderr2
-rw-r--r--src/test/ui/type/type-annotation-needed.rs2
-rw-r--r--src/test/ui/type/type-annotation-needed.stderr2
-rw-r--r--src/test/ui/type/type-check/issue-40294.rs2
-rw-r--r--src/test/ui/type/type-check/issue-40294.stderr2
-rw-r--r--src/test/ui/type/type-path-err-node-types.rs2
-rw-r--r--src/test/ui/type/type-path-err-node-types.stderr12
50 files changed, 297 insertions, 193 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f6b872623d7..1e05018007a 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2184,9 +2184,7 @@ impl<'a> LoweringContext<'a> {
             match decl.output {
                 FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
                     Some((def_id, _)) if impl_trait_return_allow => {
-                        hir::Return(self.lower_ty(ty,
-                            ImplTraitContext::OpaqueTy(Some(def_id))
-                        ))
+                        hir::Return(self.lower_ty(ty, ImplTraitContext::OpaqueTy(Some(def_id))))
                     }
                     _ => {
                         hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index c9fd3392a96..129cfc8bcb2 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -988,7 +988,9 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
         value.fold_with(&mut BottomUpFolder {
             tcx,
             ty_op: |ty| {
-                if let ty::Opaque(def_id, substs) = ty.sty {
+                if ty.references_error() {
+                    return tcx.types.err;
+                } else if let ty::Opaque(def_id, substs) = ty.sty {
                     // Check that this is `impl Trait` type is
                     // declared by `parent_def_id` -- i.e., one whose
                     // value we are inferring.  At present, this is
@@ -1155,6 +1157,15 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
         );
         debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
 
+        for predicate in &bounds.predicates {
+            if let ty::Predicate::Projection(projection) = &predicate {
+                if projection.skip_binder().ty.references_error() {
+                    // No point on adding these obligations since there's a type error involved.
+                    return ty_var;
+                }
+            }
+        }
+
         self.obligations.reserve(bounds.predicates.len());
         for predicate in bounds.predicates {
             // Change the predicate to refer to the type variable,
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index aff866fa76d..08fea757399 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1432,8 +1432,11 @@ impl<'tcx> TyCtxt<'tcx> {
 }
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
-                              body_id: Option<hir::BodyId>) {
+    fn maybe_report_ambiguity(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        body_id: Option<hir::BodyId>,
+    ) {
         // Unable to successfully determine, probably means
         // insufficient type information, but could mean
         // ambiguous impls. The latter *ought* to be a
@@ -1442,9 +1445,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let predicate = self.resolve_vars_if_possible(&obligation.predicate);
         let span = obligation.cause.span;
 
-        debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
-               predicate,
-               obligation);
+        debug!(
+            "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})",
+            predicate,
+            obligation,
+            body_id,
+            obligation.cause.code,
+        );
 
         // Ambiguity errors are often caused as fallout from earlier
         // errors. So just ignore them if this infcx is tainted.
@@ -1456,6 +1463,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             ty::Predicate::Trait(ref data) => {
                 let trait_ref = data.to_poly_trait_ref();
                 let self_ty = trait_ref.self_ty();
+                debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.sty, trait_ref);
+
                 if predicate.references_error() {
                     return;
                 }
@@ -1480,24 +1489,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 // be ignoring the fact that we don't KNOW the type works
                 // out. Though even that would probably be harmless, given that
                 // we're only talking about builtin traits, which are known to be
-                // inhabited. But in any case I just threw in this check for
-                // has_errors() to be sure that compilation isn't happening
-                // anyway. In that case, why inundate the user.
-                if !self.tcx.sess.has_errors() {
-                    if
-                        self.tcx.lang_items().sized_trait()
-                        .map_or(false, |sized_id| sized_id == trait_ref.def_id())
-                    {
-                        self.need_type_info_err(body_id, span, self_ty).emit();
-                    } else {
-                        let mut err = struct_span_err!(self.tcx.sess,
-                                                       span, E0283,
-                                                       "type annotations required: \
-                                                        cannot resolve `{}`",
-                                                       predicate);
-                        self.note_obligation_cause(&mut err, obligation);
-                        err.emit();
-                    }
+                // inhabited. We used to check for `self.tcx.sess.has_errors()` to
+                // avoid inundating the user with unnecessary errors, but we now
+                // check upstream for type errors and dont add the obligations to
+                // begin with in those cases.
+                if
+                    self.tcx.lang_items().sized_trait()
+                    .map_or(false, |sized_id| sized_id == trait_ref.def_id())
+                {
+                    self.need_type_info_err(body_id, span, self_ty).emit();
+                } else {
+                    let mut err = struct_span_err!(
+                        self.tcx.sess,
+                        span,
+                        E0283,
+                        "type annotations needed: cannot resolve `{}`",
+                        predicate,
+                    );
+                    self.note_obligation_cause(&mut err, obligation);
+                    err.emit();
                 }
             }
 
@@ -1524,11 +1534,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
             _ => {
                 if !self.tcx.sess.has_errors() {
-                    let mut err = struct_span_err!(self.tcx.sess,
-                                                   obligation.cause.span, E0284,
-                                                   "type annotations required: \
-                                                    cannot resolve `{}`",
-                                                   predicate);
+                    let mut err = struct_span_err!(
+                        self.tcx.sess,
+                        obligation.cause.span,
+                        E0284,
+                        "type annotations needed: cannot resolve `{}`",
+                        predicate,
+                    );
                     self.note_obligation_cause(&mut err, obligation);
                     err.emit();
                 }
@@ -1766,7 +1778,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                               but not on the corresponding trait method",
                              predicate));
             }
-            ObligationCauseCode::ReturnType(_) |
+            ObligationCauseCode::ReturnType |
+            ObligationCauseCode::ReturnValue(_) |
             ObligationCauseCode::BlockTailExpression(_) => (),
             ObligationCauseCode::TrivialBound => {
                 err.help("see issue #48214");
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 1123422ad60..accbbe3643e 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -212,14 +212,14 @@ pub enum ObligationCauseCode<'tcx> {
     /// Constant expressions must be sized.
     ConstSized,
 
-    /// static items must have `Sync` type
+    /// Static items must have `Sync` type
     SharedStatic,
 
     BuiltinDerivedObligation(DerivedObligationCause<'tcx>),
 
     ImplDerivedObligation(DerivedObligationCause<'tcx>),
 
-    /// error derived when matching traits/impls; see ObligationCause for more details
+    /// Error derived when matching traits/impls; see ObligationCause for more details
     CompareImplMethodObligation {
         item_name: ast::Name,
         impl_item_def_id: DefId,
@@ -248,17 +248,20 @@ pub enum ObligationCauseCode<'tcx> {
     /// `start` has wrong type
     StartFunctionType,
 
-    /// intrinsic has wrong type
+    /// Intrinsic has wrong type
     IntrinsicType,
 
-    /// method receiver
+    /// Method receiver
     MethodReceiver,
 
     /// `return` with no expression
     ReturnNoExpression,
 
     /// `return` with an expression
-    ReturnType(hir::HirId),
+    ReturnValue(hir::HirId),
+
+    /// Return type of this function
+    ReturnType,
 
     /// Block implicit return
     BlockTailExpression(hir::HirId),
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index a54bc05f169..386a5677f5f 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -214,7 +214,7 @@ pub struct SelectionCache<'tcx> {
 /// of type variables - it just means the obligation isn't sufficiently
 /// elaborated. In that case we report an ambiguity, and the caller can
 /// try again after more type information has been gathered or report a
-/// "type annotations required" error.
+/// "type annotations needed" error.
 ///
 /// However, with type parameters, this can be a real problem - type
 /// parameters don't unify with regular types, but they *can* unify
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 68c97226f89..c0d8230999d 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -485,7 +485,8 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::TupleInitializerSized => Some(super::TupleInitializerSized),
             super::StructInitializerSized => Some(super::StructInitializerSized),
             super::VariableType(id) => Some(super::VariableType(id)),
-            super::ReturnType(id) => Some(super::ReturnType(id)),
+            super::ReturnValue(id) => Some(super::ReturnValue(id)),
+            super::ReturnType => Some(super::ReturnType),
             super::SizedArgumentType => Some(super::SizedArgumentType),
             super::SizedReturnType => Some(super::SizedReturnType),
             super::SizedYieldType => Some(super::SizedYieldType),
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 89afbbaf4d4..ef8bdfb583e 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -438,7 +438,7 @@ bitflags! {
 
         /// `true` if there are "names" of types and regions and so forth
         /// that are local to a particular fn
-        const HAS_FREE_LOCAL_NAMES    = 1 << 9;
+        const HAS_FREE_LOCAL_NAMES = 1 << 9;
 
         /// Present if the type belongs in a local type context.
         /// Only set for Infer other than Fresh.
@@ -446,11 +446,11 @@ bitflags! {
 
         /// Does this have any `ReLateBound` regions? Used to check
         /// if a global bound is safe to evaluate.
-        const HAS_RE_LATE_BOUND = 1 << 11;
+        const HAS_RE_LATE_BOUND  = 1 << 11;
 
         const HAS_TY_PLACEHOLDER = 1 << 12;
 
-        const HAS_CT_INFER = 1 << 13;
+        const HAS_CT_INFER       = 1 << 13;
         const HAS_CT_PLACEHOLDER = 1 << 14;
 
         const NEEDS_SUBST        = TypeFlags::HAS_PARAMS.bits |
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index d98e1f3e128..dc536329251 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -1253,7 +1253,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                             expression.map(|expr| (expr, blk_id)),
                         );
                     }
-                    ObligationCauseCode::ReturnType(id) => {
+                    ObligationCauseCode::ReturnValue(id) => {
                         db = self.report_return_mismatched_types(
                             cause, expected, found, err, fcx, id, None);
                     }
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index e34a2c6f61c..6b694bfc8da 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -664,12 +664,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let ret_ty = ret_coercion.borrow().expected_ty();
         let return_expr_ty = self.check_expr_with_hint(return_expr, ret_ty.clone());
-        ret_coercion.borrow_mut()
-                    .coerce(self,
-                            &self.cause(return_expr.span,
-                                        ObligationCauseCode::ReturnType(return_expr.hir_id)),
-                            return_expr,
-                            return_expr_ty);
+        ret_coercion.borrow_mut().coerce(
+            self,
+            &self.cause(return_expr.span, ObligationCauseCode::ReturnValue(return_expr.hir_id)),
+            return_expr,
+            return_expr_ty,
+        );
     }
 
     /// Type check assignment expression `expr` of form `lhs = rhs`.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6c8c5ae5123..02f4f2a3744 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2698,30 +2698,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             traits::ObligationCause::new(span, self.body_id, code));
     }
 
-    pub fn require_type_is_sized(&self,
-                                 ty: Ty<'tcx>,
-                                 span: Span,
-                                 code: traits::ObligationCauseCode<'tcx>)
-    {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
-        self.require_type_meets(ty, span, code, lang_item);
+    pub fn require_type_is_sized(
+        &self,
+        ty: Ty<'tcx>,
+        span: Span,
+        code: traits::ObligationCauseCode<'tcx>,
+    ) {
+        if !ty.references_error() {
+            let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
+            self.require_type_meets(ty, span, code, lang_item);
+        }
     }
 
-    pub fn require_type_is_sized_deferred(&self,
-                                          ty: Ty<'tcx>,
-                                          span: Span,
-                                          code: traits::ObligationCauseCode<'tcx>)
-    {
-        self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
+    pub fn require_type_is_sized_deferred(
+        &self,
+        ty: Ty<'tcx>,
+        span: Span,
+        code: traits::ObligationCauseCode<'tcx>,
+    ) {
+        if !ty.references_error() {
+            self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
+        }
     }
 
-    pub fn register_bound(&self,
-                          ty: Ty<'tcx>,
-                          def_id: DefId,
-                          cause: traits::ObligationCause<'tcx>)
-    {
-        self.fulfillment_cx.borrow_mut()
-                           .register_bound(self, self.param_env, ty, def_id, cause);
+    pub fn register_bound(
+        &self,
+        ty: Ty<'tcx>,
+        def_id: DefId,
+        cause: traits::ObligationCause<'tcx>,
+    ) {
+        if !ty.references_error() {
+            self.fulfillment_cx.borrow_mut()
+                .register_bound(self, self.param_env, ty, def_id, cause);
+        }
     }
 
     pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
@@ -2780,22 +2789,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Registers an obligation for checking later, during regionck, that the type `ty` must
     /// outlive the region `r`.
-    pub fn register_wf_obligation(&self,
-                                  ty: Ty<'tcx>,
-                                  span: Span,
-                                  code: traits::ObligationCauseCode<'tcx>)
-    {
+    pub fn register_wf_obligation(
+        &self,
+        ty: Ty<'tcx>,
+        span: Span,
+        code: traits::ObligationCauseCode<'tcx>,
+    ) {
         // WF obligations never themselves fail, so no real need to give a detailed cause:
         let cause = traits::ObligationCause::new(span, self.body_id, code);
-        self.register_predicate(traits::Obligation::new(cause,
-                                                        self.param_env,
-                                                        ty::Predicate::WellFormed(ty)));
+        self.register_predicate(
+            traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty)),
+        );
     }
 
     /// Registers obligations that all types appearing in `substs` are well-formed.
     pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr) {
         for ty in substs.types() {
-            self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
+            if !ty.references_error() {
+                self.register_wf_obligation(ty, expr.span, traits::MiscObligation);
+            }
         }
     }
 
@@ -2834,12 +2846,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // FIXME(arielb1): use this instead of field.ty everywhere
     // Only for fields! Returns <none> for methods>
     // Indifferent to privacy flags
-    pub fn field_ty(&self,
-                    span: Span,
-                    field: &'tcx ty::FieldDef,
-                    substs: SubstsRef<'tcx>)
-                    -> Ty<'tcx>
-    {
+    pub fn field_ty(
+        &self,
+        span: Span,
+        field: &'tcx ty::FieldDef,
+        substs: SubstsRef<'tcx>,
+    ) -> Ty<'tcx> {
         self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
     }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index f7e766bb84d..265d0676fa8 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -596,7 +596,7 @@ fn check_fn_or_method<'fcx, 'tcx>(
     }
     implied_bounds.extend(sig.inputs());
 
-    fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::MiscObligation);
+    fcx.register_wf_obligation(sig.output(), span, ObligationCauseCode::ReturnType);
 
     // FIXME(#25759) return types should not be implied bounds
     implied_bounds.push(sig.output());
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs
index fa1889389fd..9a64a06c31b 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.rs
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.rs
@@ -1,10 +1,10 @@
 #![feature(trait_alias)]
 
 trait Foo: Iterator<Item = i32> {}
-trait Bar: Foo<Item = u32> {} //~ ERROR type annotations required
+trait Bar: Foo<Item = u32> {} //~ ERROR type annotations needed
 
 trait I32Iterator = Iterator<Item = i32>;
-trait U32Iterator = I32Iterator<Item = u32>;
+trait U32Iterator = I32Iterator<Item = u32>; //~ ERROR type annotations needed
 
 fn main() {
     let _: &dyn I32Iterator<Item = u32>;
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
index a7238541cd9..5ef1b23cbcd 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -1,4 +1,4 @@
-error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
+error[E0284]: type annotations needed: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
   --> $DIR/associated-types-overridden-binding.rs:4:1
    |
 LL | trait Foo: Iterator<Item = i32> {}
@@ -6,6 +6,13 @@ LL | trait Foo: Iterator<Item = i32> {}
 LL | trait Bar: Foo<Item = u32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error[E0282]: type annotations needed
+  --> $DIR/associated-types-overridden-binding.rs:7:1
+   |
+LL | trait U32Iterator = I32Iterator<Item = u32>;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0284`.
+Some errors have detailed explanations: E0282, E0284.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.rs b/src/test/ui/associated-types/associated-types-unconstrained.rs
index 99424836ece..b97d4af184f 100644
--- a/src/test/ui/associated-types/associated-types-unconstrained.rs
+++ b/src/test/ui/associated-types/associated-types-unconstrained.rs
@@ -12,5 +12,5 @@ impl Foo for isize {
 
 pub fn main() {
     let x: isize = Foo::bar();
-    //~^ ERROR type annotations required
+    //~^ ERROR type annotations needed
 }
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr
index da14a69ae30..4e9e54d3688 100644
--- a/src/test/ui/associated-types/associated-types-unconstrained.stderr
+++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr
@@ -1,4 +1,4 @@
-error[E0284]: type annotations required: cannot resolve `<_ as Foo>::A == _`
+error[E0284]: type annotations needed: cannot resolve `<_ as Foo>::A == _`
   --> $DIR/associated-types-unconstrained.rs:14:20
    |
 LL |     let x: isize = Foo::bar();
diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr
index 1d99f99c623..aba649d83ec 100644
--- a/src/test/ui/error-codes/E0283.stderr
+++ b/src/test/ui/error-codes/E0283.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `_: Generator`
+error[E0283]: type annotations needed: cannot resolve `_: Generator`
   --> $DIR/E0283.rs:18:21
    |
 LL |     fn create() -> u32;
diff --git a/src/test/ui/error-codes/E0401.rs b/src/test/ui/error-codes/E0401.rs
index a120198b728..c30e5f47188 100644
--- a/src/test/ui/error-codes/E0401.rs
+++ b/src/test/ui/error-codes/E0401.rs
@@ -8,7 +8,7 @@ fn foo<T>(x: T) {
            W: Fn()>
            (y: T) { //~ ERROR E0401
     }
-    bfnr(x);
+    bfnr(x); //~ ERROR type annotations needed
 }
 
 
diff --git a/src/test/ui/error-codes/E0401.stderr b/src/test/ui/error-codes/E0401.stderr
index 1d9dfe46722..485b76a09a3 100644
--- a/src/test/ui/error-codes/E0401.stderr
+++ b/src/test/ui/error-codes/E0401.stderr
@@ -32,6 +32,13 @@ LL |         fn helper(sel: &Self) -> u8 {
    |                         use of generic parameter from outer function
    |                         use a type here instead
 
-error: aborting due to 3 previous errors
+error[E0282]: type annotations needed
+  --> $DIR/E0401.rs:11:5
+   |
+LL |     bfnr(x);
+   |     ^^^^ cannot infer type for `U`
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0401`.
+Some errors have detailed explanations: E0282, E0401.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/error-codes/E0661.rs b/src/test/ui/error-codes/E0661.rs
index 2440e3a446e..5ac0c415ae1 100644
--- a/src/test/ui/error-codes/E0661.rs
+++ b/src/test/ui/error-codes/E0661.rs
@@ -3,7 +3,7 @@
 #![feature(asm)]
 
 fn main() {
-    let a;
+    let a; //~ ERROR type annotations needed
     asm!("nop" : "r"(a));
     //~^ ERROR E0661
 }
diff --git a/src/test/ui/error-codes/E0661.stderr b/src/test/ui/error-codes/E0661.stderr
index 58f7e7fa0f9..3537e0bc3a4 100644
--- a/src/test/ui/error-codes/E0661.stderr
+++ b/src/test/ui/error-codes/E0661.stderr
@@ -4,5 +4,12 @@ error[E0661]: output operand constraint lacks '=' or '+'
 LL |     asm!("nop" : "r"(a));
    |                  ^^^
 
-error: aborting due to previous error
+error[E0282]: type annotations needed
+  --> $DIR/E0661.rs:6:9
+   |
+LL |     let a;
+   |         ^ consider giving `a` a type
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/impl-trait/where-allowed.rs b/src/test/ui/impl-trait/where-allowed.rs
index 9eac6b714de..65c4b78bf6a 100644
--- a/src/test/ui/impl-trait/where-allowed.rs
+++ b/src/test/ui/impl-trait/where-allowed.rs
@@ -11,8 +11,9 @@ fn in_return() -> impl Debug { panic!() }
 // Allowed
 fn in_adt_in_parameters(_: Vec<impl Debug>) { panic!() }
 
-// Allowed
+// Disallowed
 fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
+//~^ ERROR type annotations needed
 
 // Disallowed
 fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
@@ -58,7 +59,8 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
 // Disallowed
 fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
-//~^^ ERROR nested `impl Trait` is not allowed
+//~| ERROR nested `impl Trait` is not allowed
+//~| ERROR type annotations needed
 
 // Disallowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr
index 1332fff84f5..dfb6e6524d9 100644
--- a/src/test/ui/impl-trait/where-allowed.stderr
+++ b/src/test/ui/impl-trait/where-allowed.stderr
@@ -1,5 +1,5 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:50:51
+  --> $DIR/where-allowed.rs:51:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           --------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:59:57
+  --> $DIR/where-allowed.rs:60:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                 --------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:122:5
+  --> $DIR/where-allowed.rs:124:5
    |
 LL |     type Out = impl Debug;
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     type Out = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:158:1
+  --> $DIR/where-allowed.rs:160:1
    |
 LL | type InTypeAlias<R> = impl Debug;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,205 +35,205 @@ LL | type InTypeAlias<R> = impl Debug;
    = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:18:40
+  --> $DIR/where-allowed.rs:19:40
    |
 LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
    |                                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:22:42
+  --> $DIR/where-allowed.rs:23:42
    |
 LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
    |                                          ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:26:38
+  --> $DIR/where-allowed.rs:27:38
    |
 LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
    |                                      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:30:40
+  --> $DIR/where-allowed.rs:31:40
    |
 LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
    |                                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:34:49
+  --> $DIR/where-allowed.rs:35:49
    |
 LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
    |                                                 ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:38:51
+  --> $DIR/where-allowed.rs:39:51
    |
 LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
    |                                                   ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:42:55
+  --> $DIR/where-allowed.rs:43:55
    |
 LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
    |                                                       ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:46:57
+  --> $DIR/where-allowed.rs:47:57
    |
 LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
    |                                                         ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:50:51
+  --> $DIR/where-allowed.rs:51:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                                   ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:55:53
+  --> $DIR/where-allowed.rs:56:53
    |
 LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
    |                                                     ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:59:57
+  --> $DIR/where-allowed.rs:60:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                         ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:64:59
+  --> $DIR/where-allowed.rs:66:59
    |
 LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
    |                                                           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:68:38
+  --> $DIR/where-allowed.rs:70:38
    |
 LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    |                                      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:72:40
+  --> $DIR/where-allowed.rs:74:40
    |
 LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    |                                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:85:32
+  --> $DIR/where-allowed.rs:87:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:89:41
+  --> $DIR/where-allowed.rs:91:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:93:27
+  --> $DIR/where-allowed.rs:95:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:98:25
+  --> $DIR/where-allowed.rs:100:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:100:20
+  --> $DIR/where-allowed.rs:102:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:111:23
+  --> $DIR/where-allowed.rs:113:23
    |
 LL |     fn in_return() -> impl Debug;
    |                       ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:129:34
+  --> $DIR/where-allowed.rs:131:34
    |
 LL |     fn in_trait_impl_return() -> impl Debug { () }
    |                                  ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:142:33
+  --> $DIR/where-allowed.rs:144:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:145:31
+  --> $DIR/where-allowed.rs:147:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:162:39
+  --> $DIR/where-allowed.rs:164:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:166:16
+  --> $DIR/where-allowed.rs:168:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:171:24
+  --> $DIR/where-allowed.rs:173:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:176:6
+  --> $DIR/where-allowed.rs:178:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:182:24
+  --> $DIR/where-allowed.rs:184:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:188:11
+  --> $DIR/where-allowed.rs:190:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:195:15
+  --> $DIR/where-allowed.rs:197:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:202:24
+  --> $DIR/where-allowed.rs:204:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:209:17
+  --> $DIR/where-allowed.rs:211:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:216:22
+  --> $DIR/where-allowed.rs:218:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:222:29
+  --> $DIR/where-allowed.rs:224:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -241,24 +241,36 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
-  --> $DIR/where-allowed.rs:224:46
+  --> $DIR/where-allowed.rs:226:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
 
+error[E0282]: type annotations needed
+  --> $DIR/where-allowed.rs:15:30
+   |
+LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() }
+   |                              ^^^^^^^^^^ cannot infer type
+
+error[E0282]: type annotations needed
+  --> $DIR/where-allowed.rs:60:49
+   |
+LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
+   |                                                 ^^^^^^^^^^^^^^^^^^^ cannot infer type
+
 error: could not find defining uses
-  --> $DIR/where-allowed.rs:158:1
+  --> $DIR/where-allowed.rs:160:1
    |
 LL | type InTypeAlias<R> = impl Debug;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: could not find defining uses
-  --> $DIR/where-allowed.rs:122:5
+  --> $DIR/where-allowed.rs:124:5
    |
 LL |     type Out = impl Debug;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 41 previous errors
+error: aborting due to 43 previous errors
 
-Some errors have detailed explanations: E0562, E0658.
-For more information about an error, try `rustc --explain E0562`.
+Some errors have detailed explanations: E0282, E0562, E0658.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/issues/issue-12028.rs b/src/test/ui/issues/issue-12028.rs
index 7c2b0d69c8b..7503766ff20 100644
--- a/src/test/ui/issues/issue-12028.rs
+++ b/src/test/ui/issues/issue-12028.rs
@@ -24,7 +24,7 @@ trait StreamHash<H: StreamHasher>: Hash<H> {
 impl<H: StreamHasher> Hash<H> for u8 {
     fn hash2(&self, hasher: &H) -> u64 {
         let mut stream = hasher.stream();
-        self.input_stream(&mut stream); //~ ERROR type annotations required
+        self.input_stream(&mut stream); //~ ERROR type annotations needed
         Stream::result(&stream)
     }
 }
diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr
index 24aa88c3fa3..ff92d01a69e 100644
--- a/src/test/ui/issues/issue-12028.stderr
+++ b/src/test/ui/issues/issue-12028.stderr
@@ -1,4 +1,4 @@
-error[E0284]: type annotations required: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
+error[E0284]: type annotations needed: cannot resolve `<_ as StreamHasher>::S == <H as StreamHasher>::S`
   --> $DIR/issue-12028.rs:27:14
    |
 LL |         self.input_stream(&mut stream);
diff --git a/src/test/ui/issues/issue-21974.rs b/src/test/ui/issues/issue-21974.rs
index f49eb230b40..0cbe38d6ec0 100644
--- a/src/test/ui/issues/issue-21974.rs
+++ b/src/test/ui/issues/issue-21974.rs
@@ -7,7 +7,7 @@ trait Foo {
     fn foo(self);
 }
 
-fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required
+fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed
     where &'a T : Foo,
           &'b T : Foo
 {
diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr
index a6cce7846e8..7ceb2bd23f6 100644
--- a/src/test/ui/issues/issue-21974.stderr
+++ b/src/test/ui/issues/issue-21974.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
+error[E0283]: type annotations needed: cannot resolve `&'a T: Foo`
   --> $DIR/issue-21974.rs:10:1
    |
 LL |   trait Foo {
diff --git a/src/test/ui/issues/issue-24424.rs b/src/test/ui/issues/issue-24424.rs
index 8b8c5bc23e4..9b74cd1230e 100644
--- a/src/test/ui/issues/issue-24424.rs
+++ b/src/test/ui/issues/issue-24424.rs
@@ -2,6 +2,6 @@ trait Trait1<'l0, T0> {}
 trait Trait0<'l0>  {}
 
 impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
-//~^ ERROR type annotations required: cannot resolve `T0: Trait0<'l0>`
+//~^ ERROR type annotations needed: cannot resolve `T0: Trait0<'l0>`
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr
index 7ff019a30a8..8c539f7cedd 100644
--- a/src/test/ui/issues/issue-24424.stderr
+++ b/src/test/ui/issues/issue-24424.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>`
+error[E0283]: type annotations needed: cannot resolve `T0: Trait0<'l0>`
   --> $DIR/issue-24424.rs:4:1
    |
 LL | trait Trait0<'l0>  {}
diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr
index 0dc9b0c9e10..c9dd92fca7d 100644
--- a/src/test/ui/issues/issue-29147.stderr
+++ b/src/test/ui/issues/issue-29147.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `S5<_>: Foo`
+error[E0283]: type annotations needed: cannot resolve `S5<_>: Foo`
   --> $DIR/issue-29147.rs:21:13
    |
 LL | trait Foo { fn xxx(&self); }
diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs
index 40045bc758c..9e9f92ed9ac 100644
--- a/src/test/ui/issues/issue-54954.rs
+++ b/src/test/ui/issues/issue-54954.rs
@@ -1,7 +1,7 @@
 #![feature(const_fn)]
 
 const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
-//~^ ERROR constant contains unimplemented expression type
+//~^ ERROR type annotations needed
 
 trait Tt {
     const fn const_val<T: Sized>() -> usize {
@@ -11,6 +11,8 @@ trait Tt {
 }
 
 fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
+    //~^ ERROR evaluation of constant value failed
+    //~| ERROR evaluation of constant value failed
     z
 }
 
diff --git a/src/test/ui/issues/issue-54954.stderr b/src/test/ui/issues/issue-54954.stderr
index 29edb506c4b..56ccdaf7aac 100644
--- a/src/test/ui/issues/issue-54954.stderr
+++ b/src/test/ui/issues/issue-54954.stderr
@@ -4,13 +4,28 @@ error[E0379]: trait fns cannot be declared const
 LL |     const fn const_val<T: Sized>() -> usize {
    |     ^^^^^ trait fns cannot be const
 
-error[E0019]: constant contains unimplemented expression type
+error[E0283]: type annotations needed: cannot resolve `_: Tt`
   --> $DIR/issue-54954.rs:3:24
    |
 LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     const fn const_val<T: Sized>() -> usize {
+   |              --------- - required by this bound in `Tt::const_val`
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/issue-54954.rs:13:15
+   |
+LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
+   |               ^^^^^^^ referenced constant has errors
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/issue-54954.rs:13:34
+   |
+LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] {
+   |                                  ^^^^^^^ referenced constant has errors
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0019, E0379.
-For more information about an error, try `rustc --explain E0019`.
+Some errors have detailed explanations: E0080, E0283, E0379.
+For more information about an error, try `rustc --explain E0080`.
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 e33f23c64db..49fe7d1324c 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
@@ -15,7 +15,7 @@ impl Foo for Vec<isize> {
 }
 
 // This is very hokey: we have heuristics to suppress messages about
-// type annotations required. But placing these two bits of code into
+// type annotations needed. But placing these two bits of code into
 // distinct functions, in this order, causes us to print out both
 // errors I'd like to see.
 
diff --git a/src/test/ui/parser/raw/raw-literal-self.rs b/src/test/ui/parser/raw/raw-literal-self.rs
index 123a11b6f85..a0c9e24c235 100644
--- a/src/test/ui/parser/raw/raw-literal-self.rs
+++ b/src/test/ui/parser/raw/raw-literal-self.rs
@@ -1,4 +1,4 @@
 fn main() {
-    let r#self;
+    let r#self: ();
     //~^ ERROR `self` cannot be a raw identifier
 }
diff --git a/src/test/ui/parser/raw/raw-literal-self.stderr b/src/test/ui/parser/raw/raw-literal-self.stderr
index 9a330fcdf2a..2a40dfe200c 100644
--- a/src/test/ui/parser/raw/raw-literal-self.stderr
+++ b/src/test/ui/parser/raw/raw-literal-self.stderr
@@ -1,7 +1,7 @@
 error: `self` cannot be a raw identifier
   --> $DIR/raw-literal-self.rs:2:9
    |
-LL |     let r#self;
+LL |     let r#self: ();
    |         ^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.rs b/src/test/ui/parser/raw/raw-literal-underscore.rs
index 6d15f1e7f0a..a9d9e13a9d9 100644
--- a/src/test/ui/parser/raw/raw-literal-underscore.rs
+++ b/src/test/ui/parser/raw/raw-literal-underscore.rs
@@ -1,4 +1,4 @@
 fn main() {
-    let r#_;
+    let r#_: ();
     //~^ ERROR `_` cannot be a raw identifier
 }
diff --git a/src/test/ui/parser/raw/raw-literal-underscore.stderr b/src/test/ui/parser/raw/raw-literal-underscore.stderr
index d96b14f55a3..d7a364d8579 100644
--- a/src/test/ui/parser/raw/raw-literal-underscore.stderr
+++ b/src/test/ui/parser/raw/raw-literal-underscore.stderr
@@ -1,7 +1,7 @@
 error: `_` cannot be a raw identifier
   --> $DIR/raw-literal-underscore.rs:2:9
    |
-LL |     let r#_;
+LL |     let r#_: ();
    |         ^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
index 36a45a3ccdc..31620216e82 100644
--- a/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
+++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.rs
@@ -31,6 +31,7 @@ fn rest_patterns() {
 
     // Ident patterns:
     let x @ ..; //~ ERROR `..` patterns are not allowed here
+    //~^ ERROR type annotations needed
     let ref x @ ..; //~ ERROR `..` patterns are not allowed here
     let ref mut x @ ..; //~ ERROR `..` patterns are not allowed here
 
diff --git a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
index 826f76b356c..be484e3a4d4 100644
--- a/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
+++ b/src/test/ui/pattern/rest-pat-semantic-disallowed.stderr
@@ -58,7 +58,7 @@ LL |     let x @ ..;
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error: `..` patterns are not allowed here
-  --> $DIR/rest-pat-semantic-disallowed.rs:34:17
+  --> $DIR/rest-pat-semantic-disallowed.rs:35:17
    |
 LL |     let ref x @ ..;
    |                 ^^
@@ -66,7 +66,7 @@ LL |     let ref x @ ..;
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error: `..` patterns are not allowed here
-  --> $DIR/rest-pat-semantic-disallowed.rs:35:21
+  --> $DIR/rest-pat-semantic-disallowed.rs:36:21
    |
 LL |     let ref mut x @ ..;
    |                     ^^
@@ -74,7 +74,7 @@ LL |     let ref mut x @ ..;
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error: `..` can only be used once per tuple pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:42:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:43:9
    |
 LL |         ..,
    |         -- previously used here
@@ -82,7 +82,7 @@ LL |         ..,
    |         ^^ can only be used once per tuple pattern
 
 error: `..` can only be used once per tuple pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:43:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:44:9
    |
 LL |         ..,
    |         -- previously used here
@@ -91,7 +91,7 @@ LL |         ..
    |         ^^ can only be used once per tuple pattern
 
 error: `..` can only be used once per tuple pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:48:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:49:9
    |
 LL |         ..,
    |         -- previously used here
@@ -100,7 +100,7 @@ LL |         ..
    |         ^^ can only be used once per tuple pattern
 
 error: `..` can only be used once per tuple struct pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:58:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:59:9
    |
 LL |         ..,
    |         -- previously used here
@@ -108,7 +108,7 @@ LL |         ..,
    |         ^^ can only be used once per tuple struct pattern
 
 error: `..` can only be used once per tuple struct pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:59:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:60:9
    |
 LL |         ..,
    |         -- previously used here
@@ -117,7 +117,7 @@ LL |         ..
    |         ^^ can only be used once per tuple struct pattern
 
 error: `..` can only be used once per tuple struct pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:64:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:65:9
    |
 LL |         ..,
    |         -- previously used here
@@ -126,7 +126,7 @@ LL |         ..
    |         ^^ can only be used once per tuple struct pattern
 
 error: `..` can only be used once per slice pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:72:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:73:9
    |
 LL |         ..,
    |         -- previously used here
@@ -134,7 +134,7 @@ LL |         ..,
    |         ^^ can only be used once per slice pattern
 
 error: `..` can only be used once per slice pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:73:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:74:9
    |
 LL |         ..,
    |         -- previously used here
@@ -143,7 +143,7 @@ LL |         ..
    |         ^^ can only be used once per slice pattern
 
 error: `..` can only be used once per slice pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:77:17
+  --> $DIR/rest-pat-semantic-disallowed.rs:78:17
    |
 LL |         ..,
    |         -- previously used here
@@ -151,7 +151,7 @@ LL |         ref x @ ..,
    |                 ^^ can only be used once per slice pattern
 
 error: `..` can only be used once per slice pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:78:21
+  --> $DIR/rest-pat-semantic-disallowed.rs:79:21
    |
 LL |         ..,
    |         -- previously used here
@@ -160,7 +160,7 @@ LL |         ref mut y @ ..,
    |                     ^^ can only be used once per slice pattern
 
 error: `..` patterns are not allowed here
-  --> $DIR/rest-pat-semantic-disallowed.rs:79:18
+  --> $DIR/rest-pat-semantic-disallowed.rs:80:18
    |
 LL |         (ref z @ ..),
    |                  ^^
@@ -168,7 +168,7 @@ LL |         (ref z @ ..),
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error: `..` can only be used once per slice pattern
-  --> $DIR/rest-pat-semantic-disallowed.rs:80:9
+  --> $DIR/rest-pat-semantic-disallowed.rs:81:9
    |
 LL |         ..,
    |         -- previously used here
@@ -184,5 +184,12 @@ LL |     fn foo(..: u8) {}
    |
    = note: only allowed in tuple, tuple struct, and slice patterns
 
-error: aborting due to 22 previous errors
+error[E0282]: type annotations needed
+  --> $DIR/rest-pat-semantic-disallowed.rs:33:9
+   |
+LL |     let x @ ..;
+   |         ^^^^^^ consider giving this pattern a type
+
+error: aborting due to 23 previous errors
 
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/question-mark-type-infer.rs b/src/test/ui/question-mark-type-infer.rs
index 2e7a342b95e..95ee01a70ce 100644
--- a/src/test/ui/question-mark-type-infer.rs
+++ b/src/test/ui/question-mark-type-infer.rs
@@ -9,7 +9,7 @@ fn f(x: &i32) -> Result<i32, ()> {
 
 fn g() -> Result<Vec<i32>, ()> {
     let l = [1, 2, 3, 4];
-    l.iter().map(f).collect()? //~ ERROR type annotations required: cannot resolve
+    l.iter().map(f).collect()? //~ ERROR type annotations needed: cannot resolve
 }
 
 fn main() {
diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr
index f62a540572c..53a170e7d43 100644
--- a/src/test/ui/question-mark-type-infer.stderr
+++ b/src/test/ui/question-mark-type-infer.stderr
@@ -1,4 +1,4 @@
-error[E0284]: type annotations required: cannot resolve `<_ as std::ops::Try>::Ok == _`
+error[E0284]: type annotations needed: cannot resolve `<_ as std::ops::Try>::Ok == _`
   --> $DIR/question-mark-type-infer.rs:12:5
    |
 LL |     l.iter().map(f).collect()?
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index 9f4e2710dc4..e2680446f85 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -20,7 +20,7 @@ type Alias = extern "C" fn(#[id] u8, #[id] ...);
 
 fn free(#[id] arg1: u8) {
     //~^ ERROR expected an inert attribute, found an attribute macro
-    let lam = |#[id] W(x), #[id] y| ();
+    let lam = |#[id] W(x), #[id] y: usize| ();
     //~^ ERROR expected an inert attribute, found an attribute macro
     //~| ERROR expected an inert attribute, found an attribute macro
 }
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index b4946fa7494..4654dc1b496 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -37,13 +37,13 @@ LL | fn free(#[id] arg1: u8) {
 error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:23:16
    |
-LL |     let lam = |#[id] W(x), #[id] y| ();
+LL |     let lam = |#[id] W(x), #[id] y: usize| ();
    |                ^^^^^
 
 error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:23:28
    |
-LL |     let lam = |#[id] W(x), #[id] y| ();
+LL |     let lam = |#[id] W(x), #[id] y: usize| ();
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
diff --git a/src/test/ui/traits/trait-static-method-generic-inference.rs b/src/test/ui/traits/trait-static-method-generic-inference.rs
index c08bd5cb135..759416d1901 100644
--- a/src/test/ui/traits/trait-static-method-generic-inference.rs
+++ b/src/test/ui/traits/trait-static-method-generic-inference.rs
@@ -22,7 +22,7 @@ mod base {
 
 pub fn foo() {
     let _f: base::Foo = base::HasNew::new();
-    //~^ ERROR type annotations required
+    //~^ ERROR type annotations needed
 }
 
 fn main() { }
diff --git a/src/test/ui/traits/trait-static-method-generic-inference.stderr b/src/test/ui/traits/trait-static-method-generic-inference.stderr
index a99536d31ef..22931c5ba32 100644
--- a/src/test/ui/traits/trait-static-method-generic-inference.stderr
+++ b/src/test/ui/traits/trait-static-method-generic-inference.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `_: base::HasNew<base::Foo>`
+error[E0283]: type annotations needed: cannot resolve `_: base::HasNew<base::Foo>`
   --> $DIR/trait-static-method-generic-inference.rs:24:25
    |
 LL |         fn new() -> T;
diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs
index ddf16f76995..3b1521d5c02 100644
--- a/src/test/ui/type/type-annotation-needed.rs
+++ b/src/test/ui/type/type-annotation-needed.rs
@@ -4,5 +4,5 @@ fn foo<T: Into<String>>(x: i32) {}
 
 fn main() {
     foo(42);
-    //~^ ERROR type annotations required
+    //~^ ERROR type annotations needed
 }
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index 01287b727d2..460bbe9dbc4 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::string::String>`
+error[E0283]: type annotations needed: cannot resolve `_: std::convert::Into<std::string::String>`
   --> $DIR/type-annotation-needed.rs:6:5
    |
 LL | fn foo<T: Into<String>>(x: i32) {}
diff --git a/src/test/ui/type/type-check/issue-40294.rs b/src/test/ui/type/type-check/issue-40294.rs
index c73acdc467e..7e6429ccfbe 100644
--- a/src/test/ui/type/type-check/issue-40294.rs
+++ b/src/test/ui/type/type-check/issue-40294.rs
@@ -2,7 +2,7 @@ trait Foo: Sized {
     fn foo(self);
 }
 
-fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required
+fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations needed
     where &'a T : Foo,
           &'b T : Foo
 {
diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr
index 732a81c8a24..508783aaf2b 100644
--- a/src/test/ui/type/type-check/issue-40294.stderr
+++ b/src/test/ui/type/type-check/issue-40294.stderr
@@ -1,4 +1,4 @@
-error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
+error[E0283]: type annotations needed: cannot resolve `&'a T: Foo`
   --> $DIR/issue-40294.rs:5:1
    |
 LL |   trait Foo: Sized {
diff --git a/src/test/ui/type/type-path-err-node-types.rs b/src/test/ui/type/type-path-err-node-types.rs
index a2cc5070db4..15adfebb334 100644
--- a/src/test/ui/type/type-path-err-node-types.rs
+++ b/src/test/ui/type/type-path-err-node-types.rs
@@ -20,7 +20,7 @@ fn method() {
 }
 
 fn closure() {
-    let _ = |a, b: _| -> _ { 0 }; // OK
+    let _ = |a, b: _| -> _ { 0 }; //~ ERROR type annotations needed
 }
 
 fn main() {}
diff --git a/src/test/ui/type/type-path-err-node-types.stderr b/src/test/ui/type/type-path-err-node-types.stderr
index ed744478f26..cd93525c762 100644
--- a/src/test/ui/type/type-path-err-node-types.stderr
+++ b/src/test/ui/type/type-path-err-node-types.stderr
@@ -22,7 +22,13 @@ error[E0425]: cannot find value `nonexistent` in this scope
 LL |     nonexistent.nonexistent::<u8>();
    |     ^^^^^^^^^^^ not found in this scope
 
-error: aborting due to 4 previous errors
+error[E0282]: type annotations needed
+  --> $DIR/type-path-err-node-types.rs:23:14
+   |
+LL |     let _ = |a, b: _| -> _ { 0 };
+   |              ^ consider giving this closure parameter a type
+
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0412, E0425, E0433.
-For more information about an error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0282, E0412, E0425, E0433.
+For more information about an error, try `rustc --explain E0282`.