about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-04-17 11:52:01 +0000
committerbors <bors@rust-lang.org>2020-04-17 11:52:01 +0000
commit8d67f576b56e8fc98a31123e5963f8d00e40611c (patch)
tree41ca42929c30c4fe7da7021b9f4dc7355e7ffe47
parentb2c1a606feb1fbdb0ac0acba76f881ef172ed474 (diff)
parent77f38dc284c3adab8c529e478fe8b2fa5e4a82d3 (diff)
downloadrust-8d67f576b56e8fc98a31123e5963f8d00e40611c.tar.gz
rust-8d67f576b56e8fc98a31123e5963f8d00e40611c.zip
Auto merge of #71049 - eddyb:const-err, r=oli-obk
Add `ConstKind::Error` and convert `ErrorHandled::Reported` to it.

By replicating the `ty::Error` approach to encoding "an error has occurred", all of the mechanisms that skip redundant/downstream errors are engaged and help out (see the reduction in test output).

This PR also adds `ErrorHandled::Linted` for the lint case because using `ErrorHandled::Reported` *without* having emitted an error that is *guaranteed* to stop compilation, is incorrect now.

r? @oli-obk cc @rust-lang/wg-const-eval @varkor @yodaldevoid
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs7
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs4
-rw-r--r--src/librustc_infer/infer/freshen.rs5
-rw-r--r--src/librustc_infer/infer/resolve.rs2
-rw-r--r--src/librustc_middle/mir/interpret/error.rs57
-rw-r--r--src/librustc_middle/ty/context.rs12
-rw-r--r--src/librustc_middle/ty/flags.rs10
-rw-r--r--src/librustc_middle/ty/fold.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs7
-rw-r--r--src/librustc_middle/ty/print/pretty.rs1
-rw-r--r--src/librustc_middle/ty/relate.rs12
-rw-r--r--src/librustc_middle/ty/structural_impls.rs14
-rw-r--r--src/librustc_middle/ty/sty.rs13
-rw-r--r--src/librustc_middle/ty/walk.rs3
-rw-r--r--src/librustc_mir/borrow_check/mod.rs4
-rw-r--r--src/librustc_mir/const_eval/eval_queries.rs16
-rw-r--r--src/librustc_mir/interpret/eval_context.rs9
-rw-r--r--src/librustc_mir/interpret/intern.rs5
-rw-r--r--src/librustc_mir/interpret/memory.rs9
-rw-r--r--src/librustc_mir/interpret/operand.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs3
-rw-r--r--src/librustc_mir_build/build/mod.rs3
-rw-r--r--src/librustc_mir_build/hair/cx/expr.rs14
-rw-r--r--src/librustc_trait_selection/opaque_types.rs2
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs15
-rw-r--r--src/librustc_typeck/astconv.rs4
-rw-r--r--src/librustc_typeck/check/writeback.rs13
-rw-r--r--src/librustc_typeck/collect.rs7
-rw-r--r--src/librustc_typeck/collect/type_of.rs6
-rw-r--r--src/test/ui/array-break-length.rs2
-rw-r--r--src/test/ui/array-break-length.stderr25
-rw-r--r--src/test/ui/closures/closure-array-break-length.rs2
-rw-r--r--src/test/ui/closures/closure-array-break-length.stderr25
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3.rs1
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3.stderr14
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3b.rs1
-rw-r--r--src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr11
-rw-r--r--src/test/ui/consts/const-eval/match-test-ptr-null.rs2
-rw-r--r--src/test/ui/consts/const-eval/match-test-ptr-null.stderr27
-rw-r--r--src/test/ui/consts/const-integer-bool-ops.rs10
-rw-r--r--src/test/ui/consts/const-integer-bool-ops.stderr95
-rw-r--r--src/test/ui/consts/const-tup-index-span.rs1
-rw-r--r--src/test/ui/consts/const-tup-index-span.stderr11
-rw-r--r--src/test/ui/issues/issue-39559-2.rs1
-rw-r--r--src/test/ui/issues/issue-39559-2.stderr16
-rw-r--r--src/test/ui/issues/issue-41394.rs1
-rw-r--r--src/test/ui/issues/issue-41394.stderr11
-rw-r--r--src/test/ui/issues/issue-50599.rs1
-rw-r--r--src/test/ui/issues/issue-50599.stderr11
-rw-r--r--src/test/ui/issues/issue-52060.rs1
-rw-r--r--src/test/ui/issues/issue-52060.stderr13
-rw-r--r--src/test/ui/issues/issue-54954.rs2
-rw-r--r--src/test/ui/issues/issue-54954.stderr18
-rw-r--r--src/test/ui/resolve/issue-65035-static-with-parent-generics.rs3
-rw-r--r--src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr14
-rw-r--r--src/test/ui/type/type-dependent-def-issue-49241.rs2
-rw-r--r--src/test/ui/type/type-dependent-def-issue-49241.stderr19
57 files changed, 193 insertions, 408 deletions
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 69f11ed57ac..7d0e6998db4 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -6,6 +6,7 @@ use crate::glue;
 use crate::traits::*;
 use crate::MemFlags;
 
+use rustc_errors::ErrorReported;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
 use rustc_middle::ty::layout::TyAndLayout;
@@ -447,8 +448,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
                     match err {
                         // errored or at least linted
-                        ErrorHandled::Reported => {}
-                        ErrorHandled::TooGeneric => bug!("codgen encountered polymorphic constant"),
+                        ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
+                        ErrorHandled::TooGeneric => {
+                            bug!("codegen encountered polymorphic constant")
+                        }
                     }
                     // Allow RalfJ to sleep soundly knowing that even refactorings that remove
                     // the above error (or silence it under some conditions) will not cause UB.
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 2aed0b7490c..3711d848d81 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -304,8 +304,8 @@ pub fn unexpected_hidden_region_diagnostic(
         // down this path which gives a decent human readable
         // explanation.
         //
-        // (*) if not, the `tainted_by_errors` flag would be set to
-        // true in any case, so we wouldn't be here at all.
+        // (*) if not, the `tainted_by_errors` field would be set to
+        // `Some(ErrorReported)` in any case, so we wouldn't be here at all.
         note_and_explain_free_region(
             tcx,
             &mut err,
diff --git a/src/librustc_infer/infer/freshen.rs b/src/librustc_infer/infer/freshen.rs
index eeaa4c1661e..a95d276f4a8 100644
--- a/src/librustc_infer/infer/freshen.rs
+++ b/src/librustc_infer/infer/freshen.rs
@@ -251,7 +251,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
                 bug!("unexpected const {:?}", ct)
             }
 
-            ty::ConstKind::Param(_) | ty::ConstKind::Value(_) | ty::ConstKind::Unevaluated(..) => {}
+            ty::ConstKind::Param(_)
+            | ty::ConstKind::Value(_)
+            | ty::ConstKind::Unevaluated(..)
+            | ty::ConstKind::Error => {}
         }
 
         ct.super_fold_with(self)
