diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index c46ab89d0049..5a4588d746db 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -53,9 +53,8 @@ pub struct ConstEvalErr<'tcx> { #[derive(Debug)] pub struct FrameInfo<'tcx> { - /// This span is in the caller. - pub call_site: Span, pub instance: ty::Instance<'tcx>, + pub span: Span, pub lint_root: Option, } @@ -65,12 +64,12 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> { if tcx.def_key(self.instance.def_id()).disambiguated_data.data == DefPathData::ClosureExpr { - write!(f, "inside call to closure")?; + write!(f, "inside closure")?; } else { - write!(f, "inside call to `{}`", self.instance)?; + write!(f, "inside `{}`", self.instance)?; } - if !self.call_site.is_dummy() { - let lo = tcx.sess.source_map().lookup_char_pos(self.call_site.lo()); + if !self.span.is_dummy() { + let lo = tcx.sess.source_map().lookup_char_pos(self.span.lo()); write!(f, " at {}:{}:{}", lo.file.name, lo.line, lo.col.to_usize() + 1)?; } Ok(()) @@ -169,13 +168,9 @@ impl<'tcx> ConstEvalErr<'tcx> { err.span_label(self.span, span_msg); } // Add spans for the stacktrace. - // Skip the last, which is just the environment of the constant. The stacktrace - // is sometimes empty because we create "fake" eval contexts in CTFE to do work - // on constant values. - if !self.stacktrace.is_empty() { - for frame_info in &self.stacktrace[..self.stacktrace.len() - 1] { - err.span_label(frame_info.call_site, frame_info.to_string()); - } + // Skip the first, which is the place of the error. + for frame_info in self.stacktrace.iter().skip(1) { + err.span_label(frame_info.span, frame_info.to_string()); } // Let the caller finish the job. emit(err) diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d204be7f8067..9680130bbde1 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -860,30 +860,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } pub fn generate_stacktrace(&self, explicit_span: Option) -> Vec> { - let mut last_span = None; let mut frames = Vec::new(); for frame in self.stack().iter().rev() { - // make sure we don't emit frames that are duplicates of the previous - if explicit_span == Some(frame.span) { - last_span = Some(frame.span); - continue; - } - if let Some(last) = last_span { - if last == frame.span { - continue; - } - } else { - last_span = Some(frame.span); - } - - let lint_root = frame.current_source_info().and_then(|source_info| { + let source_info = frame.current_source_info(); + let lint_root = source_info.and_then(|source_info| { match &frame.body.source_scopes[source_info.scope].local_data { mir::ClearCrossCrate::Set(data) => Some(data.lint_root), mir::ClearCrossCrate::Clear => None, } }); + let span = source_info.map_or(DUMMY_SP, |source_info| source_info.span); - frames.push(FrameInfo { call_site: frame.span, instance: frame.instance, lint_root }); + frames.push(FrameInfo { span, instance: frame.instance, lint_root }); } trace!("generate stacktrace: {:#?}, {:?}", frames, explicit_span); frames