From 3a423c3feb9b4827ff8b3dd1e18307df700320f2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 24 May 2023 21:12:30 +0000 Subject: [PATCH] Manually add inlined frames in the interpreter stacktrace. --- .../src/interpret/eval_context.rs | 15 ++++++++++++++- src/tools/miri/tests/fail/terminate-terminator.rs | 2 +- .../miri/tests/fail/terminate-terminator.stderr | 11 +++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 040eba10eb4..7e94578003e 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -949,7 +949,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // 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 = frame.current_span(); + 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); diff --git a/src/tools/miri/tests/fail/terminate-terminator.rs b/src/tools/miri/tests/fail/terminate-terminator.rs index 22ffa1b2711..b9199cff079 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.rs +++ b/src/tools/miri/tests/fail/terminate-terminator.rs @@ -12,13 +12,13 @@ impl Drop for Foo { #[inline(always)] fn has_cleanup() { + //~^ ERROR: panic in a function that cannot unwind let _f = Foo; panic!(); } extern "C" fn panic_abort() { has_cleanup(); - //~^ ERROR: panic in a function that cannot unwind } fn main() { diff --git a/src/tools/miri/tests/fail/terminate-terminator.stderr b/src/tools/miri/tests/fail/terminate-terminator.stderr index 8ce4bb7cbb5..d73e23a53d0 100644 --- a/src/tools/miri/tests/fail/terminate-terminator.stderr +++ b/src/tools/miri/tests/fail/terminate-terminator.stderr @@ -6,15 +6,18 @@ error: abnormal termination: panic in a function that cannot unwind --> $DIR/terminate-terminator.rs:LL:CC | LL | / fn has_cleanup() { +LL | | LL | | let _f = Foo; LL | | panic!(); LL | | } | |_^ panic in a function that cannot unwind -... -LL | has_cleanup(); - | ------------- in this inlined function call | - = note: inside `panic_abort` at $DIR/terminate-terminator.rs:LL:CC + = note: inside `has_cleanup` at $DIR/terminate-terminator.rs:LL:CC +note: inside `panic_abort` + --> $DIR/terminate-terminator.rs:LL:CC + | +LL | has_cleanup(); + | ^^^^^^^^^^^^^ note: inside `main` --> $DIR/terminate-terminator.rs:LL:CC |