diff --git a/src/librustc_infer/infer/resolve.rs b/src/librustc_infer/infer/resolve.rs
index b908b75a257..bd9d108cfe8 100644
--- a/src/librustc_infer/infer/resolve.rs
+++ b/src/librustc_infer/infer/resolve.rs
@@ -227,7 +227,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
             match c.val {
                 ty::ConstKind::Infer(InferConst::Var(vid)) => {
                     self.err = Some(FixupError::UnresolvedConst(vid));
-                    return self.tcx().consts.err;
+                    return self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: c.ty });
                 }
                 ty::ConstKind::Infer(InferConst::Fresh(_)) => {
                     bug!("Unexpected const in full const resolver: {:?}", c);
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index f058d17a9bf..c56dc5196c6 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -8,7 +8,7 @@ use crate::ty::{self, layout, Ty};
 
 use backtrace::Backtrace;
 use rustc_data_structures::sync::Lock;
-use rustc_errors::{struct_span_err, DiagnosticBuilder};
+use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::definitions::DefPathData;
 use rustc_macros::HashStable;
@@ -19,25 +19,16 @@ use std::{any::Any, fmt, mem};
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
 pub enum ErrorHandled {
-    /// Already reported a lint or an error for this evaluation.
-    Reported,
+    /// Already reported an error for this evaluation, and the compilation is
+    /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
+    Reported(ErrorReported),
+    /// Already emitted a lint for this evaluation.
+    Linted,
     /// Don't emit an error, the evaluation failed because the MIR was generic
     /// and the substs didn't fully monomorphize it.
     TooGeneric,
 }
 
-impl ErrorHandled {
-    pub fn assert_reported(self) {
-        match self {
-            ErrorHandled::Reported => {}
-            ErrorHandled::TooGeneric => bug!(
-                "MIR interpretation failed without reporting an error \
-                 even though it was fully monomorphized"
-            ),
-        }
-    }
-}
-
 CloneTypeFoldableImpls! {
     ErrorHandled,
 }
@@ -84,15 +75,12 @@ impl<'tcx> ConstEvalErr<'tcx> {
         tcx: TyCtxtAt<'tcx>,
         message: &str,
         emit: impl FnOnce(DiagnosticBuilder<'_>),
-    ) -> Result<(), ErrorHandled> {
+    ) -> ErrorHandled {
         self.struct_generic(tcx, message, emit, None)
     }
 
     pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
-        match self.struct_error(tcx, message, |mut e| e.emit()) {
-            Ok(_) => ErrorHandled::Reported,
-            Err(x) => x,
-        }
+        self.struct_error(tcx, message, |mut e| e.emit())
     }
 
     pub fn report_as_lint(
@@ -102,7 +90,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
         lint_root: hir::HirId,
         span: Option<Span>,
     ) -> ErrorHandled {
-        match self.struct_generic(
+        self.struct_generic(
             tcx,
             message,
             |mut lint: DiagnosticBuilder<'_>| {
@@ -122,10 +110,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
                 lint.emit();
             },
             Some(lint_root),
-        ) {
-            Ok(_) => ErrorHandled::Reported,
-            Err(err) => err,
-        }
+        )
     }
 
     /// Create a diagnostic for this const eval error.
@@ -143,12 +128,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
         message: &str,
         emit: impl FnOnce(DiagnosticBuilder<'_>),
         lint_root: Option<hir::HirId>,
-    ) -> Result<(), ErrorHandled> {
+    ) -> ErrorHandled {
         let must_error = match self.error {
             err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
-                return Err(ErrorHandled::TooGeneric);
+                return ErrorHandled::TooGeneric;
+            }
+            err_inval!(TypeckError(error_reported)) => {
+                return ErrorHandled::Reported(error_reported);
             }
-            err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
             // We must *always* hard error on these, even if the caller wants just a lint.
             err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
             _ => false,
@@ -183,6 +170,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
             // caller thinks anyway.
             // See <https://github.com/rust-lang/rust/pull/63152>.
             finish(struct_error(tcx, &err_msg), None);
+            ErrorHandled::Reported(ErrorReported)
         } else {
             // Regular case.
             if let Some(lint_root) = lint_root {
@@ -200,12 +188,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
                     tcx.span,
                     |lint| finish(lint.build(message), Some(err_msg)),
                 );
+                ErrorHandled::Linted
             } else {
                 // Report as hard error.
                 finish(struct_error(tcx, message), Some(err_msg));
+                ErrorHandled::Reported(ErrorReported)
             }
         }
-        Ok(())
     }
 }
 
@@ -246,7 +235,9 @@ fn print_backtrace(backtrace: &mut Backtrace) {
 impl From<ErrorHandled> for InterpErrorInfo<'_> {
     fn from(err: ErrorHandled) -> Self {
         match err {
-            ErrorHandled::Reported => err_inval!(ReferencedConstant),
+            ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
+                err_inval!(ReferencedConstant)
+            }
             ErrorHandled::TooGeneric => err_inval!(TooGeneric),
         }
         .into()
@@ -288,7 +279,7 @@ pub enum InvalidProgramInfo<'tcx> {
     /// which already produced an error.
     ReferencedConstant,
     /// Abort in case type errors are reached.
-    TypeckError,
+    TypeckError(ErrorReported),
     /// An error occurred during layout computation.
     Layout(layout::LayoutError<'tcx>),
     /// An invalid transmute happened.
@@ -301,7 +292,9 @@ impl fmt::Debug for InvalidProgramInfo<'_> {
         match self {
             TooGeneric => write!(f, "encountered overly generic constant"),
             ReferencedConstant => write!(f, "referenced constant has errors"),
-            TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"),
+            TypeckError(ErrorReported) => {
+                write!(f, "encountered constants with type errors, stopping evaluation")
+            }
             Layout(ref err) => write!(f, "{}", err),
             TransmuteSizeDiff(from_ty, to_ty) => write!(
                 f,
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index a49dc105498..3eec58251a0 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -182,7 +182,7 @@ pub struct CommonLifetimes<'tcx> {
 }
 
 pub struct CommonConsts<'tcx> {
-    pub err: &'tcx Const<'tcx>,
+    pub unit: &'tcx Const<'tcx>,
 }
 
 pub struct LocalTableInContext<'a, V> {
@@ -410,8 +410,8 @@ pub struct TypeckTables<'tcx> {
     pub used_trait_imports: Lrc<DefIdSet>,
 
     /// If any errors occurred while type-checking this body,
-    /// this field will be set to `true`.
-    pub tainted_by_errors: bool,
+    /// this field will be set to `Some(ErrorReported)`.
+    pub tainted_by_errors: Option<ErrorReported>,
 
     /// All the opaque types that are restricted to concrete types
     /// by this function.
@@ -447,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
             fru_field_types: Default::default(),
             coercion_casts: Default::default(),
             used_trait_imports: Lrc::new(Default::default()),
-            tainted_by_errors: false,
+            tainted_by_errors: None,
             concrete_opaque_types: Default::default(),
             upvar_list: Default::default(),
             generator_interior_types: Default::default(),
@@ -858,9 +858,9 @@ impl<'tcx> CommonConsts<'tcx> {
         let mk_const = |c| interners.const_.intern(c, |c| Interned(interners.arena.alloc(c))).0;
 
         CommonConsts {
-            err: mk_const(ty::Const {
+            unit: mk_const(ty::Const {
                 val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::zst())),
-                ty: types.err,
+                ty: types.unit,
             }),
         }
     }
diff --git a/src/librustc_middle/ty/flags.rs b/src/librustc_middle/ty/flags.rs
index 172f6d4608b..a88f3628109 100644
--- a/src/librustc_middle/ty/flags.rs
+++ b/src/librustc_middle/ty/flags.rs
@@ -70,14 +70,7 @@ impl FlagComputation {
             | &ty::Str
             | &ty::Foreign(..) => {}
 
-            // You might think that we could just return Error for
-            // any type containing Error as a component, and get
-            // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
-            // the exception of function types that return bot).
-            // But doing so caused sporadic memory corruption, and
-            // neither I (tjc) nor nmatsakis could figure out why,
-            // so we're doing it this way.
-            &ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR),
+            &ty::Error => self.add_flags(TypeFlags::HAS_ERROR),
 
             &ty::Param(_) => {
                 self.add_flags(TypeFlags::HAS_TY_PARAM);
@@ -239,6 +232,7 @@ impl FlagComputation {
                 self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
             }
             ty::ConstKind::Value(_) => {}
+            ty::ConstKind::Error => self.add_flags(TypeFlags::HAS_ERROR),
         }
     }
 
diff --git a/src/librustc_middle/ty/fold.rs b/src/librustc_middle/ty/fold.rs
index d144e507691..248dd00ef47 100644
--- a/src/librustc_middle/ty/fold.rs
+++ b/src/librustc_middle/ty/fold.rs
@@ -82,7 +82,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
         self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
     }
     fn references_error(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_TY_ERR)
