1
Fork 0

interpret: the MIR is actually at lifetime 'tcx

This commit is contained in:
Ralf Jung 2024-05-26 20:20:43 +02:00
parent cdc509f7c0
commit 36d36a3e1f
13 changed files with 75 additions and 74 deletions

View file

@ -90,7 +90,7 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
_destination: &interpret::MPlaceTy<'tcx, Self::Provenance>, _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>,
_target: Option<BasicBlock>, _target: Option<BasicBlock>,
_unwind: UnwindAction, _unwind: UnwindAction,
) -> interpret::InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> { ) -> interpret::InterpResult<'tcx, Option<(&'tcx Body<'tcx>, ty::Instance<'tcx>)>> {
unimplemented!() unimplemented!()
} }
@ -176,24 +176,24 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
fn init_frame_extra( fn init_frame_extra(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'mir, 'tcx, Self>,
_frame: interpret::Frame<'mir, 'tcx, Self::Provenance>, _frame: interpret::Frame<'tcx, Self::Provenance>,
) -> interpret::InterpResult< ) -> interpret::InterpResult<
'tcx, 'tcx,
interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>,
> { > {
unimplemented!() unimplemented!()
} }
fn stack<'a>( fn stack<'a>(
_ecx: &'a InterpCx<'mir, 'tcx, Self>, _ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
// Return an empty stack instead of panicking, as `cur_span` uses it to evaluate constants. // Return an empty stack instead of panicking, as `cur_span` uses it to evaluate constants.
&[] &[]
} }
fn stack_mut<'a>( fn stack_mut<'a>(
_ecx: &'a mut InterpCx<'mir, 'tcx, Self>, _ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>> { ) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
unimplemented!() unimplemented!()
} }
} }

View file

@ -58,13 +58,10 @@ impl<'tcx> Into<InterpErrorInfo<'tcx>> for ConstEvalErrKind {
} }
} }
pub fn get_span_and_frames<'tcx, 'mir>( pub fn get_span_and_frames<'tcx>(
tcx: TyCtxtAt<'tcx>, tcx: TyCtxtAt<'tcx>,
stack: &[Frame<'mir, 'tcx, impl Provenance, impl Sized>], stack: &[Frame<'tcx, impl Provenance, impl Sized>],
) -> (Span, Vec<errors::FrameNote>) ) -> (Span, Vec<errors::FrameNote>) {
where
'tcx: 'mir,
{
let mut stacktrace = Frame::generate_stacktrace_from_stack(stack); let mut stacktrace = Frame::generate_stacktrace_from_stack(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));
@ -161,9 +158,9 @@ where
/// Emit a lint from a const-eval situation. /// Emit a lint from a const-eval situation.
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future! // Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
pub(super) fn lint<'tcx, 'mir, L>( pub(super) fn lint<'tcx, L>(
tcx: TyCtxtAt<'tcx>, tcx: TyCtxtAt<'tcx>,
machine: &CompileTimeInterpreter<'mir, 'tcx>, machine: &CompileTimeInterpreter<'tcx>,
lint: &'static rustc_session::lint::Lint, lint: &'static rustc_session::lint::Lint,
decorator: impl FnOnce(Vec<errors::FrameNote>) -> L, decorator: impl FnOnce(Vec<errors::FrameNote>) -> L,
) where ) where

View file

