Skip to content

interpret: rename StackPopCleanup #143528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::{CanAccessMutGlobal, CompileTimeInterpCx, CompileTimeMachine};
use crate::const_eval::CheckAlignment;
use crate::interpret::{
CtfeValidationMode, GlobalId, Immediate, InternKind, InternResult, InterpCx, InterpErrorKind,
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, create_static_alloc,
InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, ReturnContinuation, create_static_alloc,
intern_const_alloc_recursive, interp_ok, throw_exhaust,
};
use crate::{CTRL_C_RECEIVED, errors};
Expand Down Expand Up @@ -76,7 +76,7 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
cid.instance,
body,
&ret.clone().into(),
StackPopCleanup::Root { cleanup: false },
ReturnContinuation::Stop { cleanup: false },
)?;
ecx.storage_live_for_always_live_locals()?;

Expand Down
36 changes: 18 additions & 18 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use tracing::{info, instrument, trace};

use super::{
CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy,
Projectable, Provenance, ReturnAction, Scalar, StackPopCleanup, StackPopInfo, interp_ok,
Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok,
throw_ub, throw_ub_custom, throw_unsup_format,
};
use crate::fluent_generated as fluent;
Expand Down Expand Up @@ -340,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
args: &[FnArg<'tcx, M::Provenance>],
with_caller_location: bool,
destination: &PlaceTy<'tcx, M::Provenance>,
mut stack_pop: StackPopCleanup,
mut cont: ReturnContinuation,
) -> InterpResult<'tcx> {
// Compute callee information.
// FIXME: for variadic support, do we have to somehow determine callee's extra_args?
Expand All @@ -365,15 +365,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