+        self.has_type_flags(TypeFlags::HAS_ERROR)
     }
     fn has_param_types_or_consts(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 430ff67d56b..9f095847099 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sorted_map::SortedIndexMultiMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{self, par_iter, ParallelIterator};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
@@ -567,8 +568,8 @@ bitflags! {
                                           | TypeFlags::HAS_TY_OPAQUE.bits
                                           | TypeFlags::HAS_CT_PROJECTION.bits;
 
-        /// Is an error type reachable?
-        const HAS_TY_ERR                  = 1 << 13;
+        /// Is an error type/const reachable?
+        const HAS_ERROR                   = 1 << 13;
 
         /// Does this have any region that "appears free" in the type?
         /// Basically anything but [ReLateBound] and [ReErased].
@@ -2388,7 +2389,7 @@ impl<'tcx> AdtDef {
                     None
                 }
             }
-            Err(ErrorHandled::Reported) => {
+            Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {
                 if !expr_did.is_local() {
                     span_bug!(
                         tcx.def_span(expr_did),
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index a8b7b6a4b97..2aa849f89c4 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -938,6 +938,7 @@ pub trait PrettyPrinter<'tcx>:
                 self.pretty_print_bound_var(debruijn, bound_var)?
             }
             ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
+            ty::ConstKind::Error => p!(write("[const error]")),
         };
         Ok(self)
     }
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs
index 4d668e6ee59..f4f0b6c41b9 100644
--- a/src/librustc_middle/ty/relate.rs
+++ b/src/librustc_middle/ty/relate.rs
@@ -510,12 +510,21 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
     let tcx = relation.tcx();
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
+        // FIXME(eddyb) this doesn't account for lifetime inference variables
+        // being erased by `eval`, *nor* for the polymorphic aspect of `eval`.
+        // That is, we could always use `eval` and it will just return the
+        // old value back if it doesn't succeed.
         if !x.val.needs_infer() {
             return x.eval(tcx, relation.param_env()).val;
         }
         x.val
     };
 
+    // FIXME(eddyb) doesn't look like everything below checks that `a.ty == b.ty`.
+    // We could probably always assert it early, as `const` generic parameters
+    // are not allowed to depend on other generic parameters, i.e. are concrete.
+    // (although there could be normalization differences)
+
     // Currently, the values that can be unified are primitive types,
     // and those that derive both `PartialEq` and `Eq`, corresponding
     // to structural-match types.
@@ -524,6 +533,9 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
             // The caller should handle these cases!
             bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
         }
+
+        (ty::ConstKind::Error, _) | (_, ty::ConstKind::Error) => Ok(ty::ConstKind::Error),
+
         (ty::ConstKind::Param(a_p), ty::ConstKind::Param(b_p)) if a_p.index == b_p.index => {
             return Ok(a);
         }
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index 0ac4466d34f..1c0ffe12314 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -1022,9 +1022,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
             ty::ConstKind::Unevaluated(did, substs, promoted) => {
                 ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted)
             }
-            ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) => {
-                *self
-            }
+            ty::ConstKind::Value(_)
+            | ty::ConstKind::Bound(..)
+            | ty::ConstKind::Placeholder(..)
+            | ty::ConstKind::Error => *self,
         }
     }
 
@@ -1033,9 +1034,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
             ty::ConstKind::Infer(ic) => ic.visit_with(visitor),
             ty::ConstKind::Param(p) => p.visit_with(visitor),
             ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor),
-            ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
-                false
-            }
+            ty::ConstKind::Value(_)
+            | ty::ConstKind::Bound(..)
+            | ty::ConstKind::Placeholder(_)
+            | ty::ConstKind::Error => false,
         }
     }
 }
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 248a2095d0a..c80d4fb99b5 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -18,6 +18,7 @@ use crate::ty::{List, ParamEnv, ParamEnvAnd, TyS};
 use polonius_engine::Atom;
 use rustc_ast::ast::{self, Ident};
 use rustc_data_structures::captures::Captures;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::vec::Idx;
