about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-06-03 03:01:06 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-06-05 20:49:47 +0200
commit78d48867da5bf64d41883c67580885943c21f1b9 (patch)
tree0d953b9e161dc4c0cbd59b98dfb15e4a6b3e53d0
parent9cb47de81337482b226cde3a2f59594ed78412d1 (diff)
downloadrust-78d48867da5bf64d41883c67580885943c21f1b9.tar.gz
rust-78d48867da5bf64d41883c67580885943c21f1b9.zip
Properly report transitive errors
-rw-r--r--src/librustc/ich/impls_ty.rs11
-rw-r--r--src/librustc/middle/const_val.rs21
-rw-r--r--src/librustc/mir/interpret/error.rs80
-rw-r--r--src/librustc/traits/fulfill.rs3
-rw-r--r--src/librustc/ty/structural_impls.rs9
-rw-r--r--src/librustc_mir/interpret/const_eval.rs3
-rw-r--r--src/librustc_mir/interpret/eval_context.rs12
-rw-r--r--src/librustc_mir/interpret/memory.rs16
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/test/compile-fail/const-err-multi.rs3
-rw-r--r--src/test/ui/const-eval/conditional_array_execution.nll.stderr31
-rw-r--r--src/test/ui/const-eval/conditional_array_execution.rs2
-rw-r--r--src/test/ui/const-eval/conditional_array_execution.stderr20
-rw-r--r--src/test/ui/const-eval/issue-43197.nll.stderr49
-rw-r--r--src/test/ui/const-eval/issue-43197.rs4
-rw-r--r--src/test/ui/const-eval/issue-43197.stderr38
-rw-r--r--src/test/ui/const-eval/issue-44578.nll.stderr22
-rw-r--r--src/test/ui/const-eval/issue-44578.rs1
-rw-r--r--src/test/ui/const-eval/issue-44578.stderr11
-rw-r--r--src/test/ui/const-eval/issue-50814-2.rs1
-rw-r--r--src/test/ui/const-eval/issue-50814-2.stderr11
-rw-r--r--src/test/ui/const-eval/issue-50814.rs1
-rw-r--r--src/test/ui/const-eval/issue-50814.stderr11
-rw-r--r--src/test/ui/const-len-underflow-separate-spans.rs1
-rw-r--r--src/test/ui/const-len-underflow-separate-spans.stderr11
25 files changed, 270 insertions, 104 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index e1e5bc58952..592ada83c85 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -526,19 +526,14 @@ for ::middle::const_val::ErrKind<'gcx> {
         match *self {
             NonConstPath |
             TypeckError |
+            CouldNotResolve |
             CheckMatchError => {
                 // nothing to do
             }
-            UnimplementedConstVal(s) => {
-                s.hash_stable(hcx, hasher);
-            }
             IndexOutOfBounds { len, index } => {
                 len.hash_stable(hcx, hasher);
                 index.hash_stable(hcx, hasher);
             }
-            LayoutError(ref layout_error) => {
-                layout_error.hash_stable(hcx, hasher);
-            }
             Miri(ref err, ref trace) => {
                 err.hash_stable(hcx, hasher);
                 trace.hash_stable(hcx, hasher);
@@ -609,8 +604,8 @@ for ::mir::interpret::EvalErrorKind<'gcx, O> {
             RemainderByZero |
             DivisionByZero |
             GeneratorResumedAfterReturn |
-            GeneratorResumedAfterPanic |
-            ReferencedConstant => {}
+            GeneratorResumedAfterPanic => {}
+            ReferencedConstant(ref err) => err.hash_stable(hcx, hasher),
             MachineError(ref err) => err.hash_stable(hcx, hasher),
             FunctionPointerTyMismatch(a, b) => {
                 a.hash_stable(hcx, hasher);
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index d4ec71bc6c4..d2c6bb28948 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
-use ty::{self, layout};
+use ty;
 use ty::subst::Substs;
 use ty::maps::TyCtxtAt;
 use mir::interpret::ConstValue;
@@ -30,27 +30,25 @@ pub enum ConstVal<'tcx> {
     Value(ConstValue<'tcx>),
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct ConstEvalErr<'tcx> {
     pub span: Span,
     pub kind: Lrc<ErrKind<'tcx>>,
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum ErrKind<'tcx> {
 
     NonConstPath,
-    UnimplementedConstVal(&'static str),
+    CouldNotResolve,
     IndexOutOfBounds { len: u64, index: u64 },
 
-    LayoutError(layout::LayoutError<'tcx>),
-
     TypeckError,
     CheckMatchError,
     Miri(::mir::interpret::EvalError<'tcx>, Vec<FrameInfo>),
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct FrameInfo {
     pub span: Span,
     pub location: String,
@@ -87,15 +85,12 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
 
         match *self.kind {
             NonConstPath        => simple!("non-constant path in constant expression"),
-            UnimplementedConstVal(what) =>
-                simple!("unimplemented constant expression: {}", what),
+            CouldNotResolve => simple!("could not resolve"),
             IndexOutOfBounds { len, index } => {
                 simple!("index out of bounds: the len is {} but the index is {}",
                         len, index)
             }
 
-            LayoutError(ref err) => Simple(err.to_string().into_cow()),
-
             TypeckError => simple!("type-checking failed"),
             CheckMatchError => simple!("match-checking failed"),
             Miri(ref err, ref trace) => Backtrace(err, trace),
@@ -149,6 +144,10 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> {
                 match miri.kind {
                     ::mir::interpret::EvalErrorKind::TypeckError |
                     ::mir::interpret::EvalErrorKind::Layout(_) => return None,
+                    ::mir::interpret::EvalErrorKind::ReferencedConstant(ref inner) => {
+                        inner.struct_generic(tcx, "referenced constant", lint_root, as_err)?.emit();
+                        (miri.to_string(), frames)
+                    },
                     _ => (miri.to_string(), frames),
                 }
             }
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 1b7c8bdc8a3..bf5bae6b20c 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -1,6 +1,7 @@
 use std::{fmt, env};
 
 use mir;
+use middle::const_val::ConstEvalErr;
 use ty::{FnSig, Ty, layout};
 use ty::layout::{Size, Align};
 
@@ -10,57 +11,50 @@ use super::{
 
 use backtrace::Backtrace;
 
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
 pub struct EvalError<'tcx> {
     pub kind: EvalErrorKind<'tcx, u64>,
-    pub backtrace: Option<Backtrace>,
 }
 
-impl<'tcx> EvalError<'tcx> {
-    pub fn print_backtrace(&mut self) {
-        if let Some(ref mut backtrace) = self.backtrace {
-            use std::fmt::Write;
-            let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
-            backtrace.resolve();
-            write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
-            'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
-                if frame.symbols().is_empty() {
-                    write!(trace_text, "{}: no symbols\n", i).unwrap();
-                }
-                for symbol in frame.symbols() {
-                    write!(trace_text, "{}: ", i).unwrap();
-                    if let Some(name) = symbol.name() {
-                        write!(trace_text, "{}\n", name).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown>\n").unwrap();
-                    }
-                    write!(trace_text, "\tat ").unwrap();
-                    if let Some(file_path) = symbol.filename() {
-                        write!(trace_text, "{}", file_path.display()).unwrap();
-                    } else {
-                        write!(trace_text, "<unknown_file>").unwrap();
+impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
+    fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
+        match env::var("MIRI_BACKTRACE") {
+            Ok(ref val) if !val.is_empty() => {
+                let backtrace = Backtrace::new();
+
+                use std::fmt::Write;
+                let mut trace_text = "\n\nAn error occurred in miri:\n".to_string();
+                write!(trace_text, "backtrace frames: {}\n", backtrace.frames().len()).unwrap();
+                'frames: for (i, frame) in backtrace.frames().iter().enumerate() {
+                    if frame.symbols().is_empty() {
+                        write!(trace_text, "{}: no symbols\n", i).unwrap();
                     }
-                    if let Some(line) = symbol.lineno() {
-                        write!(trace_text, ":{}\n", line).unwrap();
-                    } else {
-                        write!(trace_text, "\n").unwrap();
+                    for symbol in frame.symbols() {
+                        write!(trace_text, "{}: ", i).unwrap();
+                        if let Some(name) = symbol.name() {
+                            write!(trace_text, "{}\n", name).unwrap();
+                        } else {
+                            write!(trace_text, "<unknown>\n").unwrap();
+                        }
+                        write!(trace_text, "\tat ").unwrap();
+                        if let Some(file_path) = symbol.filename() {
+                            write!(trace_text, "{}", file_path.display()).unwrap();
+                        } else {
+                            write!(trace_text, "<unknown_file>").unwrap();
+                        }
+                        if let Some(line) = symbol.lineno() {
+                            write!(trace_text, ":{}\n", line).unwrap();
+                        } else {
+                            write!(trace_text, "\n").unwrap();
+                        }
                     }
                 }
-            }
-            error!("{}", trace_text);
+                error!("{}", trace_text);
+            },
+            _ => {},
         }
-    }
-}
-
-impl<'tcx> From<EvalErrorKind<'tcx, u64>> for EvalError<'tcx> {
-    fn from(kind: EvalErrorKind<'tcx, u64>) -> Self {
-        let backtrace = match env::var("MIRI_BACKTRACE") {
-            Ok(ref val) if !val.is_empty() => Some(Backtrace::new_unresolved()),
-            _ => None
-        };
         EvalError {
             kind,
-            backtrace,
         }
     }
 }
@@ -158,7 +152,7 @@ pub enum EvalErrorKind<'tcx, O> {
     TypeckError,
     /// Cannot compute this constant because it depends on another one
     /// which already produced an error
-    ReferencedConstant,
+    ReferencedConstant(ConstEvalErr<'tcx>),
     GeneratorResumedAfterReturn,
     GeneratorResumedAfterPanic,
 }
@@ -274,7 +268,7 @@ impl<'tcx, O> EvalErrorKind<'tcx, O> {
                 "there were unresolved type arguments during trait selection",
             TypeckError =>
                 "encountered constants with type errors, stopping evaluation",
-            ReferencedConstant =>
+            ReferencedConstant(_) =>
                 "referenced constant has errors",
             Overflow(mir::BinOp::Add) => "attempt to add with overflow",
             Overflow(mir::BinOp::Sub) => "attempt to subtract with overflow",
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 4447a2b6ed1..dff89f3c888 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -534,8 +534,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
                             } else {
                                 Err(CodeSelectionError(ConstEvalFailure(ConstEvalErr {
                                     span: obligation.cause.span,
-                                    kind: ErrKind::UnimplementedConstVal("could not resolve")
-                                        .into(),
+                                    kind: ErrKind::CouldNotResolve.into(),
                                 })))
                             }
                         },
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index e77ede72143..537efcd9b59 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -476,7 +476,6 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
         Some(interpret::EvalError {
             kind: tcx.lift(&self.kind)?,
-            backtrace: self.backtrace.clone(),
         })
     }
 }
@@ -578,7 +577,7 @@ impl<'a, 'tcx, O: Lift<'tcx>> Lift<'tcx> for interpret::EvalErrorKind<'a, O> {
             PathNotFound(ref v) => PathNotFound(v.clone()),
             UnimplementedTraitSelection => UnimplementedTraitSelection,
             TypeckError => TypeckError,
-            ReferencedConstant => ReferencedConstant,
+            ReferencedConstant(ref err) => ReferencedConstant(tcx.lift(err)?),
             OverflowNeg => OverflowNeg,
             Overflow(op) => Overflow(op),
             DivisionByZero => DivisionByZero,
@@ -596,13 +595,9 @@ impl<'a, 'tcx> Lift<'tcx> for const_val::ErrKind<'a> {
 
         Some(match *self {
             NonConstPath => NonConstPath,
-            UnimplementedConstVal(s) => UnimplementedConstVal(s),
+            CouldNotResolve => CouldNotResolve,
             IndexOutOfBounds { len, index } => IndexOutOfBounds { len, index },
 
-            LayoutError(ref e) => {
-                return tcx.lift(e).map(LayoutError)
-            }
-
             TypeckError => TypeckError,
             CheckMatchError => CheckMatchError,
             Miri(ref e, ref frames) => return tcx.lift(e).map(|e| Miri(e, frames.clone())),
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index 17df184920c..3fcf1b5c8ed 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -564,8 +564,7 @@ pub fn const_eval_provider<'a, 'tcx>(
             val = ecx.try_read_by_ref(val, miri_ty)?;
         }
         Ok(value_to_const_value(&ecx, val, miri_ty))
-    }).map_err(|mut err| {
-        err.print_backtrace();
+    }).map_err(|err| {
         let (trace, span) = ecx.generate_stacktrace(None);
         let err = ErrKind::Miri(err, trace);
         let err = ConstEvalErr {
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 4c03046f7b1..3e91fa72cae 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -3,7 +3,7 @@ use std::fmt::Write;
 use rustc::hir::def_id::DefId;
 use rustc::hir::def::Def;
 use rustc::hir::map::definitions::DefPathData;
-use rustc::middle::const_val::{ConstVal, ErrKind};
+use rustc::middle::const_val::ConstVal;
 use rustc::mir;
 use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout};
 use rustc::ty::subst::{Subst, Substs};
@@ -1056,15 +1056,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
         } else {
             self.param_env
         };
-        self.tcx.const_eval(param_env.and(gid)).map_err(|err| match *err.kind {
-            ErrKind::Miri(ref err, _) => match err.kind {
-                EvalErrorKind::TypeckError |
-                EvalErrorKind::Layout(_) => EvalErrorKind::TypeckError.into(),
-                _ => EvalErrorKind::ReferencedConstant.into(),
-            },
-            ErrKind::TypeckError => EvalErrorKind::TypeckError.into(),
-            ref other => bug!("const eval returned {:?}", other),
-        })
+        self.tcx.const_eval(param_env.and(gid)).map_err(|err| EvalErrorKind::ReferencedConstant(err).into())
     }
 
     pub fn force_allocation(&mut self, place: Place) -> EvalResult<'tcx, Place> {
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index dc56de47fbf..ec308c2193d 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -7,7 +7,7 @@ use rustc::ty::ParamEnv;
 use rustc::ty::maps::TyCtxtAt;
 use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
 use syntax::ast::Mutability;
-use rustc::middle::const_val::{ConstVal, ErrKind};
+use rustc::middle::const_val::ConstVal;
 
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value,
@@ -285,16 +285,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
             instance,
             promoted: None,
         };
-        self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|err| {
-            match *err.kind {
-                ErrKind::Miri(ref err, _) => match err.kind {
-                    EvalErrorKind::TypeckError |
-                    EvalErrorKind::Layout(_) => EvalErrorKind::TypeckError.into(),
-                    _ => EvalErrorKind::ReferencedConstant.into(),
-                },
-                ErrKind::TypeckError => EvalErrorKind::TypeckError.into(),
-                ref other => bug!("const eval returned {:?}", other),
-            }
+        self.tcx.const_eval(ParamEnv::reveal_all().and(gid)).map_err(|_| {
+            // no need to report anything, the const_eval call takes care of that for statics
+            assert!(self.tcx.is_static(def_id).is_some());
+            EvalErrorKind::TypeckError.into()
         }).map(|val| {
             let const_val = match val.val {
                 ConstVal::Value(val) => val,
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 4f3adaaae27..a8a50c50f59 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1201,7 +1201,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 use rustc::middle::const_val::ErrKind;
                 use rustc::mir::interpret::EvalErrorKind;
                 if let ErrKind::Miri(ref miri, ..) = *err.kind {
-                    if let EvalErrorKind::ReferencedConstant = miri.kind {
+                    if let EvalErrorKind::ReferencedConstant(_) = miri.kind {
                         err.report_as_error(
                             tcx.at(mir.promoted[i].span),
                             "erroneous constant used",
diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs
index 277a92e8314..4a5e78b381e 100644
--- a/src/test/compile-fail/const-err-multi.rs
+++ b/src/test/compile-fail/const-err-multi.rs
@@ -17,10 +17,13 @@ pub const A: i8 = -std::i8::MIN;
 //~| ERROR this constant cannot be used
 pub const B: i8 = A;
 //~^ ERROR const_err
+//~| ERROR const_err
 pub const C: u8 = A as u8;
 //~^ ERROR const_err
+//~| ERROR const_err
 pub const D: i8 = 50 - A;
 //~^ ERROR const_err
+//~| ERROR const_err
 
 fn main() {
     let _ = (A, B, C, D);
diff --git a/src/test/ui/const-eval/conditional_array_execution.nll.stderr b/src/test/ui/const-eval/conditional_array_execution.nll.stderr
index a35252c4789..3580950854d 100644
--- a/src/test/ui/const-eval/conditional_array_execution.nll.stderr
+++ b/src/test/ui/const-eval/conditional_array_execution.nll.stderr
@@ -18,12 +18,32 @@ LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    |                   |
    |                   attempt to subtract with overflow
 
+warning: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
 warning: this expression will panic at runtime
   --> $DIR/conditional_array_execution.rs:20:20
    |
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:5
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
 error[E0080]: erroneous constant used
   --> $DIR/conditional_array_execution.rs:20:5
    |
@@ -34,12 +54,21 @@ LL |     println!("{}", FOO);
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/conditional_array_execution.rs:20:20
    |
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/conditional_array_execution.rs b/src/test/ui/const-eval/conditional_array_execution.rs
index 055224d2731..ac555b25afd 100644
--- a/src/test/ui/const-eval/conditional_array_execution.rs
+++ b/src/test/ui/const-eval/conditional_array_execution.rs
@@ -19,5 +19,7 @@ const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
 fn main() {
     println!("{}", FOO);
     //~^ WARN this expression will panic at runtime
+    //~| WARN referenced constant
     //~| ERROR erroneous constant used
+    //~| E0080
 }
diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr
index f396c8f0444..64010c946a7 100644
--- a/src/test/ui/const-eval/conditional_array_execution.stderr
+++ b/src/test/ui/const-eval/conditional_array_execution.stderr
@@ -18,18 +18,36 @@ LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
    |                   |
    |                   attempt to subtract with overflow
 
+warning: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
 warning: this expression will panic at runtime
   --> $DIR/conditional_array_execution.rs:20:20
    |
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/conditional_array_execution.rs:20:20
+   |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+   |                   ----- attempt to subtract with overflow
+...
+LL |     println!("{}", FOO);
+   |                    ^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/conditional_array_execution.rs:20:20
    |
 LL |     println!("{}", FOO);
    |                    ^^^ referenced constant has errors
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-43197.nll.stderr b/src/test/ui/const-eval/issue-43197.nll.stderr
index 416967613f0..3bde12ade90 100644
--- a/src/test/ui/const-eval/issue-43197.nll.stderr
+++ b/src/test/ui/const-eval/issue-43197.nll.stderr
@@ -32,18 +32,47 @@ LL |     const Y: u32 = foo(0-1);
    |                        |
    |                        attempt to subtract with overflow
 
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
 warning: this expression will panic at runtime
   --> $DIR/issue-43197.rs:26:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
 warning: this expression will panic at runtime
   --> $DIR/issue-43197.rs:26:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:5
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-43197.rs:26:5
    |
@@ -54,18 +83,36 @@ LL |     println!("{} {}", X, Y);
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-43197.rs:26:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-43197.rs:26:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs
index f8d820db747..03aa65eb274 100644
--- a/src/test/ui/const-eval/issue-43197.rs
+++ b/src/test/ui/const-eval/issue-43197.rs
@@ -28,4 +28,8 @@ fn main() {
     //~| WARN this expression will panic at runtime
     //~| ERROR erroneous constant used
     //~| ERROR erroneous constant used
+    //~| ERROR E0080
+    //~| ERROR E0080
+    //~| WARN referenced constant
+    //~| WARN referenced constant
 }
diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr
index 207523f688f..071d8787307 100644
--- a/src/test/ui/const-eval/issue-43197.stderr
+++ b/src/test/ui/const-eval/issue-43197.stderr
@@ -32,30 +32,66 @@ LL |     const Y: u32 = foo(0-1);
    |                        |
    |                        attempt to subtract with overflow
 
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
 warning: this expression will panic at runtime
   --> $DIR/issue-43197.rs:26:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
+warning: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
 warning: this expression will panic at runtime
   --> $DIR/issue-43197.rs:26:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:26
+   |
+LL |     const Y: u32 = foo(0-1);
+   |                        --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                          ^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-43197.rs:26:26
    |
 LL |     println!("{} {}", X, Y);
    |                          ^ referenced constant has errors
 
+error[E0080]: referenced constant
+  --> $DIR/issue-43197.rs:26:23
+   |
+LL |     const X: u32 = 0-1;
+   |                    --- attempt to subtract with overflow
+...
+LL |     println!("{} {}", X, Y);
+   |                       ^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-43197.rs:26:23
    |
 LL |     println!("{} {}", X, Y);
    |                       ^ referenced constant has errors
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-44578.nll.stderr b/src/test/ui/const-eval/issue-44578.nll.stderr
index 49587fa0809..ad4f08966c0 100644
--- a/src/test/ui/const-eval/issue-44578.nll.stderr
+++ b/src/test/ui/const-eval/issue-44578.nll.stderr
@@ -1,3 +1,14 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:5
+   |
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-44578.rs:35:5
    |
@@ -8,12 +19,21 @@ LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-44578.rs:35:20
    |
 LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-44578.rs b/src/test/ui/const-eval/issue-44578.rs
index 331de4ab661..59ac4ab311c 100644
--- a/src/test/ui/const-eval/issue-44578.rs
+++ b/src/test/ui/const-eval/issue-44578.rs
@@ -34,4 +34,5 @@ impl Foo for u16 {
 fn main() {
     println!("{}", <Bar<u16, u8> as Foo>::AMT);
     //~^ ERROR erroneous constant used
+    //~| ERROR E0080
 }
diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr
index 42d60c604b8..28a723a069e 100644
--- a/src/test/ui/const-eval/issue-44578.stderr
+++ b/src/test/ui/const-eval/issue-44578.stderr
@@ -1,9 +1,18 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-44578.rs:35:20
+   |
+LL |     const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+   |                        ------------------------------------ index out of bounds: the len is 1 but the index is 1
+...
+LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-44578.rs:35:20
    |
 LL |     println!("{}", <Bar<u16, u8> as Foo>::AMT);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-50814-2.rs b/src/test/ui/const-eval/issue-50814-2.rs
index a90579296cb..60405da1eb6 100644
--- a/src/test/ui/const-eval/issue-50814-2.rs
+++ b/src/test/ui/const-eval/issue-50814-2.rs
@@ -24,6 +24,7 @@ impl<T: C> Foo<T> for A<T> {
 
 fn foo<T: C>() -> &'static usize {
     &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
+//~| ERROR E0080
 }
 
 impl C for () {
diff --git a/src/test/ui/const-eval/issue-50814-2.stderr b/src/test/ui/const-eval/issue-50814-2.stderr
index 3c613130354..3c59cb0e2bc 100644
--- a/src/test/ui/const-eval/issue-50814-2.stderr
+++ b/src/test/ui/const-eval/issue-50814-2.stderr
@@ -1,3 +1,12 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-50814-2.rs:26:5
+   |
+LL |     const BAR: usize = [5, 6, 7][T::BOO];
+   |                        ----------------- index out of bounds: the len is 3 but the index is 42
+...
+LL |     &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-50814-2.rs:26:5
    |
@@ -6,6 +15,6 @@ LL |     &<A<T> as Foo<T>>::BAR //~ ERROR erroneous constant used
    |      |
    |      referenced constant has errors
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-eval/issue-50814.rs b/src/test/ui/const-eval/issue-50814.rs
index 2af51c48bd4..c7140630399 100644
--- a/src/test/ui/const-eval/issue-50814.rs
+++ b/src/test/ui/const-eval/issue-50814.rs
@@ -25,6 +25,7 @@ impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A,B> {
 
 fn foo<T>(_: T) -> &'static u8 {
     &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
+//~| ERROR E0080
 }
 
 fn main() {
diff --git a/src/test/ui/const-eval/issue-50814.stderr b/src/test/ui/const-eval/issue-50814.stderr
index b3e13b43894..145279ccc03 100644
--- a/src/test/ui/const-eval/issue-50814.stderr
+++ b/src/test/ui/const-eval/issue-50814.stderr
@@ -1,3 +1,12 @@
+error[E0080]: referenced constant
+  --> $DIR/issue-50814.rs:27:5
+   |
+LL |     const MAX: u8 = A::MAX + B::MAX;
+   |                     --------------- attempt to add with overflow
+...
+LL |     &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
+   |     ^^^^^^^^^^^^^^^^^^
+
 error[E0080]: erroneous constant used
   --> $DIR/issue-50814.rs:27:5
    |
@@ -6,6 +15,6 @@ LL |     &Sum::<U8,U8>::MAX //~ ERROR erroneous constant used
    |      |
    |      referenced constant has errors
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/const-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs
index 453e332a903..20b88657674 100644
--- a/src/test/ui/const-len-underflow-separate-spans.rs
+++ b/src/test/ui/const-len-underflow-separate-spans.rs
@@ -21,4 +21,5 @@ const LEN: usize = ONE - TWO;
 fn main() {
     let a: [i8; LEN] = unimplemented!();
 //~^ ERROR E0080
+//~| ERROR E0080
 }
diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr
index 09a68a40b3a..630828ef8f5 100644
--- a/src/test/ui/const-len-underflow-separate-spans.stderr
+++ b/src/test/ui/const-len-underflow-separate-spans.stderr
@@ -12,6 +12,15 @@ error[E0080]: constant evaluation error
 LL | const LEN: usize = ONE - TWO;
    |                    ^^^^^^^^^ attempt to subtract with overflow
 
+error[E0080]: referenced constant
+  --> $DIR/const-len-underflow-separate-spans.rs:22:12
+   |
+LL | const LEN: usize = ONE - TWO;
+   |                    --------- attempt to subtract with overflow
+...
+LL |     let a: [i8; LEN] = unimplemented!();
+   |            ^^^^^^^^^
+
 error[E0080]: could not evaluate constant expression
   --> $DIR/const-len-underflow-separate-spans.rs:22:12
    |
@@ -20,6 +29,6 @@ LL |     let a: [i8; LEN] = unimplemented!();
    |                 |
    |                 referenced constant has errors
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0080`.