diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 04e57883c7753..e1e5bc589526b 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -510,6 +510,7 @@ impl_stable_hash_for!(struct ::middle::const_val::ConstEvalErr<'tcx> { impl_stable_hash_for!(struct ::middle::const_val::FrameInfo { span, + lint_root, location }); diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 381bb161e4205..824930a7eb000 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -655,6 +655,9 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { f(self); self.param_env = old_param_env; } + pub fn current_lint_root(&self) -> ast::NodeId { + self.last_ast_node_with_lint_attrs + } } impl<'a, 'tcx> LayoutOf for &'a LateContext<'a, 'tcx> { diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index d7f116705113e..d4ec71bc6c40a 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -9,13 +9,15 @@ // except according to those terms. use hir::def_id::DefId; -use ty::{self, TyCtxt, layout}; +use ty::{self, layout}; use ty::subst::Substs; +use ty::maps::TyCtxtAt; use mir::interpret::ConstValue; use errors::DiagnosticBuilder; use graphviz::IntoCow; use syntax_pos::Span; +use syntax::ast; use std::borrow::Cow; use rustc_data_structures::sync::Lrc; @@ -52,6 +54,7 @@ pub enum ErrKind<'tcx> { pub struct FrameInfo { pub span: Span, pub location: String, + pub lint_root: Option, } #[derive(Clone, Debug)] @@ -100,64 +103,86 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { } pub fn struct_error(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - primary_span: Span, - primary_kind: &str) - -> DiagnosticBuilder<'gcx> + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, + message: &str) + -> Option> { - let mut diag = struct_error(tcx, self.span, "constant evaluation error"); - self.note(tcx, primary_span, primary_kind, &mut diag); - diag + self.struct_generic(tcx, message, None, true) } - pub fn note(&self, - _tcx: TyCtxt<'a, 'gcx, 'tcx>, - primary_span: Span, - primary_kind: &str, - diag: &mut DiagnosticBuilder) - { - match self.description() { - ConstEvalErrDescription::Simple(message) => { - diag.span_label(self.span, message); - } - ConstEvalErrDescription::Backtrace(miri, frames) => { - diag.span_label(self.span, format!("{}", miri)); - for frame in frames { - diag.span_label(frame.span, format!("inside call to `{}`", frame.location)); - } - } + pub fn report_as_error(&self, + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, + message: &str + ) { + let err = self.struct_generic(tcx, message, None, true); + if let Some(mut err) = err { + err.emit(); } + } - if !primary_span.contains(self.span) { - diag.span_note(primary_span, - &format!("for {} here", primary_kind)); + pub fn report_as_lint(&self, + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, + message: &str, + lint_root: ast::NodeId, + ) { + let lint = self.struct_generic( + tcx, + message, + Some(lint_root), + false, + ); + if let Some(mut lint) = lint { + lint.emit(); } } - pub fn report(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - primary_span: Span, - primary_kind: &str) - { - match *self.kind { - ErrKind::TypeckError | ErrKind::CheckMatchError => return, - ErrKind::Miri(ref miri, _) => { + fn struct_generic( + &self, + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, + message: &str, + lint_root: Option, + as_err: bool, + ) -> Option> { + let (msg, frames): (_, &[_]) = match *self.kind { + ErrKind::TypeckError | ErrKind::CheckMatchError => return None, + ErrKind::Miri(ref miri, ref frames) => { match miri.kind { ::mir::interpret::EvalErrorKind::TypeckError | - ::mir::interpret::EvalErrorKind::Layout(_) => return, - _ => {}, + ::mir::interpret::EvalErrorKind::Layout(_) => return None, + _ => (miri.to_string(), frames), } } - _ => {} + _ => (self.description().into_oneline().to_string(), &[]), + }; + trace!("reporting const eval failure at {:?}", self.span); + let mut err = if as_err { + struct_error(tcx, message) + } else { + let node_id = frames + .iter() + .rev() + .filter_map(|frame| frame.lint_root) + .next() + .or(lint_root) + .expect("some part of a failing const eval must be local"); + tcx.struct_span_lint_node( + ::rustc::lint::builtin::CONST_ERR, + node_id, + tcx.span, + message, + ) + }; + err.span_label(self.span, msg); + for FrameInfo { span, location, .. } in frames { + err.span_label(*span, format!("inside call to `{}`", location)); } - self.struct_error(tcx, primary_span, primary_kind).emit(); + Some(err) } } pub fn struct_error<'a, 'gcx, 'tcx>( - tcx: TyCtxt<'a, 'gcx, 'tcx>, - span: Span, + tcx: TyCtxtAt<'a, 'gcx, 'tcx>, msg: &str, -) -> DiagnosticBuilder<'gcx> { - struct_span_err!(tcx.sess, span, E0080, "{}", msg) +) -> DiagnosticBuilder<'tcx> { + struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg) } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 45819afca3f5c..1b7c8bdc8a301 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -16,6 +16,42 @@ pub struct EvalError<'tcx> { pub backtrace: Option, } +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, "\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, "").unwrap(); + } + if let Some(line) = symbol.lineno() { + write!(trace_text, ":{}\n", line).unwrap(); + } else { + write!(trace_text, "\n").unwrap(); + } + } + } + error!("{}", trace_text); + } + } +} + impl<'tcx> From> for EvalError<'tcx> { fn from(kind: EvalErrorKind<'tcx, u64>) -> Self { let backtrace = match env::var("MIRI_BACKTRACE") { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index dc4233436c660..f76b312ee530d 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -827,10 +827,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } ConstEvalFailure(ref err) => { - if let ::middle::const_val::ErrKind::TypeckError = *err.kind { - return; + match err.struct_error( + self.tcx.at(span), + "could not evaluate constant expression", + ) { + Some(err) => err, + None => return, } - err.struct_error(self.tcx, span, "constant expression") } Overflow => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 0bb0208e2a1b4..f947ed4568624 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2075,15 +2075,17 @@ impl<'a, 'gcx, 'tcx> AdtDef { } else { info!("invalid enum discriminant: {:#?}", val); ::middle::const_val::struct_error( - tcx, - tcx.def_span(expr_did), + tcx.at(tcx.def_span(expr_did)), "constant evaluation of enum discriminant resulted in non-integer", ).emit(); None } } Err(err) => { - err.report(tcx, tcx.def_span(expr_did), "enum discriminant"); + err.report_as_error( + tcx.at(tcx.def_span(expr_did)), + "could not evaluate enum discriminant", + ); if !expr_did.is_local() { span_bug!(tcx.def_span(expr_did), "variant discriminant evaluation succeeded \ diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index ef0bc3ed3306a..7c1035e2fcb88 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -217,7 +217,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { Ok((llval, constant.ty)) }) .unwrap_or_else(|e| { - e.report(bx.tcx(), constant.span, "shuffle_indices"); + e.report_as_error( + bx.tcx().at(constant.span), + "could not evaluate shuffle_indices at compile time", + ); // We've errored, so we don't have to produce working code. let ty = self.monomorphize(&constant.ty); let llty = bx.cx.layout_of(ty).llvm_type(bx.cx); diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 98383e882c4e8..9f32b41cb13e7 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -416,7 +416,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { // FIXME: generate a panic here }, mir::Literal::Value { .. } => { - err.report(bx.tcx(), constant.span, "const operand"); + err.report_as_error( + bx.tcx().at(constant.span), + "could not evaluate constant operand", + ); }, } // We've errored, so we don't have to produce working code. diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 79c7a79114761..d788e312d155a 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1501,24 +1501,11 @@ fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) { }; if let Err(err) = cx.tcx.const_eval(param_env.and(cid)) { let span = cx.tcx.def_span(def_id); - let mut diag = cx.struct_span_lint( - CONST_ERR, - span, + err.report_as_lint( + cx.tcx.at(span), &format!("this {} cannot be used", what), + cx.current_lint_root(), ); - use rustc::middle::const_val::ConstEvalErrDescription; - match err.description() { - ConstEvalErrDescription::Simple(message) => { - diag.span_label(span, message); - } - ConstEvalErrDescription::Backtrace(miri, frames) => { - diag.span_label(span, format!("{}", miri)); - for frame in frames { - diag.span_label(frame.span, format!("inside call to `{}`", frame.location)); - } - } - } - diag.emit() } } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index f6f98f0732e3a..f23e10ae5d2d8 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -523,7 +523,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let count = match cx.tcx.at(span).const_eval(cx.param_env.and(global_id)) { Ok(cv) => cv.unwrap_usize(cx.tcx), Err(e) => { - e.report(cx.tcx, cx.tcx.def_span(def_id), "array length"); + e.report_as_error(cx.tcx.at(span), "could not evaluate array length"); 0 }, }; diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 0a1139700984d..7cef8a75aa6ba 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -141,13 +141,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatternError::FloatBug => { // FIXME(#31407) this is only necessary because float parsing is buggy ::rustc::middle::const_val::struct_error( - self.tcx, pat_span, + self.tcx.at(pat_span), "could not evaluate float literal (see issue #31407)", ).emit(); } PatternError::NonConstPath(span) => { ::rustc::middle::const_val::struct_error( - self.tcx, span, + self.tcx.at(span), "runtime values cannot be referenced in patterns", ).emit(); } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 4cfe74413dfa5..7dae79530c488 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -695,7 +695,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { return self.const_to_pat(instance, value, id, span) }, Err(err) => { - err.report(self.tcx, span, "pattern"); + err.report_as_error( + self.tcx.at(span), + "could not evaluate constant pattern", + ); PatternKind::Wild }, } diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 44832df824064..17df184920cbf 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -65,34 +65,12 @@ pub fn eval_promoted<'a, 'mir, 'tcx>( cid: GlobalId<'tcx>, mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, -) -> Option<(Value, Scalar, Ty<'tcx>)> { +) -> EvalResult<'tcx, (Value, Scalar, Ty<'tcx>)> { ecx.with_fresh_body(|ecx| { - let res = eval_body_using_ecx(ecx, cid, Some(mir), param_env); - match res { - Ok(val) => Some(val), - Err(mut err) => { - ecx.report(&mut err, false, None); - None - } - } + eval_body_using_ecx(ecx, cid, Some(mir), param_env) }) } -pub fn eval_body<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - cid: GlobalId<'tcx>, - param_env: ty::ParamEnv<'tcx>, -) -> Option<(Value, Scalar, Ty<'tcx>)> { - let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env); - match res { - Ok(val) => Some(val), - Err(mut err) => { - ecx.report(&mut err, true, None); - None - } - } -} - pub fn value_to_const_value<'tcx>( ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>, val: Value, @@ -124,9 +102,17 @@ pub fn value_to_const_value<'tcx>( })(); match val { Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, ty), - Err(mut err) => { - ecx.report(&mut err, true, None); - bug!("miri error occured when converting Value to ConstValue") + Err(err) => { + let (frames, span) = ecx.generate_stacktrace(None); + let err = ConstEvalErr { + span, + kind: ErrKind::Miri(err, frames).into(), + }; + err.report_as_error( + ecx.tcx, + "failed to convert Value to ConstValue, this is a bug", + ); + span_bug!(span, "miri error occured when converting Value to ConstValue") } } } @@ -579,15 +565,17 @@ pub fn const_eval_provider<'a, 'tcx>( } Ok(value_to_const_value(&ecx, val, miri_ty)) }).map_err(|mut err| { - if tcx.is_static(def_id).is_some() { - ecx.report(&mut err, true, None); - } + err.print_backtrace(); let (trace, span) = ecx.generate_stacktrace(None); let err = ErrKind::Miri(err, trace); - ConstEvalErr { + let err = ConstEvalErr { kind: err.into(), span, + }; + if tcx.is_static(def_id).is_some() { + err.report_as_error(ecx.tcx, "could not evaluate static initializer"); } + err }) } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 632f7abfdb499..4c03046f7b14b 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -15,7 +15,7 @@ use syntax::codemap::{self, Span}; use syntax::ast::Mutability; use rustc::mir::interpret::{ GlobalId, Value, Scalar, - EvalError, EvalResult, EvalErrorKind, Pointer, ConstValue, + EvalResult, EvalErrorKind, Pointer, ConstValue, }; use std::mem; @@ -1626,7 +1626,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M let mut last_span = None; let mut frames = Vec::new(); // skip 1 because the last frame is just the environment of the constant - for &Frame { instance, span, .. } in self.stack().iter().skip(1).rev() { + for &Frame { instance, span, mir, block, stmt, .. } in self.stack().iter().skip(1).rev() { // make sure we don't emit frames that are duplicates of the previous if explicit_span == Some(span) { last_span = Some(span); @@ -1644,82 +1644,20 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M } else { instance.to_string() }; - frames.push(FrameInfo { span, location }); - } - trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); - (frames, self.tcx.span) - } - - pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option) { - match e.kind { - EvalErrorKind::Layout(_) | - EvalErrorKind::TypeckError => return, - _ => {}, - } - if let Some(ref mut backtrace) = e.backtrace { - 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, "\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, "").unwrap(); - } - if let Some(line) = symbol.lineno() { - write!(trace_text, ":{}\n", line).unwrap(); - } else { - write!(trace_text, "\n").unwrap(); - } - } - } - error!("{}", trace_text); - } - if let Some(frame) = self.stack().last() { - let block = &frame.mir.basic_blocks()[frame.block]; - let span = explicit_span.unwrap_or_else(|| if frame.stmt < block.statements.len() { - block.statements[frame.stmt].source_info.span - } else { - block.terminator().source_info.span - }); - trace!("reporting const eval failure at {:?}", span); - let mut err = if as_err { - ::rustc::middle::const_val::struct_error(*self.tcx, span, "constant evaluation error") + let block = &mir.basic_blocks()[block]; + let source_info = if stmt < block.statements.len() { + block.statements[stmt].source_info } else { - let node_id = self - .stack() - .iter() - .rev() - .filter_map(|frame| self.tcx.hir.as_local_node_id(frame.instance.def_id())) - .next() - .expect("some part of a failing const eval must be local"); - self.tcx.struct_span_lint_node( - ::rustc::lint::builtin::CONST_ERR, - node_id, - span, - "constant evaluation error", - ) + block.terminator().source_info }; - let (frames, span) = self.generate_stacktrace(explicit_span); - err.span_label(span, e.to_string()); - for FrameInfo { span, location } in frames { - err.span_note(span, &format!("inside call to `{}`", location)); - } - err.emit(); - } else { - self.tcx.sess.err(&e.to_string()); + let lint_root = match mir.source_scope_local_data { + mir::ClearCrossCrate::Set(ref ivs) => Some(ivs[source_info.scope].lint_root), + mir::ClearCrossCrate::Clear => None, + }; + frames.push(FrameInfo { span, location, lint_root }); } + trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); + (frames, self.tcx.span) } pub fn sign_extend(&self, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> { diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index b5b4ac6df6b5e..3afcd6f2d9bb5 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -21,7 +21,6 @@ pub use self::memory::{Memory, MemoryKind, HasMemory}; pub use self::const_eval::{ eval_promoted, mk_borrowck_eval_cx, - eval_body, CompileTimeEvaluator, const_value_to_allocation_provider, const_eval_provider, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a8a50e14c6822..54221239253cc 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -388,7 +388,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Ok(val) => collect_const(tcx, val, instance.substs, &mut neighbors), Err(err) => { let span = tcx.def_span(def_id); - err.report(tcx, span, "static"); + err.report_as_error( + tcx.at(span), + "could not evaluate static initializer", + ); } } } @@ -1236,7 +1239,10 @@ fn collect_const<'a, 'tcx>( Ok(val) => val.val, Err(err) => { let span = tcx.def_span(def_id); - err.report(tcx, span, "constant"); + err.report_as_error( + tcx.at(span), + "constant evaluation error", + ); return; } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index d39042ceba99f..83b4ea54aabe0 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind}; use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem}; use rustc::mir::visit::{Visitor, PlaceContext}; -use rustc::middle::const_val::ConstVal; +use rustc::middle::const_val::{ConstVal, ConstEvalErr, ErrKind}; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult}; use interpret::EvalContext; @@ -121,17 +121,37 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { fn use_ecx( &mut self, - span: Span, + source_info: SourceInfo, f: F ) -> Option where F: FnOnce(&mut Self) -> EvalResult<'tcx, T>, { - self.ecx.tcx.span = span; + self.ecx.tcx.span = source_info.span; + let lint_root = match self.mir.source_scope_local_data { + ClearCrossCrate::Set(ref ivs) => { + use rustc_data_structures::indexed_vec::Idx; + //FIXME(#51314): remove this check + if source_info.scope.index() >= ivs.len() { + return None; + } + ivs[source_info.scope].lint_root + }, + ClearCrossCrate::Clear => return None, + }; let r = match f(self) { Ok(val) => Some(val), - Err(mut err) => { - self.ecx.report(&mut err, false, Some(span)); + Err(err) => { + let (frames, span) = self.ecx.generate_stacktrace(None); + let err = ConstEvalErr { + span, + kind: ErrKind::Miri(err, frames).into(), + }; + err.report_as_lint( + self.ecx.tcx, + "this expression will panic at runtime", + lint_root, + ); None }, }; @@ -139,30 +159,37 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { r } - fn const_eval(&mut self, cid: GlobalId<'tcx>, span: Span) -> Option> { + fn const_eval(&mut self, cid: GlobalId<'tcx>, source_info: SourceInfo) -> Option> { let value = match self.tcx.const_eval(self.param_env.and(cid)) { Ok(val) => val, Err(err) => { - err.report(self.tcx, err.span, "constant propagated"); + err.report_as_error( + self.tcx.at(err.span), + "constant evaluation error", + ); return None; }, }; let val = match value.val { ConstVal::Value(v) => { - self.use_ecx(span, |this| this.ecx.const_value_to_value(v, value.ty))? + self.use_ecx(source_info, |this| this.ecx.const_value_to_value(v, value.ty))? }, _ => bug!("eval produced: {:?}", value), }; - let val = (val, value.ty, span); + let val = (val, value.ty, source_info.span); trace!("evaluated {:?} to {:?}", cid, val); Some(val) } - fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option> { + fn eval_constant( + &mut self, + c: &Constant<'tcx>, + source_info: SourceInfo, + ) -> Option> { match c.literal { Literal::Value { value } => match value.val { ConstVal::Value(v) => { - let v = self.use_ecx(c.span, |this| { + let v = self.use_ecx(source_info, |this| { this.ecx.const_value_to_value(v, value.ty) })?; Some((v, value.ty, c.span)) @@ -178,7 +205,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { instance, promoted: None, }; - self.const_eval(cid, c.span) + self.const_eval(cid, source_info) }, }, // evaluate the promoted and replace the constant with the evaluated result @@ -196,10 +223,9 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { }; // cannot use `const_eval` here, because that would require having the MIR // for the current function available, but we're producing said MIR right now - let span = self.mir.span; - let (value, _, ty) = self.use_ecx(span, |this| { - Ok(eval_promoted(&mut this.ecx, cid, this.mir, this.param_env)) - })??; + let (value, _, ty) = self.use_ecx(source_info, |this| { + eval_promoted(&mut this.ecx, cid, this.mir, this.param_env) + })?; let val = (value, ty, c.span); trace!("evaluated {:?} to {:?}", c, val); Some(val) @@ -225,9 +251,9 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { } } - fn eval_operand(&mut self, op: &Operand<'tcx>) -> Option> { + fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { - Operand::Constant(ref c) => self.eval_constant(c), + Operand::Constant(ref c) => self.eval_constant(c, source_info), Operand::Move(ref place) | Operand::Copy(ref place) => self.eval_place(place), } } @@ -243,10 +269,10 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { // This branch exists for the sanity type check Rvalue::Use(Operand::Constant(ref c)) => { assert_eq!(c.ty, place_ty); - self.eval_constant(c) + self.eval_constant(c, source_info) }, Rvalue::Use(ref op) => { - self.eval_operand(op) + self.eval_operand(op, source_info) }, Rvalue::Repeat(..) | Rvalue::Ref(..) | @@ -279,17 +305,17 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { return None; } - let val = self.eval_operand(arg)?; - let prim = self.use_ecx(span, |this| { + let val = self.eval_operand(arg, source_info)?; + let prim = self.use_ecx(source_info, |this| { this.ecx.value_to_scalar(ValTy { value: val.0, ty: val.1 }) })?; - let val = self.use_ecx(span, |this| this.ecx.unary_op(op, prim, val.1))?; + let val = self.use_ecx(source_info, |this| this.ecx.unary_op(op, prim, val.1))?; Some((Value::Scalar(val), place_ty, span)) } Rvalue::CheckedBinaryOp(op, ref left, ref right) | Rvalue::BinaryOp(op, ref left, ref right) => { trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right); - let right = self.eval_operand(right)?; + let right = self.eval_operand(right, source_info)?; let def_id = if self.tcx.is_closure(self.source.def_id) { self.tcx.closure_base_def_id(self.source.def_id) } else { @@ -301,7 +327,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { return None; } - let r = self.use_ecx(span, |this| { + let r = self.use_ecx(source_info, |this| { this.ecx.value_to_scalar(ValTy { value: right.0, ty: right.1 }) })?; if op == BinOp::Shr || op == BinOp::Shl { @@ -332,12 +358,12 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { return None; } } - let left = self.eval_operand(left)?; - let l = self.use_ecx(span, |this| { + let left = self.eval_operand(left, source_info)?; + let l = self.use_ecx(source_info, |this| { this.ecx.value_to_scalar(ValTy { value: left.0, ty: left.1 }) })?; trace!("const evaluating {:?} for {:?} and {:?}", op, left, right); - let (val, overflow) = self.use_ecx(span, |this| { + let (val, overflow) = self.use_ecx(source_info, |this| { this.ecx.binary_op(op, l, left.1, r, right.1) })?; let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue { @@ -348,11 +374,8 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { } else { if overflow { use rustc::mir::interpret::EvalErrorKind; - let mut err = EvalErrorKind::Overflow(op).into(); - self.use_ecx(span, |this| { - this.ecx.report(&mut err, false, Some(span)); - Ok(()) - }); + let err = EvalErrorKind::Overflow(op).into(); + let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; } Value::Scalar(val) @@ -431,7 +454,8 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { ) { trace!("visit_constant: {:?}", constant); self.super_constant(constant, location); - self.eval_constant(constant); + let source_info = *self.mir.source_info(location); + self.eval_constant(constant, source_info); } fn visit_statement( @@ -466,8 +490,9 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { location: Location, ) { self.super_terminator_kind(block, kind, location); + let source_info = *self.mir.source_info(location); if let TerminatorKind::Assert { expected, msg, cond, .. } = kind { - if let Some(value) = self.eval_operand(cond) { + if let Some(value) = self.eval_operand(cond, source_info) { trace!("assertion on {:?} should be {:?}", value, expected); if Value::Scalar(Scalar::from_bool(*expected)) != value.0 { // poison all places this operand references so that further code @@ -502,13 +527,15 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { DivisionByZero | RemainderByZero => msg.description().to_owned(), BoundsCheck { ref len, ref index } => { - let len = self.eval_operand(len).expect("len must be const"); + let len = self + .eval_operand(len, source_info) + .expect("len must be const"); let len = match len.0 { Value::Scalar(Scalar::Bits { bits, ..}) => bits, _ => bug!("const len not primitive: {:?}", len), }; let index = self - .eval_operand(index) + .eval_operand(index, source_info) .expect("index must be const"); let index = match index.0 { Value::Scalar(Scalar::Bits { bits, .. }) => bits, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c2c71d90f0674..83a654aaae9ca 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4040,7 +4040,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let count = tcx.const_eval(param_env.and(global_id)); if let Err(ref err) = count { - err.report(tcx, tcx.def_span(count_def_id), "constant expression"); + err.report_as_error( + tcx.at(tcx.def_span(count_def_id)), + "could not evaluate repeat length", + ); } let uty = match expected { diff --git a/src/test/compile-fail/const-array-oob.rs b/src/test/compile-fail/const-array-oob.rs index 108b7948dfcc2..22a3c5ceeb714 100644 --- a/src/test/compile-fail/const-array-oob.rs +++ b/src/test/compile-fail/const-array-oob.rs @@ -16,7 +16,7 @@ const FOO: [usize; 3] = [1, 2, 3]; const BAR: usize = FOO[5]; // no error, because the error below occurs before regular const eval const BLUB: [u32; FOO[4]] = [5, 6]; -//~^ ERROR constant evaluation error [E0080] +//~^ ERROR could not evaluate constant expression [E0080] //~| index out of bounds: the len is 3 but the index is 4 fn main() { diff --git a/src/test/compile-fail/const-err-early.rs b/src/test/compile-fail/const-err-early.rs index f8b20f6ee7933..92c6b1fd0b582 100644 --- a/src/test/compile-fail/const-err-early.rs +++ b/src/test/compile-fail/const-err-early.rs @@ -12,7 +12,7 @@ pub const A: i8 = -std::i8::MIN; //~ ERROR const_err //~^ ERROR this constant cannot be used -//~| ERROR constant evaluation error +//~| ERROR this expression will panic at runtime pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err //~^ ERROR this constant cannot be used pub const C: u8 = 200u8 * 4; //~ ERROR const_err diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs index 6f0281b8bd0ca..277a92e831453 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -13,7 +13,7 @@ pub const A: i8 = -std::i8::MIN; //~^ ERROR E0080 //~| ERROR attempt to negate with overflow -//~| ERROR constant evaluation error +//~| ERROR this expression will panic at runtime //~| ERROR this constant cannot be used pub const B: i8 = A; //~^ ERROR const_err diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs index f6a64bcba21c3..f77603b3ebafc 100644 --- a/src/test/compile-fail/const-err.rs +++ b/src/test/compile-fail/const-err.rs @@ -23,6 +23,7 @@ fn black_box(_: T) { // Make sure that the two uses get two errors. const FOO: u8 = [5u8][1]; //~^ ERROR constant evaluation error +//~| ERROR constant evaluation error //~| index out of bounds: the len is 1 but the index is 1 fn main() { diff --git a/src/test/compile-fail/const-integer-bool-ops.rs b/src/test/compile-fail/const-integer-bool-ops.rs index 3065122af6a94..29bc665a22e7b 100644 --- a/src/test/compile-fail/const-integer-bool-ops.rs +++ b/src/test/compile-fail/const-integer-bool-ops.rs @@ -16,7 +16,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected usize, found bool const ARR: [i32; X] = [99; 34]; -//~^ ERROR constant evaluation error const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -26,7 +25,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected usize, found bool const ARR1: [i32; X1] = [99; 47]; -//~^ ERROR constant evaluation error const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -36,7 +34,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected usize, found bool const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ ERROR constant evaluation error const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -46,43 +43,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected usize, found bool const ARR3: [i32; X3] = [99; 6]; -//~^ ERROR constant evaluation error const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR: [i32; Y] = [99; 1]; -//~^ ERROR constant evaluation error const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR1: [i32; Y1] = [99; 1]; -//~^ ERROR constant evaluation error const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR2: [i32; Y2] = [99; 1]; -//~^ ERROR constant evaluation error const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR3: [i32; Y3] = [99; 0]; -//~^ ERROR constant evaluation error const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR4: [i32; Y4] = [99; 0]; -//~^ ERROR constant evaluation error const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected usize, found bool const ARRR5: [i32; Y5] = [99; 0]; -//~^ ERROR constant evaluation error fn main() { let _ = ARR; diff --git a/src/test/compile-fail/const-len-underflow-subspans.rs b/src/test/compile-fail/const-len-underflow-subspans.rs index 85cc893aa133c..054c272a3d321 100644 --- a/src/test/compile-fail/const-len-underflow-subspans.rs +++ b/src/test/compile-fail/const-len-underflow-subspans.rs @@ -16,6 +16,6 @@ const TWO: usize = 2; fn main() { let a: [i8; ONE - TWO] = unimplemented!(); - //~^ ERROR constant evaluation error + //~^ ERROR could not evaluate constant expression //~| attempt to subtract with overflow } diff --git a/src/test/compile-fail/const-match-check.rs b/src/test/compile-fail/const-match-check.rs index 36a6600b62d98..304eef7847c91 100644 --- a/src/test/compile-fail/const-match-check.rs +++ b/src/test/compile-fail/const-match-check.rs @@ -40,5 +40,4 @@ fn main() { #[cfg(eval2)] let x: [i32; { let 0 = 0; 0 }] = []; //[eval2]~^ ERROR refutable pattern in local binding - //[eval2]~| ERROR constant evaluation error } diff --git a/src/test/compile-fail/const-tup-index-span.rs b/src/test/compile-fail/const-tup-index-span.rs index 7596881ef9b9a..b42c440f87d74 100644 --- a/src/test/compile-fail/const-tup-index-span.rs +++ b/src/test/compile-fail/const-tup-index-span.rs @@ -14,7 +14,6 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected tuple, found usize const ARR: [i32; TUP.0] = []; -//~^ ERROR constant evaluation error fn main() { } diff --git a/src/test/compile-fail/eval-enum.rs b/src/test/compile-fail/eval-enum.rs index 7315616860293..ada038114d8d0 100644 --- a/src/test/compile-fail/eval-enum.rs +++ b/src/test/compile-fail/eval-enum.rs @@ -11,12 +11,12 @@ enum Test { DivZero = 1/0, //~^ attempt to divide by zero - //~| ERROR constant evaluation error - //~| ERROR constant evaluation error + //~| ERROR could not evaluate enum discriminant + //~| ERROR this expression will panic at runtime RemZero = 1%0, //~^ attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error - //~| ERROR constant evaluation error + //~| ERROR could not evaluate enum discriminant + //~| ERROR this expression will panic at runtime } fn main() {} diff --git a/src/test/compile-fail/issue-43105.rs b/src/test/compile-fail/issue-43105.rs index 6fa65a541b39b..8a0471135afc4 100644 --- a/src/test/compile-fail/issue-43105.rs +++ b/src/test/compile-fail/issue-43105.rs @@ -12,11 +12,11 @@ fn xyz() -> u8 { 42 } const NUM: u8 = xyz(); //~^ ERROR calls in constants are limited to constant functions, tuple structs and tuple variants -//~| ERROR constant evaluation error fn main() { match 1 { NUM => unimplemented!(), + //~^ ERROR could not evaluate constant pattern _ => unimplemented!(), } } diff --git a/src/test/compile-fail/issue-8460-const.rs b/src/test/compile-fail/issue-8460-const.rs index 1d59e75a0f0f0..b0d6cb5df875a 100644 --- a/src/test/compile-fail/issue-8460-const.rs +++ b/src/test/compile-fail/issue-8460-const.rs @@ -16,62 +16,62 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero - //~| ERROR constant evaluation error + //~| ERROR this expression will panic at runtime } diff --git a/src/test/ui/const-eval-overflow-2.rs b/src/test/ui/const-eval-overflow-2.rs index 63f33cafaf827..ce3d54ee46d93 100644 --- a/src/test/ui/const-eval-overflow-2.rs +++ b/src/test/ui/const-eval-overflow-2.rs @@ -19,11 +19,11 @@ use std::{u8, u16, u32, u64, usize}; const NEG_128: i8 = -128; const NEG_NEG_128: i8 = -NEG_128; -//~^ ERROR E0080 fn main() { match -128i8 { NEG_NEG_128 => println!("A"), + //~^ ERROR could not evaluate constant pattern _ => println!("B"), } } diff --git a/src/test/ui/const-eval-overflow-2.stderr b/src/test/ui/const-eval-overflow-2.stderr index 9cee718c286b6..e99d409880e07 100644 --- a/src/test/ui/const-eval-overflow-2.stderr +++ b/src/test/ui/const-eval-overflow-2.stderr @@ -1,12 +1,9 @@ -error[E0080]: constant evaluation error - --> $DIR/const-eval-overflow-2.rs:21:25 +error[E0080]: could not evaluate constant pattern + --> $DIR/const-eval-overflow-2.rs:25:9 | LL | const NEG_NEG_128: i8 = -NEG_128; - | ^^^^^^^^ attempt to negate with overflow - | -note: for pattern here - --> $DIR/const-eval-overflow-2.rs:26:9 - | + | -------- attempt to negate with overflow +... LL | NEG_NEG_128 => println!("A"), | ^^^^^^^^^^^ diff --git a/src/test/ui/const-eval-overflow-4.rs b/src/test/ui/const-eval-overflow-4.rs index ed14036b0b4cb..9fc31b7c72781 100644 --- a/src/test/ui/const-eval-overflow-4.rs +++ b/src/test/ui/const-eval-overflow-4.rs @@ -20,9 +20,9 @@ use std::{i8, i16, i32, i64, isize}; use std::{u8, u16, u32, u64, usize}; const A_I8_T + //~^ ERROR could not evaluate constant expression : [u32; (i8::MAX as i8 + 1i8) as usize] - //~^ ERROR E0080 - //~| ERROR attempt to add with overflow + //~^ ERROR attempt to add with overflow = [0; (i8::MAX as usize) + 1]; fn main() { diff --git a/src/test/ui/const-eval-overflow-4.stderr b/src/test/ui/const-eval-overflow-4.stderr index fc4762f0554f7..058c8730d7c9e 100644 --- a/src/test/ui/const-eval-overflow-4.stderr +++ b/src/test/ui/const-eval-overflow-4.stderr @@ -1,16 +1,21 @@ error: attempt to add with overflow - --> $DIR/const-eval-overflow-4.rs:23:13 + --> $DIR/const-eval-overflow-4.rs:24:13 | LL | : [u32; (i8::MAX as i8 + 1i8) as usize] | ^^^^^^^^^^^^^^^^^^^^^ | = note: #[deny(const_err)] on by default -error[E0080]: constant evaluation error - --> $DIR/const-eval-overflow-4.rs:23:13 +error[E0080]: could not evaluate constant expression + --> $DIR/const-eval-overflow-4.rs:22:1 | -LL | : [u32; (i8::MAX as i8 + 1i8) as usize] - | ^^^^^^^^^^^^^^^^^^^^^ attempt to add with overflow +LL | / const A_I8_T +LL | | //~^ ERROR could not evaluate constant expression +LL | | : [u32; (i8::MAX as i8 + 1i8) as usize] + | | --------------------- attempt to add with overflow +LL | | //~^ ERROR attempt to add with overflow +LL | | = [0; (i8::MAX as usize) + 1]; + | |__________________________________^ error: aborting due to 2 previous errors diff --git a/src/test/ui/const-eval/conditional_array_execution.rs b/src/test/ui/const-eval/conditional_array_execution.rs index 8952a8386d7b8..daeeae513d911 100644 --- a/src/test/ui/const-eval/conditional_array_execution.rs +++ b/src/test/ui/const-eval/conditional_array_execution.rs @@ -19,5 +19,5 @@ const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; fn main() { println!("{}", FOO); - //~^ WARN constant evaluation error + //~^ WARN this expression will panic at runtime } diff --git a/src/test/ui/const-eval/conditional_array_execution.stderr b/src/test/ui/const-eval/conditional_array_execution.stderr index 5cf73b9fad66d..00b39d08eaf94 100644 --- a/src/test/ui/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/const-eval/conditional_array_execution.stderr @@ -14,9 +14,11 @@ warning: this constant cannot be used --> $DIR/conditional_array_execution.rs:16:1 | LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | attempt to subtract with overflow -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/conditional_array_execution.rs:21:20 | LL | println!("{}", FOO); diff --git a/src/test/ui/const-eval/issue-43197.rs b/src/test/ui/const-eval/issue-43197.rs index 7ec100e411b36..df352adea6358 100644 --- a/src/test/ui/const-eval/issue-43197.rs +++ b/src/test/ui/const-eval/issue-43197.rs @@ -25,6 +25,6 @@ fn main() { //~^ WARN attempt to subtract with overflow //~| WARN this constant cannot be used println!("{} {}", X, Y); - //~^ WARN constant evaluation error - //~| WARN constant evaluation error + //~^ WARN this expression will panic at runtime + //~| WARN this expression will panic at runtime } diff --git a/src/test/ui/const-eval/issue-43197.stderr b/src/test/ui/const-eval/issue-43197.stderr index d0e13d5657e75..412d97883f143 100644 --- a/src/test/ui/const-eval/issue-43197.stderr +++ b/src/test/ui/const-eval/issue-43197.stderr @@ -14,7 +14,9 @@ warning: this constant cannot be used --> $DIR/issue-43197.rs:21:5 | LL | const X: u32 = 0-1; - | ^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^---^ + | | + | attempt to subtract with overflow warning: attempt to subtract with overflow --> $DIR/issue-43197.rs:24:24 @@ -26,15 +28,17 @@ warning: this constant cannot be used --> $DIR/issue-43197.rs:24:5 | LL | const Y: u32 = foo(0-1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^^^^^---^^ + | | + | attempt to subtract with overflow -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/issue-43197.rs:27:23 | LL | println!("{} {}", X, Y); | ^ referenced constant has errors -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/issue-43197.rs:27:26 | LL | println!("{} {}", X, Y); diff --git a/src/test/ui/const-eval/issue-44578.stderr b/src/test/ui/const-eval/issue-44578.stderr index ce6ff86610aa5..3632a9baea172 100644 --- a/src/test/ui/const-eval/issue-44578.stderr +++ b/src/test/ui/const-eval/issue-44578.stderr @@ -1,4 +1,4 @@ -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/issue-44578.rs:36:20 | LL | println!("{}", as Foo>::AMT); //~ WARN const_err @@ -10,7 +10,7 @@ note: lint level defined here LL | #![warn(const_err)] | ^^^^^^^^^ -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/issue-44578.rs:36:20 | LL | println!("{}", as Foo>::AMT); //~ WARN const_err diff --git a/src/test/ui/const-eval/promoted_const_fn_fail.rs b/src/test/ui/const-eval/promoted_const_fn_fail.rs index 5ced2c9dd8f59..4888ed6e8dc7b 100644 --- a/src/test/ui/const-eval/promoted_const_fn_fail.rs +++ b/src/test/ui/const-eval/promoted_const_fn_fail.rs @@ -23,8 +23,8 @@ const fn bar() -> u8 { // is run on a system whose pointers need more // than 8 bits Bar { a: &42 }.b as u8 - //~^ constant evaluation error - //~| constant evaluation error + //~^ ERROR this expression will panic at runtime + //~| ERROR this expression will panic at runtime } } diff --git a/src/test/ui/const-eval/promoted_const_fn_fail.stderr b/src/test/ui/const-eval/promoted_const_fn_fail.stderr index f910705bb7b3c..d805e1a27c993 100644 --- a/src/test/ui/const-eval/promoted_const_fn_fail.stderr +++ b/src/test/ui/const-eval/promoted_const_fn_fail.stderr @@ -1,4 +1,4 @@ -error: constant evaluation error +error: this expression will panic at runtime --> $DIR/promoted_const_fn_fail.rs:25:9 | LL | Bar { a: &42 }.b as u8 @@ -9,23 +9,12 @@ note: lint level defined here | LL | #![deny(const_err)] | ^^^^^^^^^ -note: inside call to `bar` - --> $DIR/promoted_const_fn_fail.rs:35:28 - | -LL | let x: &'static u8 = &(bar() + 1); - | ^^^^^ -error: constant evaluation error +error: this expression will panic at runtime --> $DIR/promoted_const_fn_fail.rs:25:9 | LL | Bar { a: &42 }.b as u8 | ^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes - | -note: inside call to `bar` - --> $DIR/promoted_const_fn_fail.rs:35:28 - | -LL | let x: &'static u8 = &(bar() + 1); - | ^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/const-eval/promoted_errors.stderr b/src/test/ui/const-eval/promoted_errors.stderr index 683ee5375fbf6..a4c1c48a03dfe 100644 --- a/src/test/ui/const-eval/promoted_errors.stderr +++ b/src/test/ui/const-eval/promoted_errors.stderr @@ -1,4 +1,4 @@ -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/promoted_errors.rs:17:14 | LL | let _x = 0u32 - 1; @@ -16,7 +16,7 @@ warning: attempt to divide by zero LL | println!("{}", 1/(1-1)); | ^^^^^^^ -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/promoted_errors.rs:19:20 | LL | println!("{}", 1/(1-1)); @@ -28,13 +28,13 @@ warning: attempt to divide by zero LL | let _x = 1/(1-1); | ^^^^^^^ -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/promoted_errors.rs:22:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero -warning: constant evaluation error +warning: this expression will panic at runtime --> $DIR/promoted_errors.rs:25:20 | LL | println!("{}", 1/(false as u32)); diff --git a/src/test/ui/const-eval/pub_const_err.stderr b/src/test/ui/const-eval/pub_const_err.stderr index 068825f1cd310..352289417547e 100644 --- a/src/test/ui/const-eval/pub_const_err.stderr +++ b/src/test/ui/const-eval/pub_const_err.stderr @@ -14,7 +14,9 @@ warning: this constant cannot be used --> $DIR/pub_const_err.rs:16:1 | LL | pub const Z: u32 = 0 - 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^^^^^-----^ + | | + | attempt to subtract with overflow warning: attempt to subtract with overflow --> $DIR/pub_const_err.rs:20:22 diff --git a/src/test/ui/const-eval/pub_const_err_bin.stderr b/src/test/ui/const-eval/pub_const_err_bin.stderr index dcb8125fc55bc..a6db2176011d5 100644 --- a/src/test/ui/const-eval/pub_const_err_bin.stderr +++ b/src/test/ui/const-eval/pub_const_err_bin.stderr @@ -14,7 +14,9 @@ warning: this constant cannot be used --> $DIR/pub_const_err_bin.rs:14:1 | LL | pub const Z: u32 = 0 - 1; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^^^^^-----^ + | | + | attempt to subtract with overflow warning: attempt to subtract with overflow --> $DIR/pub_const_err_bin.rs:18:22 diff --git a/src/test/ui/const-fn-error.rs b/src/test/ui/const-fn-error.rs index 17dc9f94fe19c..6eda41730b307 100644 --- a/src/test/ui/const-fn-error.rs +++ b/src/test/ui/const-fn-error.rs @@ -19,7 +19,6 @@ const fn f(x: usize) -> usize { for i in 0..x { //~^ ERROR E0015 //~| ERROR E0019 - //~| ERROR E0080 sum += i; } sum @@ -27,5 +26,5 @@ const fn f(x: usize) -> usize { #[allow(unused_variables)] fn main() { - let a : [i32; f(X)]; + let a : [i32; f(X)]; //~ ERROR E0080 } diff --git a/src/test/ui/const-fn-error.stderr b/src/test/ui/const-fn-error.stderr index 29edc2756afff..cdbf86f42ecc0 100644 --- a/src/test/ui/const-fn-error.stderr +++ b/src/test/ui/const-fn-error.stderr @@ -26,20 +26,16 @@ error[E0019]: constant function contains unimplemented expression type LL | for i in 0..x { | ^^^^ -error[E0080]: constant evaluation error - --> $DIR/const-fn-error.rs:19:14 +error[E0080]: could not evaluate constant expression + --> $DIR/const-fn-error.rs:29:13 | LL | for i in 0..x { - | ^^^^ calling non-const fn `>::into_iter` + | ---- calling non-const fn `>::into_iter` ... -LL | let a : [i32; f(X)]; - | ---- inside call to `f` - | -note: for constant expression here - --> $DIR/const-fn-error.rs:30:13 - | -LL | let a : [i32; f(X)]; - | ^^^^^^^^^^^ +LL | let a : [i32; f(X)]; //~ ERROR E0080 + | ^^^^^^----^ + | | + | inside call to `f` error: aborting due to 5 previous errors diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index 48ff7a81c24ee..09a68a40b3a3d 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -12,11 +12,13 @@ error[E0080]: constant evaluation error LL | const LEN: usize = ONE - TWO; | ^^^^^^^^^ attempt to subtract with overflow -error[E0080]: constant evaluation error - --> $DIR/const-len-underflow-separate-spans.rs:22:17 +error[E0080]: could not evaluate constant expression + --> $DIR/const-len-underflow-separate-spans.rs:22:12 | LL | let a: [i8; LEN] = unimplemented!(); - | ^^^ referenced constant has errors + | ^^^^^---^ + | | + | referenced constant has errors error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0080.stderr b/src/test/ui/error-codes/E0080.stderr index 25ec5c458312d..a213c2b1b208e 100644 --- a/src/test/ui/error-codes/E0080.stderr +++ b/src/test/ui/error-codes/E0080.stderr @@ -6,7 +6,7 @@ LL | X = (1 << 500), //~ ERROR E0080 | = note: #[deny(exceeding_bitshifts)] on by default -error[E0080]: constant evaluation error +error[E0080]: could not evaluate enum discriminant --> $DIR/E0080.rs:12:9 | LL | X = (1 << 500), //~ ERROR E0080 @@ -20,13 +20,13 @@ LL | Y = (1 / 0) //~ ERROR E0080 | = note: #[deny(const_err)] on by default -error: constant evaluation error +error: this expression will panic at runtime --> $DIR/E0080.rs:14:9 | LL | Y = (1 / 0) //~ ERROR E0080 | ^^^^^^^ attempt to divide by zero -error[E0080]: constant evaluation error +error[E0080]: could not evaluate enum discriminant --> $DIR/E0080.rs:14:9 | LL | Y = (1 / 0) //~ ERROR E0080 diff --git a/src/test/ui/infinite-recursion-const-fn.rs b/src/test/ui/infinite-recursion-const-fn.rs index f98074bc554bb..4f1f67214509e 100644 --- a/src/test/ui/infinite-recursion-const-fn.rs +++ b/src/test/ui/infinite-recursion-const-fn.rs @@ -11,8 +11,8 @@ //https://github.com/rust-lang/rust/issues/31364 #![feature(const_fn)] -const fn a() -> usize { b() } //~ ERROR constant evaluation error +const fn a() -> usize { b() } const fn b() -> usize { a() } -const ARR: [i32; a()] = [5; 6]; +const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression fn main(){} diff --git a/src/test/ui/infinite-recursion-const-fn.stderr b/src/test/ui/infinite-recursion-const-fn.stderr index 81717fe1f0929..fb7c1be75413e 100644 --- a/src/test/ui/infinite-recursion-const-fn.stderr +++ b/src/test/ui/infinite-recursion-const-fn.stderr @@ -1,8 +1,8 @@ -error[E0080]: constant evaluation error - --> $DIR/infinite-recursion-const-fn.rs:14:25 +error[E0080]: could not evaluate constant expression + --> $DIR/infinite-recursion-const-fn.rs:16:1 | -LL | const fn a() -> usize { b() } //~ ERROR constant evaluation error - | ^^^ +LL | const fn a() -> usize { b() } + | --- | | | reached the configured maximum number of stack frames | inside call to `b` @@ -58,14 +58,10 @@ LL | const fn b() -> usize { a() } | inside call to `a` | inside call to `a` | inside call to `a` -LL | const ARR: [i32; a()] = [5; 6]; - | --- inside call to `a` - | -note: for constant expression here - --> $DIR/infinite-recursion-const-fn.rs:16:1 - | -LL | const ARR: [i32; a()] = [5; 6]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const ARR: [i32; a()] = [5; 6]; //~ ERROR could not evaluate constant expression + | ^^^^^^^^^^^^^^^^^---^^^^^^^^^^^ + | | + | inside call to `a` error: aborting due to previous error diff --git a/src/test/ui/type-dependent-def-issue-49241.rs b/src/test/ui/type-dependent-def-issue-49241.rs index 64264999fd2f1..db27ae89e69fd 100644 --- a/src/test/ui/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type-dependent-def-issue-49241.rs @@ -11,5 +11,5 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR can't capture dynamic environment in a fn item - let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error + let s: [u32; l] = v.into_iter().collect(); } diff --git a/src/test/ui/type-dependent-def-issue-49241.stderr b/src/test/ui/type-dependent-def-issue-49241.stderr index f00edccae5d50..361d28f274fa3 100644 --- a/src/test/ui/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type-dependent-def-issue-49241.stderr @@ -6,13 +6,6 @@ LL | const l: usize = v.count(); //~ ERROR can't capture dynamic environment | = help: use the `|| { ... }` closure form instead -error[E0080]: constant evaluation error - --> $DIR/type-dependent-def-issue-49241.rs:14:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); //~ ERROR constant evaluation error - | ^ encountered constants with type errors, stopping evaluation - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors occurred: E0080, E0434. -For more information about an error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0434`.