@@ -2340,6 +2341,8 @@ impl<'tcx> Const<'tcx> {
     /// unevaluated constant.
     pub fn eval(&self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> &Const<'tcx> {
         if let ConstKind::Unevaluated(did, substs, promoted) = self.val {
+            use crate::mir::interpret::ErrorHandled;
+
             let param_env_and_substs = param_env.with_reveal_all().and(substs);
 
             // HACK(eddyb) this erases lifetimes even though `const_eval_resolve`
@@ -2369,8 +2372,10 @@ impl<'tcx> Const<'tcx> {
                 // (which may be identity substs, see above),
                 // can leak through `val` into the const we return.
                 Ok(val) => Const::from_value(tcx, val, self.ty),
-
-                Err(_) => self,
+                Err(ErrorHandled::TooGeneric | ErrorHandled::Linted) => self,
+                Err(ErrorHandled::Reported(ErrorReported)) => {
+                    tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: self.ty })
+                }
             }
         } else {
             self
@@ -2429,6 +2434,10 @@ pub enum ConstKind<'tcx> {
 
     /// Used to hold computed value.
     Value(ConstValue<'tcx>),
+
+    /// A placeholder for a const which could not be computed; this is
+    /// propagated to avoid useless error messages.
+    Error,
 }
 
 #[cfg(target_arch = "x86_64")]
diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs
index c7a317f39ad..b6cadd00996 100644
--- a/src/librustc_middle/ty/walk.rs
+++ b/src/librustc_middle/ty/walk.rs
@@ -170,7 +170,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
                 | ty::ConstKind::Param(_)
                 | ty::ConstKind::Placeholder(_)
                 | ty::ConstKind::Bound(..)
-                | ty::ConstKind::Value(_) => {}
+                | ty::ConstKind::Value(_)
+                | ty::ConstKind::Error => {}
 
                 ty::ConstKind::Unevaluated(_, substs, _) => {
                     stack.extend(substs.iter().copied().rev());
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 6aefd86c49a..d525e7fe46f 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -3,7 +3,7 @@
 use rustc_ast::ast::Name;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
+use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::{def_id::DefId, HirId, Node};
 use rustc_index::bit_set::BitSet;
@@ -135,7 +135,7 @@ fn do_mir_borrowck<'a, 'tcx>(
 
     // Gather the upvars of a closure, if any.
     let tables = tcx.typeck_tables_of(def_id);
-    if tables.tainted_by_errors {
+    if let Some(ErrorReported) = tables.tainted_by_errors {
         infcx.set_tainted_by_errors();
     }
     let upvars: Vec<_> = tables
diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs
index 3f0774767fd..8cb0ea91bc2 100644
--- a/src/librustc_mir/const_eval/eval_queries.rs
+++ b/src/librustc_mir/const_eval/eval_queries.rs
@@ -213,13 +213,10 @@ fn validate_and_turn_into_const<'tcx>(
 
     val.map_err(|error| {
         let err = error_to_const_error(&ecx, error);
-        match err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
+        err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
             diag.note(note_on_undefined_behavior_error());
             diag.emit();
-        }) {
-            Ok(_) => ErrorHandled::Reported,
-            Err(err) => err,
-        }
+        })
     })
 }
 
@@ -292,11 +289,10 @@ pub fn const_eval_raw_provider<'tcx>(
     let cid = key.value;
     let def_id = cid.instance.def.def_id();
 
-    if def_id.is_local()
-        && tcx.has_typeck_tables(def_id)
-        && tcx.typeck_tables_of(def_id).tainted_by_errors
-    {
-        return Err(ErrorHandled::Reported);
+    if def_id.is_local() && tcx.has_typeck_tables(def_id) {
+        if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors {
+            return Err(ErrorHandled::Reported(error_reported));
+        }
     }
 
     let is_static = tcx.is_static(def_id);
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index f111eecb945..fcbb2535797 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -400,11 +400,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, mir::ReadOnlyBodyAndCache<'tcx, 'tcx>> {
         // do not continue if typeck errors occurred (can only occur in local crate)
         let did = instance.def_id();
-        if did.is_local()
-            && self.tcx.has_typeck_tables(did)
-            && self.tcx.typeck_tables_of(did).tainted_by_errors
-        {
-            throw_inval!(TypeckError)
+        if did.is_local() && self.tcx.has_typeck_tables(did) {
+            if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors {
+                throw_inval!(TypeckError(error_reported))
+            }
         }
         trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
         if let Some(promoted) = promoted {
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index af415b3837f..480415676f6 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -5,6 +5,7 @@
 
 use super::validity::RefTracking;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_middle::mir::interpret::{ErrorHandled, InterpResult};
 use rustc_middle::ty::{self, Ty};
@@ -337,7 +338,9 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
                         diag.emit();
                     },
                 ) {
-                    Ok(()) | Err(ErrorHandled::TooGeneric) | Err(ErrorHandled::Reported) => {}
+                    ErrorHandled::TooGeneric
+                    | ErrorHandled::Reported(ErrorReported)
+                    | ErrorHandled::Linted => {}
                 }
             }
         }
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index bcad7855c37..efc43afd0f0 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -18,8 +18,8 @@ use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
 use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};
 
 use super::{
-    AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc,
-    GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
+    AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId,
+    InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
 };
 use crate::util::pretty;
 
@@ -462,10 +462,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                         // no need to report anything, the const_eval call takes care of that
                         // for statics
                         assert!(tcx.is_static(def_id));
-                        match err {
-                            ErrorHandled::Reported => err_inval!(ReferencedConstant),
-                            ErrorHandled::TooGeneric => err_inval!(TooGeneric),
-                        }
+                        err
                     })?;
                 // Make sure we use the ID of the resolved memory, not the lazy one!
                 let id = raw_const.alloc_id;
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 893f4c1db7e..2317a1fea07 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -4,6 +4,7 @@
 use std::convert::TryFrom;
 use std::fmt::Write;
 
+use rustc_errors::ErrorReported;
 use rustc_hir::def::Namespace;
 use rustc_macros::HashStable;
 use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