@ -34,7 +34,7 @@ use crate::CTRL_C_RECEIVED;
fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>(
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
cid: GlobalId<'tcx>, cid: GlobalId<'tcx>,
body: &'mir mir::Body<'tcx>, body: &'tcx mir::Body<'tcx>,
) -> InterpResult<'tcx, R> { ) -> InterpResult<'tcx, R> {
trace!(?ecx.param_env); trace!(?ecx.param_env);
let tcx = *ecx.tcx; let tcx = *ecx.tcx;
@ -328,14 +328,14 @@ pub trait InterpretationResult<'tcx> {
/// evaluation query. /// evaluation query.
fn make_result<'mir>( fn make_result<'mir>(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>,
) -> Self; ) -> Self;
} }
impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> { impl<'tcx> InterpretationResult<'tcx> for ConstAlloc<'tcx> {
fn make_result<'mir>( fn make_result<'mir>(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
_ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, _ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>,
) -> Self { ) -> Self {
ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty } ConstAlloc { alloc_id: mplace.ptr().provenance.unwrap().alloc_id(), ty: mplace.layout.ty }
} }
@ -417,7 +417,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
#[inline(always)] #[inline(always)]
fn const_validate_mplace<'mir, 'tcx>( fn const_validate_mplace<'mir, 'tcx>(
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>,
mplace: &MPlaceTy<'tcx>, mplace: &MPlaceTy<'tcx>,
cid: GlobalId<'tcx>, cid: GlobalId<'tcx>,
) -> Result<(), ErrorHandled> { ) -> Result<(), ErrorHandled> {
@ -447,7 +447,7 @@ fn const_validate_mplace<'mir, 'tcx>(
#[inline(always)] #[inline(always)]
fn report_validation_error<'mir, 'tcx>( fn report_validation_error<'mir, 'tcx>(
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>,
error: InterpErrorInfo<'tcx>, error: InterpErrorInfo<'tcx>,
alloc_id: AllocId, alloc_id: AllocId,
) -> ErrorHandled { ) -> ErrorHandled {

View file

@ -45,7 +45,7 @@ const TINY_LINT_TERMINATOR_LIMIT: usize = 20;
const PROGRESS_INDICATOR_START: usize = 4_000_000; const PROGRESS_INDICATOR_START: usize = 4_000_000;
/// Extra machine state for CTFE, and the Machine instance /// Extra machine state for CTFE, and the Machine instance
pub struct CompileTimeInterpreter<'mir, 'tcx> { pub struct CompileTimeInterpreter<'tcx> {
/// The number of terminators that have been evaluated. /// The number of terminators that have been evaluated.
/// ///
/// This is used to produce lints informing the user that the compiler is not stuck. /// This is used to produce lints informing the user that the compiler is not stuck.
@ -53,7 +53,7 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
pub(super) num_evaluated_steps: usize, pub(super) num_evaluated_steps: usize,
/// The virtual call stack. /// The virtual call stack.
pub(super) stack: Vec<Frame<'mir, 'tcx>>, pub(super) stack: Vec<Frame<'tcx>>,
/// Pattern matching on consts with references would be unsound if those references /// Pattern matching on consts with references would be unsound if those references
/// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees, /// could point to anything mutable. Therefore, when evaluating consts and when constructing valtrees,
@ -90,7 +90,7 @@ impl From<bool> for CanAccessMutGlobal {
} }
} }
impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> { impl<'tcx> CompileTimeInterpreter<'tcx> {
pub(crate) fn new( pub(crate) fn new(
can_access_mut_global: CanAccessMutGlobal, can_access_mut_global: CanAccessMutGlobal,
check_alignment: CheckAlignment, check_alignment: CheckAlignment,
@ -165,7 +165,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> {
} }
pub(crate) type CompileTimeEvalContext<'mir, 'tcx> = pub(crate) type CompileTimeEvalContext<'mir, 'tcx> =
InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>; InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>;
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum MemoryKind { pub enum MemoryKind {
@ -371,7 +371,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> { impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'tcx> {
compile_time_machine!(<'mir, 'tcx>); compile_time_machine!(<'mir, 'tcx>);
type MemoryKind = MemoryKind; type MemoryKind = MemoryKind;
@ -417,7 +417,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
dest: &MPlaceTy<'tcx>, dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>, ret: Option<mir::BasicBlock>,
_unwind: mir::UnwindAction, // unwinding is not supported in consts _unwind: mir::UnwindAction, // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
debug!("find_mir_or_eval_fn: {:?}", orig_instance); debug!("find_mir_or_eval_fn: {:?}", orig_instance);
// Replace some functions. // Replace some functions.
@ -658,8 +658,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
#[inline(always)] #[inline(always)]
fn init_frame_extra( fn init_frame_extra(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'mir, 'tcx, Self>,
frame: Frame<'mir, 'tcx>, frame: Frame<'tcx>,
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> { ) -> InterpResult<'tcx, Frame<'tcx>> {
// Enforce stack size limit. Add 1 because this is run before the new frame is pushed. // Enforce stack size limit. Add 1 because this is run before the new frame is pushed.
if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) { if !ecx.recursion_limit.value_within_limit(ecx.stack().len() + 1) {
throw_exhaust!(StackFrameLimitReached) throw_exhaust!(StackFrameLimitReached)
@ -671,14 +671,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
#[inline(always)] #[inline(always)]
fn stack<'a>( fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>, ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
&ecx.machine.stack &ecx.machine.stack
} }
#[inline(always)] #[inline(always)]
fn stack_mut<'a>( fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>, ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>> { ) -> &'a mut Vec<Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
&mut ecx.machine.stack &mut ecx.machine.stack
} }

View file

@ -90,12 +90,12 @@ impl Drop for SpanGuard {
} }
/// A stack frame. /// A stack frame.
pub struct Frame<'mir, 'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> { pub struct Frame<'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Function and callsite information // Function and callsite information
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// The MIR for the function called on this frame. /// The MIR for the function called on this frame.
pub body: &'mir mir::Body<'tcx>, pub body: &'tcx mir::Body<'tcx>,
/// The def_id and args of the current function. /// The def_id and args of the current function.
pub instance: ty::Instance<'tcx>, pub instance: ty::Instance<'tcx>,
@ -232,8 +232,8 @@ impl<'tcx, Prov: Provenance> LocalState<'tcx, Prov> {
} }
} }
impl<'mir, 'tcx, Prov: Provenance> Frame<'mir, 'tcx, Prov> { impl<'tcx, Prov: Provenance> Frame<'tcx, Prov> {
pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'mir, 'tcx, Prov, Extra> { pub fn with_extra<Extra>(self, extra: Extra) -> Frame<'tcx, Prov, Extra> {
Frame { Frame {
body: self.body, body: self.body,
instance: self.instance, instance: self.instance,
@ -247,7 +247,7 @@ impl<'mir, 'tcx, Prov: Provenance> Frame<'mir, 'tcx, Prov> {
} }
} }
impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> { impl<'tcx, Prov: Provenance, Extra> Frame<'tcx, Prov, Extra> {
/// Get the current location within the Frame. /// Get the current location within the Frame.
/// ///
/// If this is `Left`, we are not currently executing any particular statement in /// If this is `Left`, we are not currently executing any particular statement in
@ -517,14 +517,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
#[inline(always)] #[inline(always)]
pub(crate) fn stack(&self) -> &[Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>] { pub(crate) fn stack(&self) -> &[Frame<'tcx, M::Provenance, M::FrameExtra>] {
M::stack(self) M::stack(self)
} }
#[inline(always)] #[inline(always)]
pub(crate) fn stack_mut( pub(crate) fn stack_mut(&mut self) -> &mut Vec<Frame<'tcx, M::Provenance, M::FrameExtra>> {
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>> {
M::stack_mut(self) M::stack_mut(self)
} }
@ -536,12 +534,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
#[inline(always)] #[inline(always)]
pub fn frame(&self) -> &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra> { pub fn frame(&self) -> &Frame<'tcx, M::Provenance, M::FrameExtra> {
self.stack().last().expect("no call frames exist") self.stack().last().expect("no call frames exist")
} }
#[inline(always)] #[inline(always)]
pub fn frame_mut(&mut self) -> &mut Frame<'mir, 'tcx, M::Provenance, M::FrameExtra> { pub fn frame_mut(&mut self) -> &mut Frame<'tcx, M::Provenance, M::FrameExtra> {
self.stack_mut().last_mut().expect("no call frames exist") self.stack_mut().last_mut().expect("no call frames exist")
} }
@ -602,7 +600,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
T: TypeFoldable<TyCtxt<'tcx>>, T: TypeFoldable<TyCtxt<'tcx>>,
>( >(
&self, &self,
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
value: T, value: T,
) -> Result<T, ErrorHandled> { ) -> Result<T, ErrorHandled> {
frame frame
@ -680,7 +678,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
#[inline(always)] #[inline(always)]
pub(super) fn layout_of_local( pub(super) fn layout_of_local(
&self, &self,
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, frame: &Frame<'tcx, M::Provenance, M::FrameExtra>,
local: mir::Local, local: mir::Local,
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, TyAndLayout<'tcx>> { ) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
@ -803,7 +801,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
pub fn push_stack_frame( pub fn push_stack_frame(
&mut self, &mut self,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
body: &'mir mir::Body<'tcx>, body: &'tcx mir::Body<'tcx>,
return_place: &MPlaceTy<'tcx, M::Provenance>, return_place: &MPlaceTy<'tcx, M::Provenance>,
return_to_block: StackPopCleanup, return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {

View file

@ -46,7 +46,7 @@ pub trait HasStaticRootDefId {
fn static_def_id(&self) -> Option<LocalDefId>; fn static_def_id(&self) -> Option<LocalDefId>;
} }
impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_, '_> { impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_> {
fn static_def_id(&self) -> Option<LocalDefId> { fn static_def_id(&self) -> Option<LocalDefId> {
Some(self.static_root_ids?.1) Some(self.static_root_ids?.1)
} }

View file

@ -200,7 +200,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
destination: &MPlaceTy<'tcx, Self::Provenance>, destination: &MPlaceTy<'tcx, Self::Provenance>,
target: Option<mir::BasicBlock>, target: Option<mir::BasicBlock>,
unwind: mir::UnwindAction, unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>; ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>>;
/// Execute `fn_val`. It is the hook's responsibility to advance the instruction /// Execute `fn_val`. It is the hook's responsibility to advance the instruction
/// pointer as appropriate. /// pointer as appropriate.
@ -478,18 +478,18 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Called immediately before a new stack frame gets pushed. /// Called immediately before a new stack frame gets pushed.
fn init_frame_extra( fn init_frame_extra(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'mir, 'tcx, Self>,
frame: Frame<'mir, 'tcx, Self::Provenance>, frame: Frame<'tcx, Self::Provenance>,
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>>; ) -> InterpResult<'tcx, Frame<'tcx, Self::Provenance, Self::FrameExtra>>;
/// Borrow the current thread's stack. /// Borrow the current thread's stack.
fn stack<'a>( fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>, ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>]; ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>];
/// Mutably borrow the current thread's stack. /// Mutably borrow the current thread's stack.
fn stack_mut<'a>( fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>, ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>>; ) -> &'a mut Vec<Frame<'tcx, Self::Provenance, Self::FrameExtra>>;
/// Called immediately after a stack frame got pushed and its locals got initialized. /// Called immediately after a stack frame got pushed and its locals got initialized.
fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn after_stack_push(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
@ -499,7 +499,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Called just before the return value is copied to the caller-provided return place. /// Called just before the return value is copied to the caller-provided return place.
fn before_stack_pop( fn before_stack_pop(
_ecx: &InterpCx<'mir, 'tcx, Self>, _ecx: &InterpCx<'mir, 'tcx, Self>,
_frame: &Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, _frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
@ -509,7 +509,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
#[inline(always)] #[inline(always)]
fn after_stack_pop( fn after_stack_pop(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'mir, 'tcx, Self>,
_frame: Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, _frame: Frame<'tcx, Self::Provenance, Self::FrameExtra>,
unwinding: bool, unwinding: bool,
) -> InterpResult<'tcx, StackPopJump> { ) -> InterpResult<'tcx, StackPopJump> {
// By default, we do not support unwinding from panics // By default, we do not support unwinding from panics

View file

@ -84,7 +84,7 @@ where
impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> { impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> {
fn make_result<'mir>( fn make_result<'mir>(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'tcx>>,
) -> Self { ) -> Self {
let alloc_id = mplace.ptr().provenance.unwrap().alloc_id(); let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
let alloc = ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1; let alloc = ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1;

View file

@ -354,7 +354,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn on_stack_pop( fn on_stack_pop(
&self, &self,
frame: &Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>, frame: &Frame<'tcx, Provenance, FrameExtra<'tcx>>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let borrow_tracker = this.machine.borrow_tracker.as_ref().unwrap(); let borrow_tracker = this.machine.borrow_tracker.as_ref().unwrap();

View file

@ -9,6 +9,7 @@ use std::time::{Duration, SystemTime};
use either::Either; use either::Either;
use rustc_const_eval::CTRL_C_RECEIVED; use rustc_const_eval::CTRL_C_RECEIVED;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_index::{Idx, IndexVec}; use rustc_index::{Idx, IndexVec};
@ -235,7 +236,7 @@ pub struct Thread<'mir, 'tcx> {
thread_name: Option<Vec<u8>>, thread_name: Option<Vec<u8>>,
/// The virtual call stack. /// The virtual call stack.
stack: Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>>, stack: Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>>,
/// The function to call when the stack ran empty, to figure out what to do next. /// The function to call when the stack ran empty, to figure out what to do next.
/// Conceptually, this is the interpreter implementation of the things that happen 'after' the /// Conceptually, this is the interpreter implementation of the things that happen 'after' the
@ -376,7 +377,7 @@ impl VisitProvenance for Thread<'_, '_> {
} }
} }
impl VisitProvenance for Frame<'_, '_, Provenance, FrameExtra<'_>> { impl VisitProvenance for Frame<'_, Provenance, FrameExtra<'_>> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) { fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
let Frame { let Frame {
return_place, return_place,
@ -505,19 +506,18 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
} }
/// Borrow the stack of the active thread. /// Borrow the stack of the active thread.
pub fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] { pub fn active_thread_stack(&self) -> &[Frame<'tcx, Provenance, FrameExtra<'tcx>>] {
&self.threads[self.active_thread].stack &self.threads[self.active_thread].stack
} }
/// Mutably borrow the stack of the active thread. /// Mutably borrow the stack of the active thread.
fn active_thread_stack_mut( fn active_thread_stack_mut(&mut self) -> &mut Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
&mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> {
&mut self.threads[self.active_thread].stack &mut self.threads[self.active_thread].stack
} }
pub fn all_stacks( pub fn all_stacks(
&self, &self,
) -> impl Iterator<Item = (ThreadId, &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>])> { ) -> impl Iterator<Item = (ThreadId, &[Frame<'tcx, Provenance, FrameExtra<'tcx>>])> + Captures<'mir>
{
self.threads.iter_enumerated().map(|(id, t)| (id, &t.stack[..])) self.threads.iter_enumerated().map(|(id, t)| (id, &t.stack[..]))
} }
@ -1099,15 +1099,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
#[inline] #[inline]
fn active_thread_stack(&self) -> &[Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>] { fn active_thread_stack<'a>(&'a self) -> &'a [Frame<'tcx, Provenance, FrameExtra<'tcx>>]
where
'mir: 'a,
{
let this = self.eval_context_ref(); let this = self.eval_context_ref();
this.machine.threads.active_thread_stack() this.machine.threads.active_thread_stack()
} }
#[inline] #[inline]
fn active_thread_stack_mut( fn active_thread_stack_mut<'a>(
&mut self, &'a mut self,
) -> &mut Vec<Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> { ) -> &'a mut Vec<Frame<'tcx, Provenance, FrameExtra<'tcx>>>
where
'mir: 'a,
{
let this = self.eval_context_mut(); let this = self.eval_context_mut();
this.machine.threads.active_thread_stack_mut() this.machine.threads.active_thread_stack_mut()
} }

View file

@ -1321,7 +1321,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
self.stack()[frame_idx].current_span() self.stack()[frame_idx].current_span()
} }
fn stack(&self) -> &[Frame<'mir, 'tcx, Provenance, machine::FrameExtra<'tcx>>] { fn stack(&self) -> &[Frame<'tcx, Provenance, machine::FrameExtra<'tcx>>] {
self.threads.active_thread_stack() self.threads.active_thread_stack()
} }
@ -1330,7 +1330,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
/// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`. /// This is the source of truth for the `is_user_relevant` flag in our `FrameExtra`.
pub fn is_user_relevant(&self, frame: &Frame<'mir, 'tcx, Provenance>) -> bool { pub fn is_user_relevant(&self, frame: &Frame<'tcx, Provenance>) -> bool {
let def_id = frame.instance.def_id(); let def_id = frame.instance.def_id();
(def_id.is_local() || self.local_crates.contains(&def_id.krate)) (def_id.is_local() || self.local_crates.contains(&def_id.krate))
&& !frame.instance.def.requires_caller_location(self.tcx) && !frame.instance.def.requires_caller_location(self.tcx)

View file

@ -949,7 +949,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>, ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction, unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
// For foreign items, try to see if we can emulate them. // For foreign items, try to see if we can emulate them.
if ecx.tcx.is_foreign_item(instance.def_id()) { if ecx.tcx.is_foreign_item(instance.def_id()) {
// An external function call that does not have a MIR body. We either find MIR elsewhere // An external function call that does not have a MIR body. We either find MIR elsewhere
@ -1359,8 +1359,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn init_frame_extra( fn init_frame_extra(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'mir, 'tcx, Self>,
frame: Frame<'mir, 'tcx, Provenance>, frame: Frame<'tcx, Provenance>,
) -> InterpResult<'tcx, Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>> { ) -> InterpResult<'tcx, Frame<'tcx, Provenance, FrameExtra<'tcx>>> {
// Start recording our event before doing anything else // Start recording our event before doing anything else
let timing = if let Some(profiler) = ecx.machine.profiler.as_ref() { let timing = if let Some(profiler) = ecx.machine.profiler.as_ref() {
let fn_name = frame.instance.to_string(); let fn_name = frame.instance.to_string();
@ -1391,13 +1391,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
fn stack<'a>( fn stack<'a>(
ecx: &'a InterpCx<'mir, 'tcx, Self>, ecx: &'a InterpCx<'mir, 'tcx, Self>,
) -> &'a [Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>] { ) -> &'a [Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
ecx.active_thread_stack() ecx.active_thread_stack()
} }
fn stack_mut<'a>( fn stack_mut<'a>(
ecx: &'a mut InterpCx<'mir, 'tcx, Self>, ecx: &'a mut InterpCx<'mir, 'tcx, Self>,
) -> &'a mut Vec<Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>> { ) -> &'a mut Vec<Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
ecx.active_thread_stack_mut() ecx.active_thread_stack_mut()
} }
@ -1444,7 +1444,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
fn before_stack_pop( fn before_stack_pop(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'mir, 'tcx, Self>,
frame: &Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// We want this *before* the return value copy, because the return place itself is protected // We want this *before* the return value copy, because the return place itself is protected
// until we do `end_call` here. // until we do `end_call` here.
@ -1461,7 +1461,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn after_stack_pop( fn after_stack_pop(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'mir, 'tcx, Self>,
frame: Frame<'mir, 'tcx, Provenance, FrameExtra<'tcx>>, frame: Frame<'tcx, Provenance, FrameExtra<'tcx>>,
unwinding: bool, unwinding: bool,
) -> InterpResult<'tcx, StackPopJump> { ) -> InterpResult<'tcx, StackPopJump> {
if frame.extra.is_user_relevant { if frame.extra.is_user_relevant {

View file

@ -44,7 +44,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
ret: Option<mir::BasicBlock>, ret: Option<mir::BasicBlock>,
unwind: mir::UnwindAction, unwind: mir::UnwindAction,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
let tcx = this.tcx.tcx; let tcx = this.tcx.tcx;
@ -137,7 +137,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
fn lookup_exported_symbol( fn lookup_exported_symbol(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
let tcx = this.tcx.tcx; let tcx = this.tcx.tcx;