diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index 151cc9b1ce2..8c3dfd0bce7 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> ConstEvalErr<'tcx> { 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)); + diag.span_label(frame.span, format!("inside call to `{}`", frame.location)); } } } diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 072b28850f0..1314f5eb58d 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -789,7 +789,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { let field = Field::new(i); let val = match cv.val { ConstVal::Value(miri) => const_val_field( - self.tcx, self.param_env, instance, span, + self.tcx, self.param_env, instance, variant_opt, field, miri, cv.ty, ).unwrap(), _ => bug!("{:#?} is not a valid adt", cv), diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 071103c6000..ebb62070140 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -61,7 +61,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>( mir: &'mir mir::Mir<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option<(Value, Pointer, Ty<'tcx>)> { - let (res, ecx, _) = eval_body_and_ecx(tcx, cid, Some(mir), param_env); + let (res, ecx) = eval_body_and_ecx(tcx, cid, Some(mir), param_env); match res { Ok(val) => Some(val), Err(mut err) => { @@ -76,7 +76,7 @@ pub fn eval_body<'a, 'tcx>( cid: GlobalId<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option<(Value, Pointer, Ty<'tcx>)> { - let (res, ecx, _) = eval_body_and_ecx(tcx, cid, None, param_env); + let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env); match res { Ok(val) => Some(val), Err(mut err) => { @@ -91,7 +91,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( cid: GlobalId<'tcx>, mir: Option<&'mir mir::Mir<'tcx>>, param_env: ty::ParamEnv<'tcx>, -) -> (EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>, Span) { +) -> (EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>) { debug!("eval_body: {:?}, {:?}", cid, param_env); let mut ecx = EvalContext::new(tcx, param_env, CompileTimeEvaluator, ()); // we start out with the best span we have @@ -155,7 +155,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>( }; Ok((value, ptr, layout.ty)) })(); - (res, ecx, span) + (res, ecx) } pub struct CompileTimeEvaluator; @@ -367,7 +367,6 @@ pub fn const_val_field<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, - span: Span, variant: Option, field: mir::Field, value: Value, @@ -403,7 +402,7 @@ pub fn const_val_field<'a, 'tcx>( ty, })), Err(err) => { - let trace = ecx.generate_stacktrace(None); + let (trace, span) = ecx.generate_stacktrace(None); let err = ErrKind::Miri(err, trace); Err(ConstEvalErr { kind: err.into(), @@ -490,7 +489,7 @@ pub fn const_eval_provider<'a, 'tcx>( } }; - let (res, ecx, span) = eval_body_and_ecx(tcx, cid, None, key.param_env); + let (res, ecx) = eval_body_and_ecx(tcx, cid, None, key.param_env); res.map(|(miri_value, _, miri_ty)| { tcx.mk_const(ty::Const { val: ConstVal::Value(miri_value), @@ -500,7 +499,7 @@ pub fn const_eval_provider<'a, 'tcx>( if tcx.is_static(def_id).is_some() { ecx.report(&mut err, true, None); } - let trace = ecx.generate_stacktrace(None); + let (trace, span) = ecx.generate_stacktrace(None); let err = ErrKind::Miri(err, trace); ConstEvalErr { kind: err.into(), diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 483649204fb..2dc23e759c8 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1570,7 +1570,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M Ok(()) } - pub fn generate_stacktrace(&self, explicit_span: Option) -> Vec { + pub fn generate_stacktrace(&self, explicit_span: Option) -> (Vec, Span) { let mut last_span = None; let mut frames = Vec::new(); // skip 1 because the last frame is just the environment of the constant @@ -1594,7 +1594,15 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M }; frames.push(FrameInfo { span, location }); } - frames + let frame = self.frame(); + let bb = &frame.mir.basic_blocks()[frame.block]; + let span = if let Some(stmt) = bb.statements.get(frame.stmt) { + stmt.source_info.span + } else { + bb.terminator().source_info.span + }; + trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); + (frames, span) } pub fn report(&self, e: &mut EvalError, as_err: bool, explicit_span: Option) { @@ -1658,9 +1666,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M "constant evaluation error", ) }; + let (frames, span) = self.generate_stacktrace(explicit_span); err.span_label(span, e.to_string()); - for FrameInfo { span, location } in self.generate_stacktrace(explicit_span) { - err.span_note(span, &format!("inside call to {}", location)); + for FrameInfo { span, location } in frames { + err.span_note(span, &format!("inside call to `{}`", location)); } err.emit(); } else { diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index b43227c9f1a..de17872e96f 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -80,7 +80,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { let value = match self.tcx.const_eval(self.param_env.and(cid)) { Ok(val) => val, Err(err) => { - err.report(self.tcx, span, "constant propagated"); + err.report(self.tcx, err.span, "constant propagated"); return None; }, }; diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 8018073883f..6aa8b7e5449 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -203,7 +203,6 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx.tcx(), ty::ParamEnv::empty(traits::Reveal::All), self.instance, - constant.span, None, mir::Field::new(field as usize), c, diff --git a/src/test/ui/const-eval/index_out_of_bound.rs b/src/test/ui/const-eval/index_out_of_bound.rs index 632804f2fd3..e7ffbe81b9a 100644 --- a/src/test/ui/const-eval/index_out_of_bound.rs +++ b/src/test/ui/const-eval/index_out_of_bound.rs @@ -10,6 +10,5 @@ static FOO: i32 = [][0]; //~^ ERROR E0080 -//~| ERROR E0080 fn main() {} diff --git a/src/test/ui/const-fn-error.rs b/src/test/ui/const-fn-error.rs index dc1526a7079..9e09f66776c 100644 --- a/src/test/ui/const-fn-error.rs +++ b/src/test/ui/const-fn-error.rs @@ -18,6 +18,7 @@ const fn f(x: usize) -> usize { for i in 0..x { //~^ ERROR E0015 //~| ERROR E0019 + //~| ERROR E0080 sum += i; } sum @@ -26,5 +27,4 @@ const fn f(x: usize) -> usize { #[allow(unused_variables)] fn main() { let a : [i32; f(X)]; - //~^ ERROR E0080 } diff --git a/src/test/ui/infinite-recursion-const-fn.rs b/src/test/ui/infinite-recursion-const-fn.rs index 05e40abdc0f..51de304405a 100644 --- a/src/test/ui/infinite-recursion-const-fn.rs +++ b/src/test/ui/infinite-recursion-const-fn.rs @@ -12,7 +12,7 @@ #![feature(const_fn)] const fn a() -> usize { b() } -const fn b() -> usize { a() } -const ARR: [i32; a()] = [5; 6]; //~ ERROR constant evaluation error +const fn b() -> usize { a() } //~ ERROR constant evaluation error +const ARR: [i32; a()] = [5; 6]; fn main(){}