@@ -518,6 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // Early-return cases.
         let val_val = match val.val {
             ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
+            ty::ConstKind::Error => throw_inval!(TypeckError(ErrorReported)),
             ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
                 let instance = self.resolve(def_id, substs)?;
                 // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index ebed96c758d..32d28bb0d13 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -178,6 +178,7 @@ use crate::monomorphize;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
@@ -602,7 +603,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
             ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
                 match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) {
                     Ok(val) => collect_const_value(self.tcx, val, self.output),
-                    Err(ErrorHandled::Reported) => {}
+                    Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
                     Err(ErrorHandled::TooGeneric) => span_bug!(
                         self.tcx.def_span(def_id),
                         "collection encountered polymorphic constant",
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index 04cb509d44e..6911c09c518 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -3,6 +3,7 @@ use crate::build::scope::DropKind;
 use crate::hair::cx::Cx;
 use crate::hair::{BindingMode, LintLevel, PatKind};
 use rustc_attr::{self as attr, UnwindAttr};
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items;
@@ -59,7 +60,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
 
     tcx.infer_ctxt().enter(|infcx| {
         let cx = Cx::new(&infcx, id);
-        let body = if cx.tables().tainted_by_errors {
+        let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors {
             build::construct_error(cx, body_id)
         } else if cx.body_owner_kind.is_fn_or_closure() {
             // fetch the fully liberated fn signature (that is, all bound
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index d2d99cf030d..21d632b9f6b 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
 };
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
+use rustc_middle::ty::{self, AdtKind, Ty};
 use rustc_span::Span;
 
 impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> {
@@ -718,7 +718,8 @@ fn convert_path_expr<'a, 'tcx>(
 
         Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
             let user_provided_types = cx.tables.user_provided_types();
-            let user_ty = user_provided_types.get(expr.hir_id).copied();
+            let user_provided_type = user_provided_types.get(expr.hir_id).copied();
+            debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
             let ty = cx.tables().node_type(expr.hir_id);
             match ty.kind {
                 // A unit struct/variant which is used as a value.
@@ -727,17 +728,10 @@ fn convert_path_expr<'a, 'tcx>(
                     adt_def,
                     variant_index: adt_def.variant_index_with_ctor_id(def_id),
                     substs,
-                    user_ty,
+                    user_ty: user_provided_type,
                     fields: vec![],
                     base: None,
                 },
-                _ if ty.references_error() => {
-                    // Handle degenerate input without ICE (#67377).
-                    ExprKind::Literal {
-                        literal: ty::Const::zero_sized(cx.tcx, cx.tcx.types.err),
-                        user_ty: None,
-                    }
-                }
                 _ => bug!("unexpected ty: {:?}", ty),
             }
         }
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index 0cb26e08228..f67b8b87ced 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -972,7 +972,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
                             )
                             .emit();
 
-                        self.tcx().consts.err
+                        self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
                     }
                 }
             }
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 144812e3923..8a9017960fb 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -12,7 +12,7 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::{Node, QPath, TyKind, WhereBoundPredicate, WherePredicate};
@@ -674,8 +674,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             }
 
             // Already reported in the query.
-            ConstEvalFailure(ErrorHandled::Reported) => {
-                self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
+            ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => {
+                // FIXME(eddyb) remove this once `ErrorReported` becomes a proof token.
+                self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error");
+                return;
+            }
+
+            // Already reported in the query, but only as a lint.
+            // This shouldn't actually happen for constants used in types, modulo
+            // bugs. The `delay_span_bug` here ensures it won't be ignored.
+            ConstEvalFailure(ErrorHandled::Linted) => {
+                self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
                 return;
             }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 87e5baa57e9..4a8cd9e91e2 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -826,14 +826,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         }
                     }
                     GenericParamDefKind::Const => {
+                        let ty = tcx.at(span).type_of(param.def_id);
                         // FIXME(const_generics:defaults)
                         if infer_args {
                             // No const parameters were provided, we can infer all.
-                            let ty = tcx.at(span).type_of(param.def_id);
                             self.ct_infer(ty, Some(param), span).into()
                         } else {
                             // We've already errored above about the mismatch.
-                            tcx.consts.err.into()
+                            tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty }).into()
                         }
                     }
                 }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 31d147b460f..7b66743b098 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -5,6 +5,7 @@
 use crate::check::FnCtxt;
 
 use rustc_data_structures::sync::Lrc;
+use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefIdSet;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -75,7 +76,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.tables.upvar_list =
             mem::replace(&mut self.tables.borrow_mut().upvar_list, Default::default());
 
-        wbcx.tables.tainted_by_errors |= self.is_tainted_by_errors();
+        if self.is_tainted_by_errors() {
+            // FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted.
+            wbcx.tables.tainted_by_errors = Some(ErrorReported);
+        }
 
         debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables);
 
@@ -591,7 +595,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         // We may have introduced e.g. `ty::Error`, if inference failed, make sure
         // to mark the `TypeckTables` as tainted in that case, so that downstream
         // users of the tables don't produce extra errors, or worse, ICEs.
-        self.tables.tainted_by_errors |= resolver.replaced_with_error;
+        if resolver.replaced_with_error {
+            // FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted.
+            self.tables.tainted_by_errors = Some(ErrorReported);
+        }
 
         x
     }
@@ -673,7 +680,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
                 // FIXME: we'd like to use `self.report_error`, but it doesn't yet
                 // accept a &'tcx ty::Const.
                 self.replaced_with_error = true;
-                self.tcx().consts.err
+                self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty: ct.ty })
             }
         }
     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index a327951b3b0..7794f62efb7 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -316,13 +316,13 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
 
     fn ct_infer(
         &self,
-        _: Ty<'tcx>,
+        ty: Ty<'tcx>,
         _: Option<&ty::GenericParamDef>,
         span: Span,
     ) -> &'tcx Const<'tcx> {
         bad_placeholder_type(self.tcx(), vec![span]).emit();
 
-        self.tcx().consts.err
+        self.tcx().mk_const(ty::Const { val: ty::ConstKind::Error, ty })
     }
 
     fn projected_ty_from_poly_trait_ref(
@@ -2037,7 +2037,8 @@ fn associated_item_predicates(
             }
             ty::GenericParamDefKind::Const => {
                 unimplemented_error("const");
-                tcx.consts.err.into()
+                tcx.mk_const(ty::Const { val: ty::ConstKind::Error, ty: tcx.type_of(param.def_id) })
+                    .into()
             }
         }
     };
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index 985f66694b6..e17b736058f 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -1,5 +1,5 @@
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_err, Applicability, StashKey};
+use rustc_errors::{struct_span_err, Applicability, ErrorReported, StashKey};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
@@ -125,7 +125,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                                     owner, def_id,
                                 ),
                             );
-                            if tcx.typeck_tables_of(owner).tainted_by_errors {
+                            if let Some(ErrorReported) =
+                                tcx.typeck_tables_of(owner).tainted_by_errors
+                            {
                                 // Some error in the
                                 // owner fn prevented us from populating
                                 // the `concrete_opaque_types` table.
diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs
index 959f4a2babb..60589f7c264 100644
--- a/src/test/ui/array-break-length.rs
+++ b/src/test/ui/array-break-length.rs
@@ -1,11 +1,9 @@
 fn main() {
     loop {
         |_: [_; break]| {} //~ ERROR: `break` outside of a loop
-        //~^ ERROR mismatched types
     }
 
     loop {
         |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop
-        //~^ ERROR mismatched types
     }
 }
diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr
index 69c7599cce1..93f1c238bcc 100644
--- a/src/test/ui/array-break-length.stderr
+++ b/src/test/ui/array-break-length.stderr
@@ -5,30 +5,11 @@ LL |         |_: [_; break]| {}
    |                 ^^^^^ cannot `break` outside of a loop
 
 error[E0268]: `continue` outside of a loop
-  --> $DIR/array-break-length.rs:8:17
+  --> $DIR/array-break-length.rs:7:17
    |
 LL |         |_: [_; continue]| {}
    |                 ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0308]: mismatched types
-  --> $DIR/array-break-length.rs:3:9
-   |
-LL |         |_: [_; break]| {}
-   |         ^^^^^^^^^^^^^^^^^^ expected `()`, found closure
-   |
-   = note: expected unit type `()`
-                found closure `[closure@$DIR/array-break-length.rs:3:9: 3:27]`
-
-error[E0308]: mismatched types
-  --> $DIR/array-break-length.rs:8:9
-   |
-LL |         |_: [_; continue]| {}
-   |         ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure
-   |
-   = note: expected unit type `()`
-                found closure `[closure@$DIR/array-break-length.rs:8:9: 8:30]`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0268, E0308.
-For more information about an error, try `rustc --explain E0268`.
+For more information about this error, try `rustc --explain E0268`.
diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs
index f3567db1fac..fda590fda02 100644
--- a/src/test/ui/closures/closure-array-break-length.rs
+++ b/src/test/ui/closures/closure-array-break-length.rs
@@ -2,8 +2,6 @@ fn main() {
     |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop
 
     while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop
-    //~^ ERROR mismatched types
 
     while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop
-    //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr
index f6991a23f4d..2b8ab9bfc44 100644
--- a/src/test/ui/closures/closure-array-break-length.stderr
+++ b/src/test/ui/closures/closure-array-break-length.stderr
@@ -11,30 +11,11 @@ LL |     while |_: [_; continue]| {} {}
    |                   ^^^^^^^^ cannot `continue` outside of a loop
 
 error[E0268]: `break` outside of a loop
-  --> $DIR/closure-array-break-length.rs:7:19
+  --> $DIR/closure-array-break-length.rs:6:19
    |
 LL |     while |_: [_; break]| {} {}
    |                   ^^^^^ cannot `break` outside of a loop
 
-error[E0308]: mismatched types
-  --> $DIR/closure-array-break-length.rs:4:11
-   |
-LL |     while |_: [_; continue]| {} {}
-   |           ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found closure
-   |
-   = note: expected type `bool`
-           found closure `[closure@$DIR/closure-array-break-length.rs:4:11: 4:32]`
-
-error[E0308]: mismatched types
-  --> $DIR/closure-array-break-length.rs:7:11
-   |
-LL |     while |_: [_; break]| {} {}
-   |           ^^^^^^^^^^^^^^^^^^ expected `bool`, found closure
-   |
-   = note: expected type `bool`
-           found closure `[closure@$DIR/closure-array-break-length.rs:7:11: 7:29]`
-
-error: aborting due to 5 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0268, E0308.
-For more information about an error, try `rustc --explain E0268`.
+For more information about this error, try `rustc --explain E0268`.
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs
index 3ae55ebdbaf..6fd8e9cbc80 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.rs
@@ -19,7 +19,6 @@ const A_I8_I
     : [u32; (i8::MAX as usize) + 1]
     = [0; (i8::MAX + 1) as usize];
 //~^ ERROR evaluation of constant value failed
-//~| ERROR mismatched types
 
 fn main() {
     foo(&A_I8_I[..]);
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr
index 94b7c12fc1a..2c5b4607aa4 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3.stderr
@@ -4,16 +4,6 @@ error[E0080]: evaluation of constant value failed
 LL |     = [0; (i8::MAX + 1) as usize];
    |           ^^^^^^^^^^^^^ attempt to add with overflow
 
-error[E0308]: mismatched types
-  --> $DIR/const-eval-overflow-3.rs:20:7
-   |
-LL |     = [0; (i8::MAX + 1) as usize];
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1) as usize`
-   |
-   = note: expected array `[u32; 128]`
-              found array `[u32; _]`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0308.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs
index e7b88e00feb..db6f17a671a 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.rs
@@ -18,7 +18,6 @@ const A_I8_I
     = [0; (i8::MAX + 1u8) as usize];
 //~^ ERROR mismatched types
 //~| ERROR cannot add `u8` to `i8`
-//~| ERROR mismatched types
 
 fn main() {
     foo(&A_I8_I[..]);
diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
index aebe4feef8d..3da34fe9af7 100644
--- a/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
+++ b/src/test/ui/consts/const-eval/const-eval-overflow-3b.stderr
@@ -12,16 +12,7 @@ LL |     = [0; (i8::MAX + 1u8) as usize];
    |
    = help: the trait `std::ops::Add<u8>` is not implemented for `i8`
 
-error[E0308]: mismatched types
-  --> $DIR/const-eval-overflow-3b.rs:18:7
-   |
-LL |     = [0; (i8::MAX + 1u8) as usize];
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `128usize`, found `(i8::MAX + 1u8) as usize`
-   |
-   = note: expected array `[u32; 128]`
-              found array `[u32; _]`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs
index 5cfe36f57e6..80494d16629 100644
--- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs
+++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs
@@ -2,7 +2,7 @@ fn main() {
     // Make sure match uses the usual pointer comparison code path -- i.e., it should complain
     // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw
     // bytes.
-    let _: [u8; 0] = [4; { //~ ERROR mismatched types
+    let _: [u8; 0] = [4; {
         match &1 as *const i32 as usize {
             //~^ ERROR casting pointers to integers in constants
             //~| ERROR `match` is not allowed in a `const`
diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr
index 7c4da5e7d86..b47f6d5f845 100644
--- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr
+++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr
@@ -28,30 +28,7 @@ error[E0080]: evaluation of constant value failed
 LL |         match &1 as *const i32 as usize {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
 
-error[E0308]: mismatched types
-  --> $DIR/match-test-ptr-null.rs:5:22
-   |
-LL |       let _: [u8; 0] = [4; {
-   |  ____________-------___^
-   | |            |
-   | |            expected due to this
-LL | |         match &1 as *const i32 as usize {
-LL | |
-LL | |
-...  |
-LL | |         }
-LL | |     }];
-   | |______^ expected `0usize`, found `{
-        match &1 as *const i32 as usize {
-            0 => 42,
-            n => n,
-        }
-    }`
-   |
-   = note: expected array `[u8; 0]`
-              found array `[u8; _]`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0080, E0308, E0658.
+Some errors have detailed explanations: E0080, E0658.
 For more information about an error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-integer-bool-ops.rs b/src/test/ui/consts/const-integer-bool-ops.rs
index 6924956bdf7..35915a7a606 100644
--- a/src/test/ui/consts/const-integer-bool-ops.rs
+++ b/src/test/ui/consts/const-integer-bool-ops.rs
@@ -6,7 +6,6 @@ const X: usize = 42 && 39;
 //~| ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARR: [i32; X] = [99; 34];
-//~^ ERROR evaluation of constant value failed
 
 const X1: usize = 42 || 39;
 //~^ ERROR mismatched types
@@ -16,7 +15,6 @@ const X1: usize = 42 || 39;
 //~| ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARR1: [i32; X1] = [99; 47];
-//~^ ERROR evaluation of constant value failed
 
 const X2: usize = -42 || -39;
 //~^ ERROR mismatched types
@@ -26,7 +24,6 @@ const X2: usize = -42 || -39;
 //~| ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARR2: [i32; X2] = [99; 18446744073709551607];
-//~^ ERROR evaluation of constant value failed
 
 const X3: usize = -42 && -39;
 //~^ ERROR mismatched types
@@ -36,43 +33,36 @@ const X3: usize = -42 && -39;
 //~| ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARR3: [i32; X3] = [99; 6];
-//~^ ERROR evaluation of constant value failed
 
 const Y: usize = 42.0 == 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR: [i32; Y] = [99; 1];
-//~^ ERROR evaluation of constant value failed
 
 const Y1: usize = 42.0 >= 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR1: [i32; Y1] = [99; 1];
-//~^ ERROR evaluation of constant value failed
 
 const Y2: usize = 42.0 <= 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR2: [i32; Y2] = [99; 1];
-//~^ ERROR evaluation of constant value failed
 
 const Y3: usize = 42.0 > 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR3: [i32; Y3] = [99; 0];
-//~^ ERROR evaluation of constant value failed
 
 const Y4: usize = 42.0 < 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR4: [i32; Y4] = [99; 0];
-//~^ ERROR evaluation of constant value failed
 
 const Y5: usize = 42.0 != 42.0;
 //~^ ERROR mismatched types
 //~| expected `usize`, found `bool`
 const ARRR5: [i32; Y5] = [99; 0];
-//~^ ERROR evaluation of constant value failed
 
 fn main() {
     let _ = ARR;
diff --git a/src/test/ui/consts/const-integer-bool-ops.stderr b/src/test/ui/consts/const-integer-bool-ops.stderr
index 9001fefd102..4e503e5a5c0 100644
--- a/src/test/ui/consts/const-integer-bool-ops.stderr
+++ b/src/test/ui/consts/const-integer-bool-ops.stderr
@@ -16,157 +16,96 @@ error[E0308]: mismatched types
 LL | const X: usize = 42 && 39;
    |                  ^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:8:18
-   |
-LL | const ARR: [i32; X] = [99; 34];
-   |                  ^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:11:19
+  --> $DIR/const-integer-bool-ops.rs:10:19
    |
 LL | const X1: usize = 42 || 39;
    |                   ^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:11:25
+  --> $DIR/const-integer-bool-ops.rs:10:25
    |
 LL | const X1: usize = 42 || 39;
    |                         ^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:11:19
+  --> $DIR/const-integer-bool-ops.rs:10:19
    |
 LL | const X1: usize = 42 || 39;
    |                   ^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:18:19
-   |
-LL | const ARR1: [i32; X1] = [99; 47];
-   |                   ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:21:19
+  --> $DIR/const-integer-bool-ops.rs:19:19
    |
 LL | const X2: usize = -42 || -39;
    |                   ^^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:21:26
+  --> $DIR/const-integer-bool-ops.rs:19:26
    |
 LL | const X2: usize = -42 || -39;
    |                          ^^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:21:19
+  --> $DIR/const-integer-bool-ops.rs:19:19
    |
 LL | const X2: usize = -42 || -39;
    |                   ^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:28:19
-   |
-LL | const ARR2: [i32; X2] = [99; 18446744073709551607];
-   |                   ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:31:19
+  --> $DIR/const-integer-bool-ops.rs:28:19
    |
 LL | const X3: usize = -42 && -39;
    |                   ^^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:31:26
+  --> $DIR/const-integer-bool-ops.rs:28:26
    |
 LL | const X3: usize = -42 && -39;
    |                          ^^^ expected `bool`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:31:19
+  --> $DIR/const-integer-bool-ops.rs:28:19
    |
 LL | const X3: usize = -42 && -39;
    |                   ^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:38:19
-   |
-LL | const ARR3: [i32; X3] = [99; 6];
-   |                   ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:41:18
+  --> $DIR/const-integer-bool-ops.rs:37:18
    |
 LL | const Y: usize = 42.0 == 42.0;
    |                  ^^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:44:19
-   |
-LL | const ARRR: [i32; Y] = [99; 1];
-   |                   ^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:47:19
+  --> $DIR/const-integer-bool-ops.rs:42:19
    |
 LL | const Y1: usize = 42.0 >= 42.0;
    |                   ^^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:50:20
-   |
-LL | const ARRR1: [i32; Y1] = [99; 1];
-   |                    ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:53:19
+  --> $DIR/const-integer-bool-ops.rs:47:19
    |
 LL | const Y2: usize = 42.0 <= 42.0;
    |                   ^^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:56:20
-   |
-LL | const ARRR2: [i32; Y2] = [99; 1];
-   |                    ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:59:19
+  --> $DIR/const-integer-bool-ops.rs:52:19
    |
 LL | const Y3: usize = 42.0 > 42.0;
    |                   ^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:62:20
-   |
-LL | const ARRR3: [i32; Y3] = [99; 0];
-   |                    ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:65:19
+  --> $DIR/const-integer-bool-ops.rs:57:19
    |
 LL | const Y4: usize = 42.0 < 42.0;
    |                   ^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:68:20
-   |
-LL | const ARRR4: [i32; Y4] = [99; 0];
-   |                    ^^ referenced constant has errors
-
 error[E0308]: mismatched types
-  --> $DIR/const-integer-bool-ops.rs:71:19
+  --> $DIR/const-integer-bool-ops.rs:62:19
    |
 LL | const Y5: usize = 42.0 != 42.0;
    |                   ^^^^^^^^^^^^ expected `usize`, found `bool`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-integer-bool-ops.rs:74:20
-   |
-LL | const ARRR5: [i32; Y5] = [99; 0];
-   |                    ^^ referenced constant has errors
-
-error: aborting due to 28 previous errors
+error: aborting due to 18 previous errors
 
-Some errors have detailed explanations: E0080, E0308.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/consts/const-tup-index-span.rs b/src/test/ui/consts/const-tup-index-span.rs
index 763263c6aeb..8057d64369a 100644
--- a/src/test/ui/consts/const-tup-index-span.rs
+++ b/src/test/ui/consts/const-tup-index-span.rs
@@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64;
 //~^ ERROR mismatched types
 //~| expected tuple, found `usize`
 const ARR: [i32; TUP.0] = [];
-//~^ ERROR evaluation of constant value failed
 
 fn main() {
 }
diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr
index 8e4a092e40f..6724984d8d7 100644
--- a/src/test/ui/consts/const-tup-index-span.stderr
+++ b/src/test/ui/consts/const-tup-index-span.stderr
@@ -7,13 +7,6 @@ LL | const TUP: (usize,) = 5usize << 64;
    = note: expected tuple `(usize,)`
                found type `usize`
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/const-tup-index-span.rs:6:18
-   |
-LL | const ARR: [i32; TUP.0] = [];
-   |                  ^^^ referenced constant has errors
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0308.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issues/issue-39559-2.rs b/src/test/ui/issues/issue-39559-2.rs
index ec0275b2d6c..3a52e4d6216 100644
--- a/src/test/ui/issues/issue-39559-2.rs
+++ b/src/test/ui/issues/issue-39559-2.rs
@@ -17,5 +17,4 @@ fn main() {
         = [0; Dim3::dim()];
         //~^ ERROR E0015
         //~| ERROR E0080
-        //~| ERROR mismatched types
 }
diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/issues/issue-39559-2.stderr
index 7cbf63c2da0..586debbbe53 100644
--- a/src/test/ui/issues/issue-39559-2.stderr
+++ b/src/test/ui/issues/issue-39559-2.stderr
@@ -22,19 +22,7 @@ error[E0080]: evaluation of constant value failed
 LL |         = [0; Dim3::dim()];
    |               ^^^^^^^^^^^ calling non-const function `<Dim3 as Dim>::dim`
 
-error[E0308]: mismatched types
-  --> $DIR/issue-39559-2.rs:17:11
-   |
-LL |     let array: [usize; Dim3::dim()]
-   |                -------------------- expected due to this
-...
-LL |         = [0; Dim3::dim()];
-   |           ^^^^^^^^^^^^^^^^ expected `Dim3::dim()`, found `Dim3::dim()`
-   |
-   = note: expected array `[usize; _]`
-              found array `[usize; _]`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0015, E0080, E0308.
+Some errors have detailed explanations: E0015, E0080.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/src/test/ui/issues/issue-41394.rs b/src/test/ui/issues/issue-41394.rs
index 64873ac35a0..06a33081340 100644
--- a/src/test/ui/issues/issue-41394.rs
+++ b/src/test/ui/issues/issue-41394.rs
@@ -5,7 +5,6 @@ enum Foo {
 
 enum Bar {
     A = Foo::A as isize
-    //~^ ERROR evaluation of constant value failed
 }
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-41394.stderr b/src/test/ui/issues/issue-41394.stderr
index 47a24547d45..fa95ca9c18a 100644
--- a/src/test/ui/issues/issue-41394.stderr
+++ b/src/test/ui/issues/issue-41394.stderr
@@ -6,13 +6,6 @@ LL |     A = "" + 1
    |         |
    |         &str
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-41394.rs:7:9
-   |
-LL |     A = Foo::A as isize
-   |         ^^^^^^^^^^^^^^^ referenced constant has errors
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0369.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/issues/issue-50599.rs b/src/test/ui/issues/issue-50599.rs
index 78a20cf8ebb..00588735b9a 100644
--- a/src/test/ui/issues/issue-50599.rs
+++ b/src/test/ui/issues/issue-50599.rs
@@ -2,5 +2,4 @@ fn main() {
     const N: u32 = 1_000;
     const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value
     let mut digits = [0u32; M];
-    //~^ ERROR evaluation of constant value failed
 }
diff --git a/src/test/ui/issues/issue-50599.stderr b/src/test/ui/issues/issue-50599.stderr
index 5c8cac44438..378c57011ac 100644
--- a/src/test/ui/issues/issue-50599.stderr
+++ b/src/test/ui/issues/issue-50599.stderr
@@ -11,13 +11,6 @@ LL | use std::f32::consts::LOG10_2;
 LL | use std::f64::consts::LOG10_2;
    |
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/issue-50599.rs:4:29
-   |
-LL |     let mut digits = [0u32; M];
-   |                             ^ referenced constant has errors
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0425.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/issues/issue-52060.rs b/src/test/ui/issues/issue-52060.rs
index 2688049fcc9..fed08902c8b 100644
--- a/src/test/ui/issues/issue-52060.rs
+++ b/src/test/ui/issues/issue-52060.rs
@@ -4,6 +4,5 @@ static A: &'static [u32] = &[1];
 static B: [u32; 1] = [0; A.len()];
 //~^ ERROR [E0013]
 //~| ERROR evaluation of constant value failed
-//~| ERROR mismatched types
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-52060.stderr b/src/test/ui/issues/issue-52060.stderr
index e076e183937..502825e9766 100644
--- a/src/test/ui/issues/issue-52060.stderr
+++ b/src/test/ui/issues/issue-52060.stderr
@@ -12,16 +12,7 @@ error[E0080]: evaluation of constant value failed
 LL | static B: [u32; 1] = [0; A.len()];
    |                          ^ constant accesses static
 
-error[E0308]: mismatched types
-  --> $DIR/issue-52060.rs:4:22
-   |
-LL | static B: [u32; 1] = [0; A.len()];
-   |                      ^^^^^^^^^^^^ expected `1usize`, found `A.len()`
-   |
-   = note: expected array `[u32; 1]`
-              found array `[u32; _]`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0013, E0080, E0308.
+Some errors have detailed explanations: E0013, E0080.
 For more information about an error, try `rustc --explain E0013`.
diff --git a/src/test/ui/issues/issue-54954.rs b/src/test/ui/issues/issue-54954.rs
index 3d6355f5c59..00805eb5dc9 100644
--- a/src/test/ui/issues/issue-54954.rs
+++ b/src/test/ui/issues/issue-54954.rs
@@ -11,8 +11,6 @@ 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 01ed1383ca2..29d439b457f 100644
--- a/src/test/ui/issues/issue-54954.stderr
+++ b/src/test/ui/issues/issue-54954.stderr
@@ -15,19 +15,7 @@ LL |     const fn const_val<T: Sized>() -> usize {
    |
    = note: cannot satisfy `_: Tt`
 
-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 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0080, E0283, E0379.
-For more information about an error, try `rustc --explain E0080`.
+Some errors have detailed explanations: E0283, E0379.
+For more information about an error, try `rustc --explain E0283`.
diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs b/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs
index 708d72a2df7..b6a08351609 100644
--- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs
+++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.rs
@@ -23,8 +23,7 @@ fn h<const N: usize>() {
 fn i<const N: usize>() {
     static a: [u8; N] = [0; N];
     //~^ ERROR can't use generic parameters from outer function
-    //~^^ ERROR can't use generic parameters from outer function
-    //~| ERROR mismatched types
+    //~| ERROR can't use generic parameters from outer function
 }
 
 fn main() {}
diff --git a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
index 18e13d30f76..6076328b12f 100644
--- a/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
+++ b/src/test/ui/resolve/issue-65035-static-with-parent-generics.stderr
@@ -48,16 +48,6 @@ LL | #![feature(const_generics)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0308]: mismatched types
-  --> $DIR/issue-65035-static-with-parent-generics.rs:24:25
-   |
-LL |     static a: [u8; N] = [0; N];
-   |                         ^^^^^^ expected `N`, found `N`
-   |
-   = note: expected array `[u8; _]`
-              found array `[u8; _]`
-
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 5 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0308, E0401.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0401`.
diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs
index a25e3ba5fa8..4b6bc6124db 100644
--- a/src/test/ui/type/type-dependent-def-issue-49241.rs
+++ b/src/test/ui/type/type-dependent-def-issue-49241.rs
@@ -2,6 +2,4 @@ fn main() {
     let v = vec![0];
     const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
     let s: [u32; l] = v.into_iter().collect();
-    //~^ ERROR evaluation of constant value failed
-    //~^^ ERROR a value of type
 }
diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr
index 18a69c50ebd..c5dcfa7a431 100644
--- a/src/test/ui/type/type-dependent-def-issue-49241.stderr
+++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr
@@ -4,21 +4,6 @@ error[E0435]: attempt to use a non-constant value in a constant
 LL |     const l: usize = v.count();
    |                      ^ non-constant value
 
-error[E0080]: evaluation of constant value failed
-  --> $DIR/type-dependent-def-issue-49241.rs:4:18
-   |
-LL |     let s: [u32; l] = v.into_iter().collect();
-   |                  ^ referenced constant has errors
-
-error[E0277]: a value of type `[u32; _]` cannot be built from an iterator over elements of type `{integer}`
-  --> $DIR/type-dependent-def-issue-49241.rs:4:37
-   |
-LL |     let s: [u32; l] = v.into_iter().collect();
-   |                                     ^^^^^^^ value of type `[u32; _]` cannot be built from `std::iter::Iterator<Item={integer}>`
-   |
-   = help: the trait `std::iter::FromIterator<{integer}>` is not implemented for `[u32; _]`
-
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0080, E0277, E0435.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0435`.