Miri stacktrace: record span inside frame, not call-site span
This commit is contained in:
parent
8926bb497d
commit
2117817cfd
2 changed files with 12 additions and 29 deletions
|
@ -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<hir::HirId>,
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -860,30 +860,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
}
|
||||
|
||||
pub fn generate_stacktrace(&self, explicit_span: Option<Span>) -> Vec<FrameInfo<'tcx>> {
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue