Rollup merge of #101985 - RalfJung:generate_stacktrace, r=oli-obk

interpret: expose generate_stacktrace without full InterpCx

In Miri we sometimes want to emit diagnostics without having a full `&InterpCx` available. To avoid duplicating code, this adds a way to get a stacktrace from an arbitrary slice of interpreter frames, that Miri can use with access to just a thread manager.
This commit is contained in:
Matthias Krüger 2022-09-19 17:55:21 +02:00 committed by GitHub
commit 8c0f8a285f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -929,11 +929,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
#[must_use] #[must_use]
pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> { pub fn generate_stacktrace_from_stack(
stack: &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>],
) -> Vec<FrameInfo<'tcx>> {
let mut frames = Vec::new(); let mut frames = Vec::new();
// This deliberately does *not* honor `requires_caller_location` since it is used for much // This deliberately does *not* honor `requires_caller_location` since it is used for much
// more than just panics. // more than just panics.
for frame in self.stack().iter().rev() { for frame in stack.iter().rev() {
let lint_root = frame.current_source_info().and_then(|source_info| { let lint_root = frame.current_source_info().and_then(|source_info| {
match &frame.body.source_scopes[source_info.scope].local_data { match &frame.body.source_scopes[source_info.scope].local_data {
mir::ClearCrossCrate::Set(data) => Some(data.lint_root), mir::ClearCrossCrate::Set(data) => Some(data.lint_root),
@ -947,6 +949,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("generate stacktrace: {:#?}", frames); trace!("generate stacktrace: {:#?}", frames);
frames frames
} }
#[must_use]
pub fn generate_stacktrace(&self) -> Vec<FrameInfo<'tcx>> {
Self::generate_stacktrace_from_stack(self.stack())
}
} }
#[doc(hidden)] #[doc(hidden)]