if !callee_fn_abi.can_unwind {
// The callee cannot unwind, so force the `Unreachable` unwind handling.
match &mut stack_pop {
StackPopCleanup::Root { .. } => {}
StackPopCleanup::Goto { unwind, .. } => {
match &mut cont {
ReturnContinuation::Stop { .. } => {}
ReturnContinuation::Goto { unwind, .. } => {
*unwind = mir::UnwindAction::Unreachable;
}
}
}

self.push_stack_frame_raw(instance, body, destination, stack_pop)?;
self.push_stack_frame_raw(instance, body, destination, cont)?;

// If an error is raised here, pop the frame again to get an accurate backtrace.
// To this end, we wrap it all in a `try` block.
Expand Down Expand Up @@ -617,7 +617,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
&args,
with_caller_location,
destination,
StackPopCleanup::Goto { ret: target, unwind },
ReturnContinuation::Goto { ret: target, unwind },
)
}
// `InstanceKind::Virtual` does not have callable MIR. Calls to `Virtual` instances must be
Expand Down Expand Up @@ -755,16 +755,16 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Note that we are using `pop_stack_frame_raw` and not `return_from_current_stack_frame`,
// as the latter "executes" the goto to the return block, but we don't want to,
// only the tail called function should return to the current return block.
let StackPopInfo { return_action, return_to_block, return_place } = self
.pop_stack_frame_raw(false, |_this, _return_place| {
let StackPopInfo { return_action, return_cont, return_place } =
self.pop_stack_frame_raw(false, |_this, _return_place| {
// This function's return value is just discarded, the tail-callee will fill in the return place instead.
interp_ok(())
})?;

assert_eq!(return_action, ReturnAction::Normal);

// Take the "stack pop cleanup" info, and use that to initiate the next call.
let StackPopCleanup::Goto { ret, unwind } = return_to_block else {
let ReturnContinuation::Goto { ret, unwind } = return_cont else {
bug!("can't tailcall as root");
};

Expand Down Expand Up @@ -896,23 +896,23 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// Normal return, figure out where to jump.
if unwinding {
// Follow the unwind edge.
match stack_pop_info.return_to_block {
StackPopCleanup::Goto { unwind, .. } => {
match stack_pop_info.return_cont {
ReturnContinuation::Goto { unwind, .. } => {
// This must be the very last thing that happens, since it can in fact push a new stack frame.
self.unwind_to_block(unwind)
}
StackPopCleanup::Root { .. } => {
panic!("encountered StackPopCleanup::Root when unwinding!")
ReturnContinuation::Stop { .. } => {
panic!("encountered ReturnContinuation::Stop when unwinding!")
}
}
} else {
// Follow the normal return edge.
match stack_pop_info.return_to_block {
StackPopCleanup::Goto { ret, .. } => self.return_to_block(ret),
StackPopCleanup::Root { .. } => {
match stack_pop_info.return_cont {
ReturnContinuation::Goto { ret, .. } => self.return_to_block(ret),
ReturnContinuation::Stop { .. } => {
assert!(
self.stack().is_empty(),
"only the bottommost frame can have StackPopCleanup::Root"
"only the bottommost frame can have ReturnContinuation::Stop"
);
interp_ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub use self::operand::{ImmTy, Immediate, OpTy};
pub use self::place::{MPlaceTy, MemPlaceMeta, PlaceTy, Writeable};
use self::place::{MemPlace, Place};
pub use self::projection::{OffsetMode, Projectable};
pub use self::stack::{Frame, FrameInfo, LocalState, StackPopCleanup, StackPopInfo};
pub use self::stack::{Frame, FrameInfo, LocalState, ReturnContinuation, StackPopInfo};
pub(crate) use self::util::create_static_alloc;
pub use self::validity::{CtfeValidationMode, RangeSet, RefTracking};
pub use self::visitor::ValueVisitor;
38 changes: 19 additions & 19 deletions compiler/rustc_const_eval/src/interpret/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
////////////////////////////////////////////////////////////////////////////////
// Return place and locals
////////////////////////////////////////////////////////////////////////////////
/// Work to perform when returning from this function.
return_to_block: StackPopCleanup,
/// Where to continue when returning from this function.
return_cont: ReturnContinuation,

/// The location where the result of the current stack frame should be written to,
/// and its layout in the caller. This place is to be interpreted relative to the
Expand Down Expand Up @@ -106,19 +106,19 @@ pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
pub(super) loc: Either<mir::Location, Span>,
}

/// Where and how to continue when returning/unwinding from the current function.
#[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these
pub enum StackPopCleanup {
pub enum ReturnContinuation {
/// Jump to the next block in the caller, or cause UB if None (that's a function
/// that may never return). Also store layout of return place so
/// we can validate it at that layout.
/// that may never return).
/// `ret` stores the block we jump to on a normal return, while `unwind`
/// stores the block used for cleanup during unwinding.
Goto { ret: Option<mir::BasicBlock>, unwind: mir::UnwindAction },
/// The root frame of the stack: nowhere else to jump to.
/// The root frame of the stack: nowhere else to jump to, so we stop.
/// `cleanup` says whether locals are deallocated. Static computation
/// wants them leaked to intern what they need (and just throw away
/// the entire `ecx` when it is done).
Root { cleanup: bool },
Stop { cleanup: bool },
}

/// Return type of [`InterpCx::pop_stack_frame_raw`].
Expand All @@ -127,8 +127,8 @@ pub struct StackPopInfo<'tcx, Prov: Provenance> {
/// stack frame.
pub return_action: ReturnAction,

/// [`return_to_block`](Frame::return_to_block) of the popped stack frame.
pub return_to_block: StackPopCleanup,
/// [`return_cont`](Frame::return_cont) of the popped stack frame.
pub return_cont: ReturnContinuation,

/// [`return_place`](Frame::return_place) of the popped stack frame.
pub return_place: PlaceTy<'tcx, Prov>,
Expand Down Expand Up @@ -255,7 +255,7 @@ impl<'tcx, Prov: Provenance> Frame<'tcx, Prov> {
Frame {
body: self.body,
instance: self.instance,
return_to_block: self.return_to_block,
return_cont: self.return_cont,
return_place: self.return_place,
locals: self.locals,
loc: self.loc,
Expand Down Expand Up @@ -350,20 +350,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// the arguments or local variables.
///
/// The high-level version of this is `init_stack_frame`.
#[instrument(skip(self, body, return_place, return_to_block), level = "debug")]
#[instrument(skip(self, body, return_place, return_cont), level = "debug")]
pub(crate) fn push_stack_frame_raw(
&mut self,
instance: ty::Instance<'tcx>,
body: &'tcx mir::Body<'tcx>,
return_place: &PlaceTy<'tcx, M::Provenance>,
return_to_block: StackPopCleanup,
return_cont: ReturnContinuation,
) -> InterpResult<'tcx> {
trace!("body: {:#?}", body);

// We can push a `Root` frame if and only if the stack is empty.
debug_assert_eq!(
self.stack().is_empty(),
matches!(return_to_block, StackPopCleanup::Root { .. })
matches!(return_cont, ReturnContinuation::Stop { .. })
);

// First push a stack frame so we have access to `instantiate_from_current_frame` and other
Expand All @@ -373,7 +373,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let pre_frame = Frame {
body,
loc: Right(body.span), // Span used for errors caused during preamble.
return_to_block,
return_cont,
return_place: return_place.clone(),
locals,
instance,
Expand Down Expand Up @@ -429,15 +429,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
copy_ret_val(self, &frame.return_place)?;
}

let return_to_block = frame.return_to_block;
let return_cont = frame.return_cont;
let return_place = frame.return_place.clone();

// Cleanup: deallocate locals.
// Usually we want to clean up (deallocate locals), but in a few rare cases we don't.
// We do this while the frame is still on the stack, so errors point to the callee.
let cleanup = match return_to_block {
StackPopCleanup::Goto { .. } => true,
StackPopCleanup::Root { cleanup, .. } => cleanup,
let cleanup = match return_cont {
ReturnContinuation::Goto { .. } => true,
ReturnContinuation::Stop { cleanup, .. } => cleanup,
};

let return_action = if cleanup {
Expand All @@ -455,7 +455,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ReturnAction::NoCleanup
};

interp_ok(StackPopInfo { return_action, return_to_block, return_place })
interp_ok(StackPopInfo { return_action, return_cont, return_place })
}

/// In the current stack frame, mark all locals as live that are not arguments and don't have
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/concurrency/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
start_abi,
&[func_arg],
Some(&ret_place),
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;

// Restore the old active thread frame.
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ pub fn create_ecx<'tcx>(
ImmTy::from_uint(sigpipe, ecx.machine.layouts.u8),
],
Some(&ret_place),
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;
}
MiriEntryFnType::MiriStart => {
Expand All @@ -445,7 +445,7 @@ pub fn create_ecx<'tcx>(
ExternAbi::Rust,
&[argc, argv],
Some(&ret_place),
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
caller_abi: ExternAbi,
args: &[ImmTy<'tcx>],
dest: Option<&MPlaceTy<'tcx>>,
stack_pop: StackPopCleanup,
cont: ReturnContinuation,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

Expand Down Expand Up @@ -472,7 +472,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
&args.iter().map(|a| FnArg::Copy(a.clone().into())).collect::<Vec<_>>(),
/*with_caller_location*/ false,
&dest.into(),
stack_pop,
cont,
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
ExternAbi::Rust,
&[],
None,
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
ReturnContinuation::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
)?;
interp_ok(())
}
Expand Down
14 changes: 7 additions & 7 deletions src/tools/miri/src/shims/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
&[data.clone()],
None,
// Directly return to caller.
StackPopCleanup::Goto { ret, unwind: mir::UnwindAction::Continue },
ReturnContinuation::Goto { ret, unwind: mir::UnwindAction::Continue },
)?;

// We ourselves will return `0`, eventually (will be overwritten if we catch a panic).
Expand Down Expand Up @@ -143,7 +143,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
&[catch_unwind.data, payload],
None,
// Directly return to caller of `catch_unwind`.
StackPopCleanup::Goto {
ReturnContinuation::Goto {
ret: catch_unwind.ret,
// `catch_fn` must not unwind.
unwind: mir::UnwindAction::Unreachable,
Expand Down Expand Up @@ -172,7 +172,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::Rust,
&[this.mplace_to_ref(&msg)?],
None,
StackPopCleanup::Goto { ret: None, unwind },
ReturnContinuation::Goto { ret: None, unwind },
)
}

Expand All @@ -191,7 +191,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::Rust,
&[this.mplace_to_ref(&msg)?],
None,
StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
ReturnContinuation::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
)
}

Expand Down Expand Up @@ -220,7 +220,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::Rust,
&[index, len],
None,
StackPopCleanup::Goto { ret: None, unwind },
ReturnContinuation::Goto { ret: None, unwind },
)?;
}
MisalignedPointerDereference { required, found } => {
Expand All @@ -241,7 +241,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::Rust,
&[required, found],
None,
StackPopCleanup::Goto { ret: None, unwind },
ReturnContinuation::Goto { ret: None, unwind },
)?;
}

Expand All @@ -254,7 +254,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::Rust,
&[],
None,
StackPopCleanup::Goto { ret: None, unwind },
ReturnContinuation::Goto { ret: None, unwind },
)?;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/tools/miri/src/shims/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::System { unwind: false },
&[null_ptr.clone(), ImmTy::from_scalar(reason, this.machine.layouts.u32), null_ptr],
None,
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;
interp_ok(())
}
Expand All @@ -346,7 +346,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::C { unwind: false },
&[ImmTy::from_scalar(data, this.machine.layouts.mut_raw_ptr)],
None,
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;

return interp_ok(Poll::Pending);
Expand Down Expand Up @@ -383,7 +383,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
ExternAbi::C { unwind: false },
&[ImmTy::from_scalar(ptr, this.machine.layouts.mut_raw_ptr)],
None,
StackPopCleanup::Root { cleanup: true },
ReturnContinuation::Stop { cleanup: true },
)?;

return interp_ok(Poll::Pending);
Expand Down
Loading