Move generate_stacktrace_from_stack away from InterpCx to avoid having to know the Machine
type
This commit is contained in:
parent
6b936b6c08
commit
d2d2bd2736
4 changed files with 32 additions and 37 deletions
|
@ -8,9 +8,9 @@ use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_middle::ty::{layout::LayoutError, ConstInt};
|
use rustc_middle::ty::{layout::LayoutError, ConstInt};
|
||||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||||
|
|
||||||
use super::{CompileTimeInterpreter, InterpCx};
|
use super::CompileTimeInterpreter;
|
||||||
use crate::errors::{self, FrameNote, ReportErrorExt};
|
use crate::errors::{self, FrameNote, ReportErrorExt};
|
||||||
use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, MachineStopType};
|
use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType};
|
||||||
|
|
||||||
/// The CTFE machine has some custom error kinds.
|
/// The CTFE machine has some custom error kinds.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -63,10 +63,7 @@ pub fn get_span_and_frames<'tcx, 'mir>(
|
||||||
where
|
where
|
||||||
'tcx: 'mir,
|
'tcx: 'mir,
|
||||||
{
|
{
|
||||||
let mut stacktrace =
|
let mut stacktrace = Frame::generate_stacktrace_from_stack(&machine.stack);
|
||||||
InterpCx::<CompileTimeInterpreter<'mir, 'tcx>>::generate_stacktrace_from_stack(
|
|
||||||
&machine.stack,
|
|
||||||
);
|
|
||||||
// Filter out `requires_caller_location` frames.
|
// Filter out `requires_caller_location` frames.
|
||||||
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
|
stacktrace.retain(|frame| !frame.instance.def.requires_caller_location(*tcx));
|
||||||
let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span);
|
let span = stacktrace.first().map(|f| f.span).unwrap_or(tcx.span);
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_middle::mir::interpret::InterpErrorInfo;
|
||||||
use rustc_middle::query::TyCtxtAt;
|
use rustc_middle::query::TyCtxtAt;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
|
|
||||||
use crate::interpret::{format_interp_error, InterpCx};
|
use crate::interpret::format_interp_error;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod eval_queries;
|
mod eval_queries;
|
||||||
|
|
|
@ -283,6 +283,32 @@ impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> {
|
||||||
pub(super) fn locals_addr(&self) -> usize {
|
pub(super) fn locals_addr(&self) -> usize {
|
||||||
self.locals.raw.as_ptr().addr()
|
self.locals.raw.as_ptr().addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn generate_stacktrace_from_stack(stack: &[Self]) -> Vec<FrameInfo<'tcx>> {
|
||||||
|
let mut frames = Vec::new();
|
||||||
|
// This deliberately does *not* honor `requires_caller_location` since it is used for much
|
||||||
|
// more than just panics.
|
||||||
|
for frame in stack.iter().rev() {
|
||||||
|
let span = match frame.loc {
|
||||||
|
Left(loc) => {
|
||||||
|
// If the stacktrace passes through MIR-inlined source scopes, add them.
|
||||||
|
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
|
||||||
|
let mut scope_data = &frame.body.source_scopes[scope];
|
||||||
|
while let Some((instance, call_span)) = scope_data.inlined {
|
||||||
|
frames.push(FrameInfo { span, instance });
|
||||||
|
span = call_span;
|
||||||
|
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
|
||||||
|
}
|
||||||
|
span
|
||||||
|
}
|
||||||
|
Right(span) => span,
|
||||||
|
};
|
||||||
|
frames.push(FrameInfo { span, instance: frame.instance });
|
||||||
|
}
|
||||||
|
trace!("generate stacktrace: {:#?}", frames);
|
||||||
|
frames
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: only used by miri, should be removed once translatable.
|
// FIXME: only used by miri, should be removed once translatable.
|
||||||
|
@ -1170,37 +1196,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
PlacePrinter { ecx: self, place: *place.place() }
|
PlacePrinter { ecx: self, place: *place.place() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn generate_stacktrace_from_stack(
|
|
||||||
stack: &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>],
|
|
||||||
) -> Vec<FrameInfo<'tcx>> {
|
|
||||||
let mut frames = Vec::new();
|
|
||||||
// This deliberately does *not* honor `requires_caller_location` since it is used for much
|
|
||||||
// more than just panics.
|
|
||||||
for frame in stack.iter().rev() {
|
|
||||||
let span = match frame.loc {
|
|
||||||
Left(loc) => {
|
|
||||||
// If the stacktrace passes through MIR-inlined source scopes, add them.
|
|
||||||
let mir::SourceInfo { mut span, scope } = *frame.body.source_info(loc);
|
|
||||||
let mut scope_data = &frame.body.source_scopes[scope];
|
|
||||||
while let Some((instance, call_span)) = scope_data.inlined {
|
|
||||||
frames.push(FrameInfo { span, instance });
|
|
||||||
span = call_span;
|
|
||||||
scope_data = &frame.body.source_scopes[scope_data.parent_scope.unwrap()];
|
|
||||||
}
|
|
||||||
span
|
|
||||||
}
|
|
||||||
Right(span) => span,
|
|
||||||
};
|
|
||||||
frames.push(FrameInfo { span, instance: frame.instance });
|
|
||||||
}
|
|
||||||
trace!("generate stacktrace: {:#?}", frames);
|
|
||||||
frames
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
|
pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
|
||||||
Self::generate_stacktrace_from_stack(self.stack())
|
Frame::generate_stacktrace_from_stack(self.stack())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -528,7 +528,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||||
use NonHaltingDiagnostic::*;
|
use NonHaltingDiagnostic::*;
|
||||||
|
|
||||||
let stacktrace =
|
let stacktrace =
|
||||||
MiriInterpCx::generate_stacktrace_from_stack(self.threads.active_thread_stack());
|
Frame::generate_stacktrace_from_stack(self.threads.active_thread_stack());
|
||||||
let (stacktrace, _was_pruned) = prune_stacktrace(stacktrace, self);
|
let (stacktrace, _was_pruned) = prune_stacktrace(stacktrace, self);
|
||||||
|
|
||||||
let (title, diag_level) = match &e {
|
let (title, diag_level) = match &e {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue