1
Fork 0

Auto merge of #125602 - RalfJung:interpret-mir-lifetime, r=oli-obk

interpret: get rid of 'mir lifetime

I realized our MIR bodies are actually at lifetime `'tcx`, so we don't need to carry around this other lifetime everywhere.

r? `@oli-obk`
This commit is contained in:
bors 2024-05-27 11:01:15 +00:00
commit a59072ec4f
88 changed files with 727 additions and 815 deletions

View file

@ -44,8 +44,8 @@ impl HasStaticRootDefId for DummyMachine {
} }
} }
impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine { impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
interpret::compile_time_machine!(<'mir, 'tcx>); interpret::compile_time_machine!(<'tcx>);
type MemoryKind = !; type MemoryKind = !;
const PANIC_ON_ALLOC_FAIL: bool = true; const PANIC_ON_ALLOC_FAIL: bool = true;
@ -53,11 +53,11 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
const ALL_CONSTS_ARE_PRECHECKED: bool = false; const ALL_CONSTS_ARE_PRECHECKED: bool = false;
#[inline(always)] #[inline(always)]
fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { fn enforce_alignment(_ecx: &InterpCx<'tcx, Self>) -> bool {
false // no reason to enforce alignment false // no reason to enforce alignment
} }
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool { fn enforce_validity(_ecx: &InterpCx<'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
false false
} }
@ -83,26 +83,26 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
} }
fn find_mir_or_eval_fn( fn find_mir_or_eval_fn(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_instance: ty::Instance<'tcx>, _instance: ty::Instance<'tcx>,
_abi: rustc_target::spec::abi::Abi, _abi: rustc_target::spec::abi::Abi,
_args: &[interpret::FnArg<'tcx, Self::Provenance>], _args: &[interpret::FnArg<'tcx, Self::Provenance>],
_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!()
} }
fn panic_nounwind( fn panic_nounwind(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_msg: &str, _msg: &str,
) -> interpret::InterpResult<'tcx> { ) -> interpret::InterpResult<'tcx> {
unimplemented!() unimplemented!()
} }
fn call_intrinsic( fn call_intrinsic(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_instance: ty::Instance<'tcx>, _instance: ty::Instance<'tcx>,
_args: &[interpret::OpTy<'tcx, Self::Provenance>], _args: &[interpret::OpTy<'tcx, Self::Provenance>],
_destination: &interpret::MPlaceTy<'tcx, Self::Provenance>, _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>,
@ -113,7 +113,7 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
} }
fn assert_panic( fn assert_panic(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_msg: &rustc_middle::mir::AssertMessage<'tcx>, _msg: &rustc_middle::mir::AssertMessage<'tcx>,
_unwind: UnwindAction, _unwind: UnwindAction,
) -> interpret::InterpResult<'tcx> { ) -> interpret::InterpResult<'tcx> {
@ -121,7 +121,7 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
} }
fn binary_ptr_op( fn binary_ptr_op(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
bin_op: BinOp, bin_op: BinOp,
left: &interpret::ImmTy<'tcx, Self::Provenance>, left: &interpret::ImmTy<'tcx, Self::Provenance>,
right: &interpret::ImmTy<'tcx, Self::Provenance>, right: &interpret::ImmTy<'tcx, Self::Provenance>,
@ -168,32 +168,30 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
} }
fn expose_ptr( fn expose_ptr(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_ptr: interpret::Pointer<Self::Provenance>, _ptr: interpret::Pointer<Self::Provenance>,
) -> interpret::InterpResult<'tcx> { ) -> interpret::InterpResult<'tcx> {
unimplemented!() unimplemented!()
} }
fn init_frame_extra( fn init_frame_extra(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_frame: interpret::Frame<'mir, 'tcx, Self::Provenance>, _frame: interpret::Frame<'tcx, Self::Provenance>,
) -> interpret::InterpResult< ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
'tcx, {
interpret::Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>,
> {
unimplemented!() unimplemented!()
} }
fn stack<'a>( fn stack<'a>(
_ecx: &'a InterpCx<'mir, 'tcx, Self>, _ecx: &'a InterpCx<'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<'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

@ -31,10 +31,10 @@ use crate::CTRL_C_RECEIVED;
// Returns a pointer to where the result lives // Returns a pointer to where the result lives
#[instrument(level = "trace", skip(ecx, body))] #[instrument(level = "trace", skip(ecx, body))]
fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>( fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, ecx: &mut CompileTimeEvalContext<'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;
@ -134,12 +134,12 @@ fn eval_body_using_ecx<'mir, 'tcx, R: InterpretationResult<'tcx>>(
/// that inform us about the generic bounds of the constant. E.g., using an associated constant /// that inform us about the generic bounds of the constant. E.g., using an associated constant
/// of a function's generic parameter will require knowledge about the bounds on the generic /// of a function's generic parameter will require knowledge about the bounds on the generic
/// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument. /// parameter. These bounds are passed to `mk_eval_cx` via the `ParamEnv` argument.
pub(crate) fn mk_eval_cx_to_read_const_val<'mir, 'tcx>( pub(crate) fn mk_eval_cx_to_read_const_val<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
root_span: Span, root_span: Span,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
can_access_mut_global: CanAccessMutGlobal, can_access_mut_global: CanAccessMutGlobal,
) -> CompileTimeEvalContext<'mir, 'tcx> { ) -> CompileTimeEvalContext<'tcx> {
debug!("mk_eval_cx: {:?}", param_env); debug!("mk_eval_cx: {:?}", param_env);
InterpCx::new( InterpCx::new(
tcx, tcx,
@ -151,12 +151,12 @@ pub(crate) fn mk_eval_cx_to_read_const_val<'mir, 'tcx>(
/// Create an interpreter context to inspect the given `ConstValue`. /// Create an interpreter context to inspect the given `ConstValue`.
/// Returns both the context and an `OpTy` that represents the constant. /// Returns both the context and an `OpTy` that represents the constant.
pub fn mk_eval_cx_for_const_val<'mir, 'tcx>( pub fn mk_eval_cx_for_const_val<'tcx>(
tcx: TyCtxtAt<'tcx>, tcx: TyCtxtAt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
val: mir::ConstValue<'tcx>, val: mir::ConstValue<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<(CompileTimeEvalContext<'mir, 'tcx>, OpTy<'tcx>)> { ) -> Option<(CompileTimeEvalContext<'tcx>, OpTy<'tcx>)> {
let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No); let ecx = mk_eval_cx_to_read_const_val(tcx.tcx, tcx.span, param_env, CanAccessMutGlobal::No);
let op = ecx.const_val_to_op(val, ty, None).ok()?; let op = ecx.const_val_to_op(val, ty, None).ok()?;
Some((ecx, op)) Some((ecx, op))
@ -170,7 +170,7 @@ pub fn mk_eval_cx_for_const_val<'mir, 'tcx>(
/// encounter an `Indirect` they cannot handle. /// encounter an `Indirect` they cannot handle.
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
pub(super) fn op_to_const<'tcx>( pub(super) fn op_to_const<'tcx>(
ecx: &CompileTimeEvalContext<'_, 'tcx>, ecx: &CompileTimeEvalContext<'tcx>,
op: &OpTy<'tcx>, op: &OpTy<'tcx>,
for_diagnostics: bool, for_diagnostics: bool,
) -> ConstValue<'tcx> { ) -> ConstValue<'tcx> {
@ -326,16 +326,16 @@ pub trait InterpretationResult<'tcx> {
/// This function takes the place where the result of the evaluation is stored /// This function takes the place where the result of the evaluation is stored
/// and prepares it for returning it in the appropriate format needed by the specific /// and prepares it for returning it in the appropriate format needed by the specific
/// evaluation query. /// evaluation query.
fn make_result<'mir>( fn make_result(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &mut InterpCx<'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(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
_ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, _ecx: &mut InterpCx<'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 }
} }
@ -416,8 +416,8 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
} }
#[inline(always)] #[inline(always)]
fn const_validate_mplace<'mir, 'tcx>( fn const_validate_mplace<'tcx>(
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &InterpCx<'tcx, CompileTimeInterpreter<'tcx>>,
mplace: &MPlaceTy<'tcx>, mplace: &MPlaceTy<'tcx>,
cid: GlobalId<'tcx>, cid: GlobalId<'tcx>,
) -> Result<(), ErrorHandled> { ) -> Result<(), ErrorHandled> {
@ -446,8 +446,8 @@ fn const_validate_mplace<'mir, 'tcx>(
} }
#[inline(always)] #[inline(always)]
fn report_validation_error<'mir, 'tcx>( fn report_validation_error<'tcx>(
ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &InterpCx<'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,
@ -164,8 +164,7 @@ impl<K: Hash + Eq, V> interpret::AllocMap<K, V> for FxIndexMap<K, V> {
} }
} }
pub(crate) type CompileTimeEvalContext<'mir, 'tcx> = pub(crate) type CompileTimeEvalContext<'tcx> = InterpCx<'tcx, CompileTimeInterpreter<'tcx>>;
InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>;
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum MemoryKind { pub enum MemoryKind {
@ -197,7 +196,7 @@ impl interpret::MayLeak for ! {
} }
} }
impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { impl<'tcx> CompileTimeEvalContext<'tcx> {
fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) { fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span); let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo()); let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
@ -371,25 +370,25 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> { impl<'tcx> interpret::Machine<'tcx> for CompileTimeInterpreter<'tcx> {
compile_time_machine!(<'mir, 'tcx>); compile_time_machine!(<'tcx>);
type MemoryKind = MemoryKind; type MemoryKind = MemoryKind;
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
#[inline(always)] #[inline(always)]
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool {
matches!(ecx.machine.check_alignment, CheckAlignment::Error) matches!(ecx.machine.check_alignment, CheckAlignment::Error)
} }
#[inline(always)] #[inline(always)]
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool { fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool {
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited() ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited()
} }
fn load_mir( fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
instance: ty::InstanceDef<'tcx>, instance: ty::InstanceDef<'tcx>,
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
match instance { match instance {
@ -410,14 +409,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
fn find_mir_or_eval_fn( fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
orig_instance: ty::Instance<'tcx>, orig_instance: ty::Instance<'tcx>,
_abi: CallAbi, _abi: CallAbi,
args: &[FnArg<'tcx>], args: &[FnArg<'tcx>],
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.
@ -448,7 +447,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance))) Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
} }
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> { fn panic_nounwind(ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
let msg = Symbol::intern(msg); let msg = Symbol::intern(msg);
let span = ecx.find_closest_untracked_caller_location(); let span = ecx.find_closest_untracked_caller_location();
let (file, line, col) = ecx.location_triple_for_span(span); let (file, line, col) = ecx.location_triple_for_span(span);
@ -456,7 +455,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
fn call_intrinsic( fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>], args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx, Self::Provenance>, dest: &MPlaceTy<'tcx, Self::Provenance>,
@ -555,7 +554,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
fn assert_panic( fn assert_panic(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
msg: &AssertMessage<'tcx>, msg: &AssertMessage<'tcx>,
_unwind: mir::UnwindAction, _unwind: mir::UnwindAction,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -586,7 +585,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
fn binary_ptr_op( fn binary_ptr_op(
_ecx: &InterpCx<'mir, 'tcx, Self>, _ecx: &InterpCx<'tcx, Self>,
_bin_op: mir::BinOp, _bin_op: mir::BinOp,
_left: &ImmTy<'tcx>, _left: &ImmTy<'tcx>,
_right: &ImmTy<'tcx>, _right: &ImmTy<'tcx>,
@ -594,7 +593,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time"); throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
} }
fn increment_const_eval_counter(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn increment_const_eval_counter(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
// The step limit has already been hit in a previous call to `increment_const_eval_counter`. // The step limit has already been hit in a previous call to `increment_const_eval_counter`.
if let Some(new_steps) = ecx.machine.num_evaluated_steps.checked_add(1) { if let Some(new_steps) = ecx.machine.num_evaluated_steps.checked_add(1) {
@ -650,16 +649,16 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
#[inline(always)] #[inline(always)]
fn expose_ptr(_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx> { fn expose_ptr(_ecx: &mut InterpCx<'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx> {
// This is only reachable with -Zunleash-the-miri-inside-of-you. // This is only reachable with -Zunleash-the-miri-inside-of-you.
throw_unsup_format!("exposing pointers is not possible at compile-time") throw_unsup_format!("exposing pointers is not possible at compile-time")
} }
#[inline(always)] #[inline(always)]
fn init_frame_extra( fn init_frame_extra(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'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)
@ -670,15 +669,15 @@ 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<'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<'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
} }
@ -715,7 +714,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
} }
fn retag_ptr_value( fn retag_ptr_value(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
_kind: mir::RetagKind, _kind: mir::RetagKind,
val: &ImmTy<'tcx, CtfeProvenance>, val: &ImmTy<'tcx, CtfeProvenance>,
) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> { ) -> InterpResult<'tcx, ImmTy<'tcx, CtfeProvenance>> {
@ -756,10 +755,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
Ok(()) Ok(())
} }
fn before_alloc_read( fn before_alloc_read(ecx: &InterpCx<'tcx, Self>, alloc_id: AllocId) -> InterpResult<'tcx> {
ecx: &InterpCx<'mir, 'tcx, Self>,
alloc_id: AllocId,
) -> InterpResult<'tcx> {
// Check if this is the currently evaluated static. // Check if this is the currently evaluated static.
if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) { if Some(alloc_id) == ecx.machine.static_root_ids.map(|(id, _)| id) {
return Err(ConstEvalErrKind::RecursiveStatic.into()); return Err(ConstEvalErrKind::RecursiveStatic.into());

View file

@ -21,7 +21,7 @@ use crate::interpret::{
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
fn branches<'tcx>( fn branches<'tcx>(
ecx: &CompileTimeEvalContext<'tcx, 'tcx>, ecx: &CompileTimeEvalContext<'tcx>,
place: &MPlaceTy<'tcx>, place: &MPlaceTy<'tcx>,
n: usize, n: usize,
variant: Option<VariantIdx>, variant: Option<VariantIdx>,
@ -59,7 +59,7 @@ fn branches<'tcx>(
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
fn slice_branches<'tcx>( fn slice_branches<'tcx>(
ecx: &CompileTimeEvalContext<'tcx, 'tcx>, ecx: &CompileTimeEvalContext<'tcx>,
place: &MPlaceTy<'tcx>, place: &MPlaceTy<'tcx>,
num_nodes: &mut usize, num_nodes: &mut usize,
) -> ValTreeCreationResult<'tcx> { ) -> ValTreeCreationResult<'tcx> {
@ -77,7 +77,7 @@ fn slice_branches<'tcx>(
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
fn const_to_valtree_inner<'tcx>( fn const_to_valtree_inner<'tcx>(
ecx: &CompileTimeEvalContext<'tcx, 'tcx>, ecx: &CompileTimeEvalContext<'tcx>,
place: &MPlaceTy<'tcx>, place: &MPlaceTy<'tcx>,
num_nodes: &mut usize, num_nodes: &mut usize,
) -> ValTreeCreationResult<'tcx> { ) -> ValTreeCreationResult<'tcx> {
@ -219,7 +219,7 @@ fn reconstruct_place_meta<'tcx>(
#[instrument(skip(ecx), level = "debug", ret)] #[instrument(skip(ecx), level = "debug", ret)]
fn create_valtree_place<'tcx>( fn create_valtree_place<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, ecx: &mut CompileTimeEvalContext<'tcx>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
valtree: ty::ValTree<'tcx>, valtree: ty::ValTree<'tcx>,
) -> MPlaceTy<'tcx> { ) -> MPlaceTy<'tcx> {
@ -364,7 +364,7 @@ pub fn valtree_to_const_value<'tcx>(
/// Put a valtree into memory and return a reference to that. /// Put a valtree into memory and return a reference to that.
fn valtree_to_ref<'tcx>( fn valtree_to_ref<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, ecx: &mut CompileTimeEvalContext<'tcx>,
valtree: ty::ValTree<'tcx>, valtree: ty::ValTree<'tcx>,
pointee_ty: Ty<'tcx>, pointee_ty: Ty<'tcx>,
) -> Immediate { ) -> Immediate {
@ -380,7 +380,7 @@ fn valtree_to_ref<'tcx>(
#[instrument(skip(ecx), level = "debug")] #[instrument(skip(ecx), level = "debug")]
fn valtree_into_mplace<'tcx>( fn valtree_into_mplace<'tcx>(
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>, ecx: &mut CompileTimeEvalContext<'tcx>,
place: &MPlaceTy<'tcx>, place: &MPlaceTy<'tcx>,
valtree: ty::ValTree<'tcx>, valtree: ty::ValTree<'tcx>,
) { ) {
@ -457,6 +457,6 @@ fn valtree_into_mplace<'tcx>(
} }
} }
fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>) { fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx>, place: &MPlaceTy<'tcx>) {
trace!("{:?}", ecx.dump_place(&PlaceTy::from(place.clone()))); trace!("{:?}", ecx.dump_place(&PlaceTy::from(place.clone())));
} }

View file

@ -19,7 +19,7 @@ use super::{
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
pub fn cast( pub fn cast(
&mut self, &mut self,
src: &OpTy<'tcx, M::Provenance>, src: &OpTy<'tcx, M::Provenance>,
@ -324,13 +324,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
use rustc_type_ir::TyKind::*; use rustc_type_ir::TyKind::*;
fn adjust_nan< fn adjust_nan<
'mir, 'tcx,
'tcx: 'mir, M: Machine<'tcx>,
M: Machine<'mir, 'tcx>,
F1: rustc_apfloat::Float + FloatConvert<F2>, F1: rustc_apfloat::Float + FloatConvert<F2>,
F2: rustc_apfloat::Float, F2: rustc_apfloat::Float,
>( >(
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
f1: F1, f1: F1,
f2: F2, f2: F2,
) -> F2 { ) -> F2 {

View file

@ -12,7 +12,7 @@ use super::{
err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable, err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable,
}; };
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Writes the discriminant of the given variant. /// Writes the discriminant of the given variant.
/// ///
/// If the variant is uninhabited, this is UB. /// If the variant is uninhabited, this is UB.

View file

@ -34,7 +34,7 @@ use crate::errors;
use crate::util; use crate::util;
use crate::{fluent_generated as fluent, ReportErrorExt}; use crate::{fluent_generated as fluent, ReportErrorExt};
pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub struct InterpCx<'tcx, M: Machine<'tcx>> {
/// Stores the `Machine` instance. /// Stores the `Machine` instance.
/// ///
/// Note: the stack is provided by the machine. /// Note: the stack is provided by the machine.
@ -49,7 +49,7 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
pub(crate) param_env: ty::ParamEnv<'tcx>, pub(crate) param_env: ty::ParamEnv<'tcx>,
/// The virtual memory system. /// The virtual memory system.
pub memory: Memory<'mir, 'tcx, M>, pub memory: Memory<'tcx, M>,
/// The recursion limit (cached from `tcx.recursion_limit(())`) /// The recursion limit (cached from `tcx.recursion_limit(())`)
pub recursion_limit: Limit, pub recursion_limit: Limit,
@ -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
@ -345,16 +345,16 @@ impl<'tcx> FrameInfo<'tcx> {
} }
} }
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> HasDataLayout for InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> HasDataLayout for InterpCx<'tcx, M> {
#[inline] #[inline]
fn data_layout(&self) -> &TargetDataLayout { fn data_layout(&self) -> &TargetDataLayout {
&self.tcx.data_layout &self.tcx.data_layout
} }
} }
impl<'mir, 'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'mir, 'tcx, M> impl<'tcx, M> layout::HasTyCtxt<'tcx> for InterpCx<'tcx, M>
where where
M: Machine<'mir, 'tcx>, M: Machine<'tcx>,
{ {
#[inline] #[inline]
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
@ -362,16 +362,16 @@ where
} }
} }
impl<'mir, 'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'mir, 'tcx, M> impl<'tcx, M> layout::HasParamEnv<'tcx> for InterpCx<'tcx, M>
where where
M: Machine<'mir, 'tcx>, M: Machine<'tcx>,
{ {
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.param_env self.param_env
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> LayoutOfHelpers<'tcx> for InterpCx<'tcx, M> {
type LayoutOfResult = InterpResult<'tcx, TyAndLayout<'tcx>>; type LayoutOfResult = InterpResult<'tcx, TyAndLayout<'tcx>>;
#[inline] #[inline]
@ -391,7 +391,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOfHelpers<'tcx> for InterpC
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
type FnAbiOfResult = InterpResult<'tcx, &'tcx FnAbi<'tcx, Ty<'tcx>>>; type FnAbiOfResult = InterpResult<'tcx, &'tcx FnAbi<'tcx, Ty<'tcx>>>;
fn handle_fn_abi_err( fn handle_fn_abi_err(
@ -484,7 +484,7 @@ pub fn format_interp_error<'tcx>(dcx: &DiagCtxt, e: InterpErrorInfo<'tcx>) -> St
s s
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
pub fn new( pub fn new(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
root_span: Span, root_span: Span,
@ -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,17 +534,17 @@ 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")
} }
#[inline(always)] #[inline(always)]
pub fn body(&self) -> &'mir mir::Body<'tcx> { pub fn body(&self) -> &'tcx mir::Body<'tcx> {
self.frame().body self.frame().body
} }
@ -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> {
@ -1205,10 +1203,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
#[must_use] #[must_use]
pub fn dump_place( pub fn dump_place(&self, place: &PlaceTy<'tcx, M::Provenance>) -> PlacePrinter<'_, 'tcx, M> {
&self,
place: &PlaceTy<'tcx, M::Provenance>,
) -> PlacePrinter<'_, 'mir, 'tcx, M> {
PlacePrinter { ecx: self, place: *place.place() } PlacePrinter { ecx: self, place: *place.place() }
} }
@ -1220,14 +1215,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
#[doc(hidden)] #[doc(hidden)]
/// Helper struct for the `dump_place` function. /// Helper struct for the `dump_place` function.
pub struct PlacePrinter<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub struct PlacePrinter<'a, 'tcx, M: Machine<'tcx>> {
ecx: &'a InterpCx<'mir, 'tcx, M>, ecx: &'a InterpCx<'tcx, M>,
place: Place<M::Provenance>, place: Place<M::Provenance>,
} }
impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> std::fmt::Debug impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for PlacePrinter<'a, 'tcx, M> {
for PlacePrinter<'a, 'mir, 'tcx, M>
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.place { match self.place {
Place::Local { local, offset, locals_addr } => { Place::Local { local, offset, locals_addr } => {

View file

@ -29,8 +29,7 @@ use super::{err_ub, AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind
use crate::const_eval; use crate::const_eval;
use crate::errors::NestedStaticInThreadLocal; use crate::errors::NestedStaticInThreadLocal;
pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine< pub trait CompileTimeMachine<'tcx, T> = Machine<
'mir,
'tcx, 'tcx,
MemoryKind = T, MemoryKind = T,
Provenance = CtfeProvenance, Provenance = CtfeProvenance,
@ -46,7 +45,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)
} }
@ -59,8 +58,8 @@ impl HasStaticRootDefId for const_eval::CompileTimeInterpreter<'_, '_> {
/// already mutable (as a sanity check). /// already mutable (as a sanity check).
/// ///
/// Returns an iterator over all relocations referred to by this allocation. /// Returns an iterator over all relocations referred to by this allocation.
fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>( fn intern_shallow<'rt, 'tcx, T, M: CompileTimeMachine<'tcx, T>>(
ecx: &'rt mut InterpCx<'mir, 'tcx, M>, ecx: &'rt mut InterpCx<'tcx, M>,
alloc_id: AllocId, alloc_id: AllocId,
mutability: Mutability, mutability: Mutability,
) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> { ) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> {
@ -146,12 +145,8 @@ pub enum InternResult {
/// ///
/// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller. /// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller.
#[instrument(level = "debug", skip(ecx))] #[instrument(level = "debug", skip(ecx))]
pub fn intern_const_alloc_recursive< pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval::MemoryKind>>(
'mir, ecx: &mut InterpCx<'tcx, M>,
'tcx: 'mir,
M: CompileTimeMachine<'mir, 'tcx, const_eval::MemoryKind>,
>(
ecx: &mut InterpCx<'mir, 'tcx, M>,
intern_kind: InternKind, intern_kind: InternKind,
ret: &MPlaceTy<'tcx>, ret: &MPlaceTy<'tcx>,
) -> Result<(), InternResult> { ) -> Result<(), InternResult> {
@ -290,13 +285,8 @@ pub fn intern_const_alloc_recursive<
/// Intern `ret`. This function assumes that `ret` references no other allocation. /// Intern `ret`. This function assumes that `ret` references no other allocation.
#[instrument(level = "debug", skip(ecx))] #[instrument(level = "debug", skip(ecx))]
pub fn intern_const_alloc_for_constprop< pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
'mir, ecx: &mut InterpCx<'tcx, M>,
'tcx: 'mir,
T,
M: CompileTimeMachine<'mir, 'tcx, T>,
>(
ecx: &mut InterpCx<'mir, 'tcx, M>,
alloc_id: AllocId, alloc_id: AllocId,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
if ecx.tcx.try_get_global_alloc(alloc_id).is_some() { if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
@ -315,19 +305,14 @@ pub fn intern_const_alloc_for_constprop<
Ok(()) Ok(())
} }
impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>> impl<'tcx, M: super::intern::CompileTimeMachine<'tcx, !>> InterpCx<'tcx, M> {
InterpCx<'mir, 'tcx, M>
{
/// A helper function that allocates memory for the layout given and gives you access to mutate /// A helper function that allocates memory for the layout given and gives you access to mutate
/// it. Once your own mutation code is done, the backing `Allocation` is removed from the /// it. Once your own mutation code is done, the backing `Allocation` is removed from the
/// current `Memory` and interned as read-only into the global memory. /// current `Memory` and interned as read-only into the global memory.
pub fn intern_with_temp_alloc( pub fn intern_with_temp_alloc(
&mut self, &mut self,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
f: impl FnOnce( f: impl FnOnce(&mut InterpCx<'tcx, M>, &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx, ()>,
&mut InterpCx<'mir, 'tcx, M>,
&PlaceTy<'tcx, M::Provenance>,
) -> InterpResult<'tcx, ()>,
) -> InterpResult<'tcx, AllocId> { ) -> InterpResult<'tcx, AllocId> {
// `allocate` picks a fresh AllocId that we will associate with its data below. // `allocate` picks a fresh AllocId that we will associate with its data below.
let dest = self.allocate(layout, MemoryKind::Stack)?; let dest = self.allocate(layout, MemoryKind::Stack)?;

View file

@ -98,7 +98,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
}) })
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Returns `true` if emulation happened. /// Returns `true` if emulation happened.
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own /// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
/// intrinsic handling. /// intrinsic handling.
@ -605,9 +605,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Copy `count*size_of::<T>()` many bytes from `*src` to `*dst`. /// Copy `count*size_of::<T>()` many bytes from `*src` to `*dst`.
pub(crate) fn copy_intrinsic( pub(crate) fn copy_intrinsic(
&mut self, &mut self,
src: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, src: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, dst: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, count: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
nonoverlapping: bool, nonoverlapping: bool,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let count = self.read_target_usize(count)?; let count = self.read_target_usize(count)?;
@ -634,8 +634,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Does a *typed* swap of `*left` and `*right`. /// Does a *typed* swap of `*left` and `*right`.
fn typed_swap_intrinsic( fn typed_swap_intrinsic(
&mut self, &mut self,
left: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, left: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
right: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, right: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let left = self.deref_pointer(left)?; let left = self.deref_pointer(left)?;
let right = self.deref_pointer(right)?; let right = self.deref_pointer(right)?;
@ -651,9 +651,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
pub(crate) fn write_bytes_intrinsic( pub(crate) fn write_bytes_intrinsic(
&mut self, &mut self,
dst: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, dst: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
byte: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, byte: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, count: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap())?; let layout = self.layout_of(dst.layout.ty.builtin_deref(true).unwrap())?;
@ -673,9 +673,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
pub(crate) fn compare_bytes_intrinsic( pub(crate) fn compare_bytes_intrinsic(
&mut self, &mut self,
left: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, left: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
right: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, right: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
byte_count: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, byte_count: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
) -> InterpResult<'tcx, Scalar<M::Provenance>> { ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
let left = self.read_pointer(left)?; let left = self.read_pointer(left)?;
let right = self.read_pointer(right)?; let right = self.read_pointer(right)?;
@ -691,14 +691,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
pub(crate) fn raw_eq_intrinsic( pub(crate) fn raw_eq_intrinsic(
&mut self, &mut self,
lhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, lhs: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
rhs: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, rhs: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
) -> InterpResult<'tcx, Scalar<M::Provenance>> { ) -> InterpResult<'tcx, Scalar<M::Provenance>> {
let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap())?; let layout = self.layout_of(lhs.layout.ty.builtin_deref(true).unwrap())?;
assert!(layout.is_sized()); assert!(layout.is_sized());
let get_bytes = |this: &InterpCx<'mir, 'tcx, M>, let get_bytes = |this: &InterpCx<'tcx, M>,
op: &OpTy<'tcx, <M as Machine<'mir, 'tcx>>::Provenance>, op: &OpTy<'tcx, <M as Machine<'tcx>>::Provenance>,
size| size|
-> InterpResult<'tcx, &[u8]> { -> InterpResult<'tcx, &[u8]> {
let ptr = this.read_pointer(op)?; let ptr = this.read_pointer(op)?;

View file

@ -94,7 +94,7 @@ pub trait AllocMap<K: Hash + Eq, V> {
/// Methods of this trait signifies a point where CTFE evaluation would fail /// Methods of this trait signifies a point where CTFE evaluation would fail
/// and some use case dependent behaviour can instead be applied. /// and some use case dependent behaviour can instead be applied.
pub trait Machine<'mir, 'tcx: 'mir>: Sized { pub trait Machine<'tcx>: Sized {
/// Additional memory kinds a machine wishes to distinguish from the builtin ones /// Additional memory kinds a machine wishes to distinguish from the builtin ones
type MemoryKind: Debug + std::fmt::Display + MayLeak + Eq + 'static; type MemoryKind: Debug + std::fmt::Display + MayLeak + Eq + 'static;
@ -145,12 +145,12 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
const ALL_CONSTS_ARE_PRECHECKED: bool = true; const ALL_CONSTS_ARE_PRECHECKED: bool = true;
/// Whether memory accesses should be alignment-checked. /// Whether memory accesses should be alignment-checked.
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; fn enforce_alignment(ecx: &InterpCx<'tcx, Self>) -> bool;
/// Gives the machine a chance to detect more misalignment than the built-in checks would catch. /// Gives the machine a chance to detect more misalignment than the built-in checks would catch.
#[inline(always)] #[inline(always)]
fn alignment_check( fn alignment_check(
_ecx: &InterpCx<'mir, 'tcx, Self>, _ecx: &InterpCx<'tcx, Self>,
_alloc_id: AllocId, _alloc_id: AllocId,
_alloc_align: Align, _alloc_align: Align,
_alloc_kind: AllocKind, _alloc_kind: AllocKind,
@ -161,22 +161,22 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
} }
/// Whether to enforce the validity invariant for a specific layout. /// Whether to enforce the validity invariant for a specific layout.
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool; fn enforce_validity(ecx: &InterpCx<'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool;
/// Whether function calls should be [ABI](CallAbi)-checked. /// Whether function calls should be [ABI](CallAbi)-checked.
fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool { fn enforce_abi(_ecx: &InterpCx<'tcx, Self>) -> bool {
true true
} }
/// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually /// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
/// check for overflow. /// check for overflow.
fn ignore_optional_overflow_checks(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool; fn ignore_optional_overflow_checks(_ecx: &InterpCx<'tcx, Self>) -> bool;
/// Entry point for obtaining the MIR of anything that should get evaluated. /// Entry point for obtaining the MIR of anything that should get evaluated.
/// So not just functions and shims, but also const/static initializers, anonymous /// So not just functions and shims, but also const/static initializers, anonymous
/// constants, ... /// constants, ...
fn load_mir( fn load_mir(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
instance: ty::InstanceDef<'tcx>, instance: ty::InstanceDef<'tcx>,
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
Ok(ecx.tcx.instance_mir(instance)) Ok(ecx.tcx.instance_mir(instance))
@ -193,19 +193,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them /// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
/// was used. /// was used.
fn find_mir_or_eval_fn( fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
abi: CallAbi, abi: CallAbi,
args: &[FnArg<'tcx, Self::Provenance>], args: &[FnArg<'tcx, Self::Provenance>],
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.
fn call_extra_fn( fn call_extra_fn(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
fn_val: Self::ExtraFnVal, fn_val: Self::ExtraFnVal,
abi: CallAbi, abi: CallAbi,
args: &[FnArg<'tcx, Self::Provenance>], args: &[FnArg<'tcx, Self::Provenance>],
@ -220,7 +220,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Returns `None` if the intrinsic was fully handled. /// Returns `None` if the intrinsic was fully handled.
/// Otherwise, returns an `Instance` of the function that implements the intrinsic. /// Otherwise, returns an `Instance` of the function that implements the intrinsic.
fn call_intrinsic( fn call_intrinsic(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Self::Provenance>], args: &[OpTy<'tcx, Self::Provenance>],
destination: &MPlaceTy<'tcx, Self::Provenance>, destination: &MPlaceTy<'tcx, Self::Provenance>,
@ -230,17 +230,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Called to evaluate `Assert` MIR terminators that trigger a panic. /// Called to evaluate `Assert` MIR terminators that trigger a panic.
fn assert_panic( fn assert_panic(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
msg: &mir::AssertMessage<'tcx>, msg: &mir::AssertMessage<'tcx>,
unwind: mir::UnwindAction, unwind: mir::UnwindAction,
) -> InterpResult<'tcx>; ) -> InterpResult<'tcx>;
/// Called to trigger a non-unwinding panic. /// Called to trigger a non-unwinding panic.
fn panic_nounwind(_ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx>; fn panic_nounwind(_ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx>;
/// Called when unwinding reached a state where execution should be terminated. /// Called when unwinding reached a state where execution should be terminated.
fn unwind_terminate( fn unwind_terminate(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
reason: mir::UnwindTerminateReason, reason: mir::UnwindTerminateReason,
) -> InterpResult<'tcx>; ) -> InterpResult<'tcx>;
@ -248,7 +248,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// ///
/// Returns a (value, overflowed) pair if the operation succeeded /// Returns a (value, overflowed) pair if the operation succeeded
fn binary_ptr_op( fn binary_ptr_op(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
bin_op: mir::BinOp, bin_op: mir::BinOp,
left: &ImmTy<'tcx, Self::Provenance>, left: &ImmTy<'tcx, Self::Provenance>,
right: &ImmTy<'tcx, Self::Provenance>, right: &ImmTy<'tcx, Self::Provenance>,
@ -257,7 +257,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Generate the NaN returned by a float operation, given the list of inputs. /// Generate the NaN returned by a float operation, given the list of inputs.
/// (This is all inputs, not just NaN inputs!) /// (This is all inputs, not just NaN inputs!)
fn generate_nan<F1: Float + FloatConvert<F2>, F2: Float>( fn generate_nan<F1: Float + FloatConvert<F2>, F2: Float>(
_ecx: &InterpCx<'mir, 'tcx, Self>, _ecx: &InterpCx<'tcx, Self>,
_inputs: &[F1], _inputs: &[F1],
) -> F2 { ) -> F2 {
// By default we always return the preferred NaN. // By default we always return the preferred NaN.
@ -266,14 +266,14 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Called before a basic block terminator is executed. /// Called before a basic block terminator is executed.
#[inline] #[inline]
fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
/// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction. /// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
/// You can use this to detect long or endlessly running programs. /// You can use this to detect long or endlessly running programs.
#[inline] #[inline]
fn increment_const_eval_counter(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn increment_const_eval_counter(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
@ -293,7 +293,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Return the `AllocId` for the given thread-local static in the current thread. /// Return the `AllocId` for the given thread-local static in the current thread.
fn thread_local_static_pointer( fn thread_local_static_pointer(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
def_id: DefId, def_id: DefId,
) -> InterpResult<'tcx, Pointer<Self::Provenance>> { ) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
throw_unsup!(ThreadLocalStatic(def_id)) throw_unsup!(ThreadLocalStatic(def_id))
@ -301,20 +301,20 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Return the `AllocId` for the given `extern static`. /// Return the `AllocId` for the given `extern static`.
fn extern_static_pointer( fn extern_static_pointer(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
def_id: DefId, def_id: DefId,
) -> InterpResult<'tcx, Pointer<Self::Provenance>>; ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
/// "Int-to-pointer cast" /// "Int-to-pointer cast"
fn ptr_from_addr_cast( fn ptr_from_addr_cast(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
addr: u64, addr: u64,
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>>; ) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>>;
/// Marks a pointer as exposed, allowing it's provenance /// Marks a pointer as exposed, allowing it's provenance
/// to be recovered. "Pointer-to-int cast" /// to be recovered. "Pointer-to-int cast"
fn expose_ptr( fn expose_ptr(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
ptr: Pointer<Self::Provenance>, ptr: Pointer<Self::Provenance>,
) -> InterpResult<'tcx>; ) -> InterpResult<'tcx>;
@ -325,7 +325,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// ///
/// When this fails, that means the pointer does not point to a live allocation. /// When this fails, that means the pointer does not point to a live allocation.
fn ptr_get_alloc( fn ptr_get_alloc(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
ptr: Pointer<Self::Provenance>, ptr: Pointer<Self::Provenance>,
) -> Option<(AllocId, Size, Self::ProvenanceExtra)>; ) -> Option<(AllocId, Size, Self::ProvenanceExtra)>;
@ -345,7 +345,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// cache the result. (This relies on `AllocMap::get_or` being able to add the /// cache the result. (This relies on `AllocMap::get_or` being able to add the
/// owned allocation to the map even when the map is shared.) /// owned allocation to the map even when the map is shared.)
fn adjust_allocation<'b>( fn adjust_allocation<'b>(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
id: AllocId, id: AllocId,
alloc: Cow<'b, Allocation>, alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind<Self::MemoryKind>>, kind: Option<MemoryKind<Self::MemoryKind>>,
@ -359,7 +359,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when /// `kind` is the kind of the allocation the pointer points to; it can be `None` when
/// it's a global and `GLOBAL_KIND` is `None`. /// it's a global and `GLOBAL_KIND` is `None`.
fn adjust_alloc_root_pointer( fn adjust_alloc_root_pointer(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
ptr: Pointer, ptr: Pointer,
kind: Option<MemoryKind<Self::MemoryKind>>, kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Pointer<Self::Provenance>>; ) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
@ -370,7 +370,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
/// `InlineAsmOptions::NORETURN` being set. /// `InlineAsmOptions::NORETURN` being set.
fn eval_inline_asm( fn eval_inline_asm(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_template: &'tcx [InlineAsmTemplatePiece], _template: &'tcx [InlineAsmTemplatePiece],
_operands: &[mir::InlineAsmOperand<'tcx>], _operands: &[mir::InlineAsmOperand<'tcx>],
_options: InlineAsmOptions, _options: InlineAsmOptions,
@ -406,10 +406,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// ///
/// Used to prevent statics from self-initializing by reading from their own memory /// Used to prevent statics from self-initializing by reading from their own memory
/// as it is being initialized. /// as it is being initialized.
fn before_alloc_read( fn before_alloc_read(_ecx: &InterpCx<'tcx, Self>, _alloc_id: AllocId) -> InterpResult<'tcx> {
_ecx: &InterpCx<'mir, 'tcx, Self>,
_alloc_id: AllocId,
) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
@ -444,7 +441,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Returns the possibly adjusted pointer. /// Returns the possibly adjusted pointer.
#[inline] #[inline]
fn retag_ptr_value( fn retag_ptr_value(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_kind: mir::RetagKind, _kind: mir::RetagKind,
val: &ImmTy<'tcx, Self::Provenance>, val: &ImmTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> { ) -> InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
@ -455,7 +452,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Replaces all pointers stored in the given place. /// Replaces all pointers stored in the given place.
#[inline] #[inline]
fn retag_place_contents( fn retag_place_contents(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_kind: mir::RetagKind, _kind: mir::RetagKind,
_place: &PlaceTy<'tcx, Self::Provenance>, _place: &PlaceTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -467,7 +464,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// These places need to be protected to make sure the program cannot tell whether the /// These places need to be protected to make sure the program cannot tell whether the
/// argument/return value was actually copied or passed in-place.. /// argument/return value was actually copied or passed in-place..
fn protect_in_place_function_argument( fn protect_in_place_function_argument(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
mplace: &MPlaceTy<'tcx, Self::Provenance>, mplace: &MPlaceTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Without an aliasing model, all we can do is put `Uninit` into the place. // Without an aliasing model, all we can do is put `Uninit` into the place.
@ -477,29 +474,29 @@ 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<'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<'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<'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<'tcx, Self>) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
/// 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<'tcx, Self>,
_frame: &Frame<'mir, 'tcx, Self::Provenance, Self::FrameExtra>, _frame: &Frame<'tcx, Self::Provenance, Self::FrameExtra>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
Ok(()) Ok(())
} }
@ -508,8 +505,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// The `locals` have already been destroyed! /// The `locals` have already been destroyed!
#[inline(always)] #[inline(always)]
fn after_stack_pop( fn after_stack_pop(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'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
@ -521,7 +518,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// but before the local's stack frame is updated to point to that memory. /// but before the local's stack frame is updated to point to that memory.
#[inline(always)] #[inline(always)]
fn after_local_allocated( fn after_local_allocated(
_ecx: &mut InterpCx<'mir, 'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_local: mir::Local, _local: mir::Local,
_mplace: &MPlaceTy<'tcx, Self::Provenance>, _mplace: &MPlaceTy<'tcx, Self::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -532,7 +529,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// but this hook has the chance to do some pre/postprocessing. /// but this hook has the chance to do some pre/postprocessing.
#[inline(always)] #[inline(always)]
fn eval_mir_constant<F>( fn eval_mir_constant<F>(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
val: mir::Const<'tcx>, val: mir::Const<'tcx>,
span: Span, span: Span,
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
@ -540,7 +537,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
where where
F: Fn( F: Fn(
&InterpCx<'mir, 'tcx, Self>, &InterpCx<'tcx, Self>,
mir::Const<'tcx>, mir::Const<'tcx>,
Span, Span,
Option<TyAndLayout<'tcx>>, Option<TyAndLayout<'tcx>>,
@ -552,7 +549,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines /// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines
/// (CTFE and ConstProp) use the same instance. Here, we share that code. /// (CTFE and ConstProp) use the same instance. Here, we share that code.
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) { pub macro compile_time_machine(<$tcx: lifetime>) {
type Provenance = CtfeProvenance; type Provenance = CtfeProvenance;
type ProvenanceExtra = bool; // the "immutable" flag type ProvenanceExtra = bool; // the "immutable" flag
@ -567,13 +564,13 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
type Bytes = Box<[u8]>; type Bytes = Box<[u8]>;
#[inline(always)] #[inline(always)]
fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool { fn ignore_optional_overflow_checks(_ecx: &InterpCx<$tcx, Self>) -> bool {
false false
} }
#[inline(always)] #[inline(always)]
fn unwind_terminate( fn unwind_terminate(
_ecx: &mut InterpCx<$mir, $tcx, Self>, _ecx: &mut InterpCx<$tcx, Self>,
_reason: mir::UnwindTerminateReason, _reason: mir::UnwindTerminateReason,
) -> InterpResult<$tcx> { ) -> InterpResult<$tcx> {
unreachable!("unwinding cannot happen during compile-time evaluation") unreachable!("unwinding cannot happen during compile-time evaluation")
@ -581,7 +578,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
#[inline(always)] #[inline(always)]
fn call_extra_fn( fn call_extra_fn(
_ecx: &mut InterpCx<$mir, $tcx, Self>, _ecx: &mut InterpCx<$tcx, Self>,
fn_val: !, fn_val: !,
_abi: CallAbi, _abi: CallAbi,
_args: &[FnArg<$tcx>], _args: &[FnArg<$tcx>],
@ -594,7 +591,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
#[inline(always)] #[inline(always)]
fn adjust_allocation<'b>( fn adjust_allocation<'b>(
_ecx: &InterpCx<$mir, $tcx, Self>, _ecx: &InterpCx<$tcx, Self>,
_id: AllocId, _id: AllocId,
alloc: Cow<'b, Allocation>, alloc: Cow<'b, Allocation>,
_kind: Option<MemoryKind<Self::MemoryKind>>, _kind: Option<MemoryKind<Self::MemoryKind>>,
@ -603,7 +600,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
} }
fn extern_static_pointer( fn extern_static_pointer(
ecx: &InterpCx<$mir, $tcx, Self>, ecx: &InterpCx<$tcx, Self>,
def_id: DefId, def_id: DefId,
) -> InterpResult<$tcx, Pointer> { ) -> InterpResult<$tcx, Pointer> {
// Use the `AllocId` associated with the `DefId`. Any actual *access* will fail. // Use the `AllocId` associated with the `DefId`. Any actual *access* will fail.
@ -612,7 +609,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
#[inline(always)] #[inline(always)]
fn adjust_alloc_root_pointer( fn adjust_alloc_root_pointer(
_ecx: &InterpCx<$mir, $tcx, Self>, _ecx: &InterpCx<$tcx, Self>,
ptr: Pointer<CtfeProvenance>, ptr: Pointer<CtfeProvenance>,
_kind: Option<MemoryKind<Self::MemoryKind>>, _kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> { ) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
@ -621,7 +618,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
#[inline(always)] #[inline(always)]
fn ptr_from_addr_cast( fn ptr_from_addr_cast(
_ecx: &InterpCx<$mir, $tcx, Self>, _ecx: &InterpCx<$tcx, Self>,
addr: u64, addr: u64,
) -> InterpResult<$tcx, Pointer<Option<CtfeProvenance>>> { ) -> InterpResult<$tcx, Pointer<Option<CtfeProvenance>>> {
// Allow these casts, but make the pointer not dereferenceable. // Allow these casts, but make the pointer not dereferenceable.
@ -632,7 +629,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
#[inline(always)] #[inline(always)]
fn ptr_get_alloc( fn ptr_get_alloc(
_ecx: &InterpCx<$mir, $tcx, Self>, _ecx: &InterpCx<$tcx, Self>,
ptr: Pointer<CtfeProvenance>, ptr: Pointer<CtfeProvenance>,
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> { ) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
// We know `offset` is relative to the allocation, so we can use `into_parts`. // We know `offset` is relative to the allocation, so we can use `into_parts`.

View file

@ -96,7 +96,7 @@ impl<'tcx, Other> FnVal<'tcx, Other> {
// `Memory` has to depend on the `Machine` because some of its operations // `Memory` has to depend on the `Machine` because some of its operations
// (e.g., `get`) call a `Machine` hook. // (e.g., `get`) call a `Machine` hook.
pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub struct Memory<'tcx, M: Machine<'tcx>> {
/// Allocations local to this instance of the interpreter. The kind /// Allocations local to this instance of the interpreter. The kind
/// helps ensure that the same mechanism is used for allocation and /// helps ensure that the same mechanism is used for allocation and
/// deallocation. When an allocation is not found here, it is a /// deallocation. When an allocation is not found here, it is a
@ -142,7 +142,7 @@ pub struct AllocRefMut<'a, 'tcx, Prov: Provenance, Extra, Bytes: AllocBytes = Bo
alloc_id: AllocId, alloc_id: AllocId,
} }
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> Memory<'tcx, M> {
pub fn new() -> Self { pub fn new() -> Self {
Memory { Memory {
alloc_map: M::MemoryMap::default(), alloc_map: M::MemoryMap::default(),
@ -158,7 +158,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Call this to turn untagged "global" pointers (obtained via `tcx`) into /// Call this to turn untagged "global" pointers (obtained via `tcx`) into
/// the machine pointer to the allocation. Must never be used /// the machine pointer to the allocation. Must never be used
/// for any other pointers, nor for TLS statics. /// for any other pointers, nor for TLS statics.
@ -524,7 +524,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// This function is used by Miri's provenance GC to remove unreachable entries from the dead_alloc_map. /// This function is used by Miri's provenance GC to remove unreachable entries from the dead_alloc_map.
pub fn remove_unreachable_allocs(&mut self, reachable_allocs: &FxHashSet<AllocId>) { pub fn remove_unreachable_allocs(&mut self, reachable_allocs: &FxHashSet<AllocId>) {
// Unlike all the other GC helpers where we check if an `AllocId` is found in the interpreter or // Unlike all the other GC helpers where we check if an `AllocId` is found in the interpreter or
@ -536,7 +536,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
/// Allocation accessors /// Allocation accessors
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Helper function to obtain a global (tcx) allocation. /// Helper function to obtain a global (tcx) allocation.
/// This attempts to return a reference to an existing allocation if /// This attempts to return a reference to an existing allocation if
/// one can be found in `tcx`. That, however, is only possible if `tcx` and /// one can be found in `tcx`. That, however, is only possible if `tcx` and
@ -888,14 +888,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Create a lazy debug printer that prints the given allocation and all allocations it points /// Create a lazy debug printer that prints the given allocation and all allocations it points
/// to, recursively. /// to, recursively.
#[must_use] #[must_use]
pub fn dump_alloc<'a>(&'a self, id: AllocId) -> DumpAllocs<'a, 'mir, 'tcx, M> { pub fn dump_alloc<'a>(&'a self, id: AllocId) -> DumpAllocs<'a, 'tcx, M> {
self.dump_allocs(vec![id]) self.dump_allocs(vec![id])
} }
/// Create a lazy debug printer for a list of allocations and all allocations they point to, /// Create a lazy debug printer for a list of allocations and all allocations they point to,
/// recursively. /// recursively.
#[must_use] #[must_use]
pub fn dump_allocs<'a>(&'a self, mut allocs: Vec<AllocId>) -> DumpAllocs<'a, 'mir, 'tcx, M> { pub fn dump_allocs<'a>(&'a self, mut allocs: Vec<AllocId>) -> DumpAllocs<'a, 'tcx, M> {
allocs.sort(); allocs.sort();
allocs.dedup(); allocs.dedup();
DumpAllocs { ecx: self, allocs } DumpAllocs { ecx: self, allocs }
@ -975,12 +975,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
#[doc(hidden)] #[doc(hidden)]
/// There's no way to use this directly, it's just a helper struct for the `dump_alloc(s)` methods. /// There's no way to use this directly, it's just a helper struct for the `dump_alloc(s)` methods.
pub struct DumpAllocs<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { pub struct DumpAllocs<'a, 'tcx, M: Machine<'tcx>> {
ecx: &'a InterpCx<'mir, 'tcx, M>, ecx: &'a InterpCx<'tcx, M>,
allocs: Vec<AllocId>, allocs: Vec<AllocId>,
} }
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> std::fmt::Debug for DumpAllocs<'a, 'mir, 'tcx, M> { impl<'a, 'tcx, M: Machine<'tcx>> std::fmt::Debug for DumpAllocs<'a, 'tcx, M> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// Cannot be a closure because it is generic in `Prov`, `Extra`. // Cannot be a closure because it is generic in `Prov`, `Extra`.
fn write_allocation_track_relocs<'tcx, Prov: Provenance, Extra, Bytes: AllocBytes>( fn write_allocation_track_relocs<'tcx, Prov: Provenance, Extra, Bytes: AllocBytes>(
@ -1125,7 +1125,7 @@ impl<'tcx, 'a, Prov: Provenance, Extra, Bytes: AllocBytes> AllocRef<'a, 'tcx, Pr
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Reads the given number of bytes from memory, and strips their provenance if possible. /// Reads the given number of bytes from memory, and strips their provenance if possible.
/// Returns them as a slice. /// Returns them as a slice.
/// ///
@ -1338,7 +1338,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
/// Machine pointer introspection. /// Machine pointer introspection.
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Test if this value might be null. /// Test if this value might be null.
/// If the machine does not support ptr-to-int casts, this is conservative. /// If the machine does not support ptr-to-int casts, this is conservative.
pub fn scalar_may_be_null(&self, scalar: Scalar<M::Provenance>) -> InterpResult<'tcx, bool> { pub fn scalar_may_be_null(&self, scalar: Scalar<M::Provenance>) -> InterpResult<'tcx, bool> {

View file

@ -374,21 +374,21 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for ImmTy<'tcx, Prov> {
MemPlaceMeta::None MemPlaceMeta::None
} }
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
_mode: OffsetMode, _mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
assert_matches!(meta, MemPlaceMeta::None); // we can't store this anywhere anyway assert_matches!(meta, MemPlaceMeta::None); // we can't store this anywhere anyway
Ok(self.offset_(offset, layout, ecx)) Ok(self.offset_(offset, layout, ecx))
} }
fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn to_op<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
_ecx: &InterpCx<'mir, 'tcx, M>, _ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
Ok(self.clone().into()) Ok(self.clone().into())
} }
@ -457,13 +457,13 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> {
} }
} }
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
mode: OffsetMode, mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
match self.as_mplace_or_imm() { match self.as_mplace_or_imm() {
Left(mplace) => Ok(mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into()), Left(mplace) => Ok(mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into()),
@ -475,9 +475,9 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for OpTy<'tcx, Prov> {
} }
} }
fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn to_op<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
_ecx: &InterpCx<'mir, 'tcx, M>, _ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
Ok(self.clone()) Ok(self.clone())
} }
@ -509,7 +509,7 @@ impl<'tcx, Prov: Provenance> Readable<'tcx, Prov> for ImmTy<'tcx, Prov> {
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`. /// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`.
/// Returns `None` if the layout does not permit loading this as a value. /// Returns `None` if the layout does not permit loading this as a value.
/// ///

View file

@ -11,7 +11,7 @@ use tracing::trace;
use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine}; use super::{err_ub, throw_ub, ImmTy, InterpCx, Machine};
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
fn three_way_compare<T: Ord>(&self, lhs: T, rhs: T) -> ImmTy<'tcx, M::Provenance> { fn three_way_compare<T: Ord>(&self, lhs: T, rhs: T) -> ImmTy<'tcx, M::Provenance> {
let res = Ord::cmp(&lhs, &rhs); let res = Ord::cmp(&lhs, &rhs);
return ImmTy::from_ordering(res, *self.tcx); return ImmTy::from_ordering(res, *self.tcx);

View file

@ -77,12 +77,12 @@ impl<Prov: Provenance> MemPlace<Prov> {
#[inline] #[inline]
// Not called `offset_with_meta` to avoid confusion with the trait method. // Not called `offset_with_meta` to avoid confusion with the trait method.
fn offset_with_meta_<'mir, 'tcx, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta_<'tcx, M: Machine<'tcx, Provenance = Prov>>(
self, self,
offset: Size, offset: Size,
mode: OffsetMode, mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
debug_assert!( debug_assert!(
!meta.has_meta() || self.meta.has_meta(), !meta.has_meta() || self.meta.has_meta(),
@ -162,20 +162,20 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for MPlaceTy<'tcx, Prov> {
self.mplace.meta self.mplace.meta
} }
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
mode: OffsetMode, mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
Ok(MPlaceTy { mplace: self.mplace.offset_with_meta_(offset, mode, meta, ecx)?, layout }) Ok(MPlaceTy { mplace: self.mplace.offset_with_meta_(offset, mode, meta, ecx)?, layout })
} }
fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn to_op<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
_ecx: &InterpCx<'mir, 'tcx, M>, _ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
Ok(self.clone().into()) Ok(self.clone().into())
} }
@ -274,13 +274,13 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
} }
} }
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
mode: OffsetMode, mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
Ok(match self.as_mplace_or_local() { Ok(match self.as_mplace_or_local() {
Left(mplace) => mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into(), Left(mplace) => mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into(),
@ -305,9 +305,9 @@ impl<'tcx, Prov: Provenance> Projectable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
}) })
} }
fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn to_op<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
ecx.place_to_op(self) ecx.place_to_op(self)
} }
@ -341,9 +341,9 @@ pub trait Writeable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> {
&self, &self,
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)>; ) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)>;
fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
ecx: &mut InterpCx<'mir, 'tcx, M>, ecx: &mut InterpCx<'tcx, M>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>>; ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>>;
} }
@ -357,9 +357,9 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
} }
#[inline(always)] #[inline(always)]
fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
ecx: &mut InterpCx<'mir, 'tcx, M>, ecx: &mut InterpCx<'tcx, M>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> {
ecx.force_allocation(self) ecx.force_allocation(self)
} }
@ -374,19 +374,19 @@ impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for MPlaceTy<'tcx, Prov> {
} }
#[inline(always)] #[inline(always)]
fn force_mplace<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
_ecx: &mut InterpCx<'mir, 'tcx, M>, _ecx: &mut InterpCx<'tcx, M>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> { ) -> InterpResult<'tcx, MPlaceTy<'tcx, Prov>> {
Ok(self.clone()) Ok(self.clone())
} }
} }
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385 // FIXME: Working around https://github.com/rust-lang/rust/issues/54385
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M> impl<'tcx, Prov, M> InterpCx<'tcx, M>
where where
Prov: Provenance, Prov: Provenance,
M: Machine<'mir, 'tcx, Provenance = Prov>, M: Machine<'tcx, Provenance = Prov>,
{ {
pub fn ptr_with_meta_to_mplace( pub fn ptr_with_meta_to_mplace(
&self, &self,

View file

@ -43,9 +43,9 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
fn meta(&self) -> MemPlaceMeta<Prov>; fn meta(&self) -> MemPlaceMeta<Prov>;
/// Get the length of a slice/string/array stored here. /// Get the length of a slice/string/array stored here.
fn len<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn len<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, u64> { ) -> InterpResult<'tcx, u64> {
let layout = self.layout(); let layout = self.layout();
if layout.is_unsized() { if layout.is_unsized() {
@ -65,29 +65,29 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
} }
/// Offset the value by the given amount, replacing the layout and metadata. /// Offset the value by the given amount, replacing the layout and metadata.
fn offset_with_meta<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
mode: OffsetMode, mode: OffsetMode,
meta: MemPlaceMeta<Prov>, meta: MemPlaceMeta<Prov>,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self>; ) -> InterpResult<'tcx, Self>;
fn offset<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn offset<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
offset: Size, offset: Size,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
assert!(layout.is_sized()); assert!(layout.is_sized());
self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx)
} }
fn transmute<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn transmute<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
assert!(self.layout().is_sized() && layout.is_sized()); assert!(self.layout().is_sized() && layout.is_sized());
assert_eq!(self.layout().size, layout.size); assert_eq!(self.layout().size, layout.size);
@ -96,9 +96,9 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
/// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for /// Convert this to an `OpTy`. This might be an irreversible transformation, but is useful for
/// reading from this thing. /// reading from this thing.
fn to_op<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( fn to_op<M: Machine<'tcx, Provenance = Prov>>(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>>; ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>>;
} }
@ -113,9 +113,9 @@ pub struct ArrayIterator<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>>
impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx, 'a, Prov, P> { impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx, 'a, Prov, P> {
/// Should be the same `ecx` on each call, and match the one used to create the iterator. /// Should be the same `ecx` on each call, and match the one used to create the iterator.
pub fn next<'mir, M: Machine<'mir, 'tcx, Provenance = Prov>>( pub fn next<M: Machine<'tcx, Provenance = Prov>>(
&mut self, &mut self,
ecx: &InterpCx<'mir, 'tcx, M>, ecx: &InterpCx<'tcx, M>,
) -> InterpResult<'tcx, Option<(u64, P)>> { ) -> InterpResult<'tcx, Option<(u64, P)>> {
let Some(idx) = self.range.next() else { return Ok(None) }; let Some(idx) = self.range.next() else { return Ok(None) };
// We use `Wrapping` here since the offset has already been checked when the iterator was created. // We use `Wrapping` here since the offset has already been checked when the iterator was created.
@ -133,10 +133,10 @@ impl<'tcx, 'a, Prov: Provenance, P: Projectable<'tcx, Prov>> ArrayIterator<'tcx,
} }
// FIXME: Working around https://github.com/rust-lang/rust/issues/54385 // FIXME: Working around https://github.com/rust-lang/rust/issues/54385
impl<'mir, 'tcx: 'mir, Prov, M> InterpCx<'mir, 'tcx, M> impl<'tcx, Prov, M> InterpCx<'tcx, M>
where where
Prov: Provenance, Prov: Provenance,
M: Machine<'mir, 'tcx, Provenance = Prov>, M: Machine<'tcx, Provenance = Prov>,
{ {
/// Offset a pointer to project to a field of a struct/union. Unlike `place_field`, this is /// Offset a pointer to project to a field of a struct/union. Unlike `place_field`, this is
/// always possible without allocating, so it can take `&self`. Also return the field's layout. /// always possible without allocating, so it can take `&self`. Also return the field's layout.

View file

@ -16,7 +16,7 @@ use super::{
}; };
use crate::util; use crate::util;
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Returns `true` as long as there are more things to do. /// Returns `true` as long as there are more things to do.
/// ///
/// This is used by [priroda](https://github.com/oli-obk/priroda) /// This is used by [priroda](https://github.com/oli-obk/priroda)

View file

@ -46,7 +46,7 @@ impl<'tcx, Prov: Provenance> FnArg<'tcx, Prov> {
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the /// Make a copy of the given fn_arg. Any `InPlace` are degenerated to copies, no protection of the
/// original memory occurs. /// original memory occurs.
pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> { pub fn copy_fn_arg(&self, arg: &FnArg<'tcx, M::Provenance>) -> OpTy<'tcx, M::Provenance> {

View file

@ -7,7 +7,7 @@ use tracing::trace;
use super::util::ensure_monomorphic_enough; use super::util::ensure_monomorphic_enough;
use super::{InterpCx, Machine}; use super::{InterpCx, Machine};
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
/// Creates a dynamic vtable for the given type and vtable origin. This is used only for /// Creates a dynamic vtable for the given type and vtable origin. This is used only for
/// objects. /// objects.
/// ///

View file

@ -82,9 +82,9 @@ 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(
mplace: MPlaceTy<'tcx>, mplace: MPlaceTy<'tcx>,
ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>, ecx: &mut InterpCx<'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;
@ -92,8 +92,8 @@ impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx>
} }
} }
pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>( pub(crate) fn create_static_alloc<'tcx>(
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, ecx: &mut CompileTimeEvalContext<'tcx>,
static_def_id: LocalDefId, static_def_id: LocalDefId,
layout: TyAndLayout<'tcx>, layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx>> { ) -> InterpResult<'tcx, MPlaceTy<'tcx>> {

View file

@ -205,7 +205,7 @@ fn write_path(out: &mut String, path: &[PathElem]) {
} }
} }
struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> { struct ValidityVisitor<'rt, 'tcx, M: Machine<'tcx>> {
/// The `path` may be pushed to, but the part that is present when a function /// The `path` may be pushed to, but the part that is present when a function
/// starts must not be changed! `visit_fields` and `visit_array` rely on /// starts must not be changed! `visit_fields` and `visit_array` rely on
/// this stack discipline. /// this stack discipline.
@ -213,10 +213,10 @@ struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
ref_tracking: Option<&'rt mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>>, ref_tracking: Option<&'rt mut RefTracking<MPlaceTy<'tcx, M::Provenance>, Vec<PathElem>>>,
/// `None` indicates this is not validating for CTFE (but for runtime). /// `None` indicates this is not validating for CTFE (but for runtime).
ctfe_mode: Option<CtfeValidationMode>, ctfe_mode: Option<CtfeValidationMode>,
ecx: &'rt InterpCx<'mir, 'tcx, M>, ecx: &'rt InterpCx<'tcx, M>,
} }
impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> { impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem { fn aggregate_field_path_elem(&mut self, layout: TyAndLayout<'tcx>, field: usize) -> PathElem {
// First, check if we are projecting to a variant. // First, check if we are projecting to a variant.
match layout.variants { match layout.variants {
@ -706,10 +706,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
/// Returns whether the allocation is mutable, and whether it's actually a static. /// Returns whether the allocation is mutable, and whether it's actually a static.
/// For "root" statics we look at the type to account for interior /// For "root" statics we look at the type to account for interior
/// mutability; for nested statics we have no type and directly use the annotated mutability. /// mutability; for nested statics we have no type and directly use the annotated mutability.
fn mutability<'mir, 'tcx: 'mir>( fn mutability<'tcx>(ecx: &InterpCx<'tcx, impl Machine<'tcx>>, alloc_id: AllocId) -> Mutability {
ecx: &InterpCx<'mir, 'tcx, impl Machine<'mir, 'tcx>>,
alloc_id: AllocId,
) -> Mutability {
// Let's see what kind of memory this points to. // Let's see what kind of memory this points to.
// We're not using `try_global_alloc` since dangling pointers have already been handled. // We're not using `try_global_alloc` since dangling pointers have already been handled.
match ecx.tcx.global_alloc(alloc_id) { match ecx.tcx.global_alloc(alloc_id) {
@ -751,13 +748,11 @@ fn mutability<'mir, 'tcx: 'mir>(
} }
} }
impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, 'tcx, M> {
for ValidityVisitor<'rt, 'mir, 'tcx, M>
{
type V = OpTy<'tcx, M::Provenance>; type V = OpTy<'tcx, M::Provenance>;
#[inline(always)] #[inline(always)]
fn ecx(&self) -> &InterpCx<'mir, 'tcx, M> { fn ecx(&self) -> &InterpCx<'tcx, M> {
self.ecx self.ecx
} }
@ -1009,7 +1004,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
} }
} }
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
fn validate_operand_internal( fn validate_operand_internal(
&self, &self,
op: &OpTy<'tcx, M::Provenance>, op: &OpTy<'tcx, M::Provenance>,

View file

@ -13,11 +13,11 @@ use std::num::NonZero;
use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable}; use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable};
/// How to traverse a value and what to do when we are at the leaves. /// How to traverse a value and what to do when we are at the leaves.
pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
type V: Projectable<'tcx, M::Provenance> + From<MPlaceTy<'tcx, M::Provenance>>; type V: Projectable<'tcx, M::Provenance> + From<MPlaceTy<'tcx, M::Provenance>>;
/// The visitor must have an `InterpCx` in it. /// The visitor must have an `InterpCx` in it.
fn ecx(&self) -> &InterpCx<'mir, 'tcx, M>; fn ecx(&self) -> &InterpCx<'tcx, M>;
/// `read_discriminant` can be hooked for better error messages. /// `read_discriminant` can be hooked for better error messages.
#[inline(always)] #[inline(always)]

View file

@ -11,8 +11,8 @@ use crate::const_eval::{mk_eval_cx_to_read_const_val, CanAccessMutGlobal, Compil
use crate::interpret::*; use crate::interpret::*;
/// Allocate a `const core::panic::Location` with the provided filename and line/column numbers. /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
fn alloc_caller_location<'mir, 'tcx>( fn alloc_caller_location<'tcx>(
ecx: &mut CompileTimeEvalContext<'mir, 'tcx>, ecx: &mut CompileTimeEvalContext<'tcx>,
filename: Symbol, filename: Symbol,
line: u32, line: u32,
col: u32, col: u32,

View file

@ -69,7 +69,7 @@ struct ConstAnalysis<'a, 'tcx> {
map: Map, map: Map,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
local_decls: &'a LocalDecls<'tcx>, local_decls: &'a LocalDecls<'tcx>,
ecx: InterpCx<'tcx, 'tcx, DummyMachine>, ecx: InterpCx<'tcx, DummyMachine>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
} }
@ -143,10 +143,9 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
}; };
if let Some(variant_target_idx) = variant_target { if let Some(variant_target_idx) = variant_target {
for (field_index, operand) in operands.iter_enumerated() { for (field_index, operand) in operands.iter_enumerated() {
if let Some(field) = self.map().apply( if let Some(field) =
variant_target_idx, self.map().apply(variant_target_idx, TrackElem::Field(field_index))
TrackElem::Field(field_index), {
) {
self.assign_operand(state, field, operand); self.assign_operand(state, field, operand);
} }
} }
@ -565,7 +564,7 @@ impl<'tcx, 'locals> Collector<'tcx, 'locals> {
fn try_make_constant( fn try_make_constant(
&self, &self,
ecx: &mut InterpCx<'tcx, 'tcx, DummyMachine>, ecx: &mut InterpCx<'tcx, DummyMachine>,
place: Place<'tcx>, place: Place<'tcx>,
state: &State<FlatSet<Scalar>>, state: &State<FlatSet<Scalar>>,
map: &Map, map: &Map,
@ -618,7 +617,7 @@ fn propagatable_scalar(
#[instrument(level = "trace", skip(ecx, state, map))] #[instrument(level = "trace", skip(ecx, state, map))]
fn try_write_constant<'tcx>( fn try_write_constant<'tcx>(
ecx: &mut InterpCx<'_, 'tcx, DummyMachine>, ecx: &mut InterpCx<'tcx, DummyMachine>,
dest: &PlaceTy<'tcx>, dest: &PlaceTy<'tcx>,
place: PlaceIndex, place: PlaceIndex,
ty: Ty<'tcx>, ty: Ty<'tcx>,
@ -836,7 +835,7 @@ impl<'tcx> MutVisitor<'tcx> for Patch<'tcx> {
struct OperandCollector<'tcx, 'map, 'locals, 'a> { struct OperandCollector<'tcx, 'map, 'locals, 'a> {
state: &'a State<FlatSet<Scalar>>, state: &'a State<FlatSet<Scalar>>,
visitor: &'a mut Collector<'tcx, 'locals>, visitor: &'a mut Collector<'tcx, 'locals>,
ecx: &'map mut InterpCx<'tcx, 'tcx, DummyMachine>, ecx: &'map mut InterpCx<'tcx, DummyMachine>,
map: &'map Map, map: &'map Map,
} }

View file

@ -234,7 +234,7 @@ enum Value<'tcx> {
struct VnState<'body, 'tcx> { struct VnState<'body, 'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ecx: InterpCx<'tcx, 'tcx, DummyMachine>, ecx: InterpCx<'tcx, DummyMachine>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
local_decls: &'body LocalDecls<'tcx>, local_decls: &'body LocalDecls<'tcx>,
/// Value stored in each local. /// Value stored in each local.
@ -1139,7 +1139,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
} }
fn op_to_prop_const<'tcx>( fn op_to_prop_const<'tcx>(
ecx: &mut InterpCx<'_, 'tcx, DummyMachine>, ecx: &mut InterpCx<'tcx, DummyMachine>,
op: &OpTy<'tcx>, op: &OpTy<'tcx>,
) -> Option<ConstValue<'tcx>> { ) -> Option<ConstValue<'tcx>> {
// Do not attempt to propagate unsized locals. // Do not attempt to propagate unsized locals.

View file

@ -155,7 +155,7 @@ struct ThreadingOpportunity {
struct TOFinder<'tcx, 'a> { struct TOFinder<'tcx, 'a> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
ecx: InterpCx<'tcx, 'tcx, DummyMachine>, ecx: InterpCx<'tcx, DummyMachine>,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
map: &'a Map, map: &'a Map,
loop_headers: &'a BitSet<BasicBlock>, loop_headers: &'a BitSet<BasicBlock>,

View file

@ -64,7 +64,7 @@ impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
/// Visits MIR nodes, performs const propagation /// Visits MIR nodes, performs const propagation
/// and runs lint checks as it goes /// and runs lint checks as it goes
struct ConstPropagator<'mir, 'tcx> { struct ConstPropagator<'mir, 'tcx> {
ecx: InterpCx<'mir, 'tcx, DummyMachine>, ecx: InterpCx<'tcx, DummyMachine>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
worklist: Vec<BasicBlock>, worklist: Vec<BasicBlock>,

View file

@ -85,7 +85,7 @@ impl GlobalStateInner {
} }
} }
pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) { pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) {
// `exposed` and `int_to_ptr_map` are cleared immediately when an allocation // `exposed` and `int_to_ptr_map` are cleared immediately when an allocation
// is freed, so `base_addr` is the only one we have to clean up based on the GC. // is freed, so `base_addr` is the only one we have to clean up based on the GC.
self.base_addr.retain(|id, _| allocs.is_live(*id)); self.base_addr.retain(|id, _| allocs.is_live(*id));
@ -101,8 +101,8 @@ fn align_addr(addr: u64, align: u64) -> u64 {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Returns the exposed `AllocId` that corresponds to the specified addr, // Returns the exposed `AllocId` that corresponds to the specified addr,
// or `None` if the addr is out of bounds // or `None` if the addr is out of bounds
fn alloc_id_from_addr(&self, addr: u64) -> Option<AllocId> { fn alloc_id_from_addr(&self, addr: u64) -> Option<AllocId> {
@ -234,8 +234,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn expose_ptr(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> { fn expose_ptr(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> {
let ecx = self.eval_context_mut(); let ecx = self.eval_context_mut();
let global_state = ecx.machine.alloc_addresses.get_mut(); let global_state = ecx.machine.alloc_addresses.get_mut();
@ -341,7 +341,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { impl<'tcx> MiriMachine<'tcx> {
pub fn free_alloc_id(&mut self, dead_id: AllocId, size: Size, align: Align, kind: MemoryKind) { pub fn free_alloc_id(&mut self, dead_id: AllocId, size: Size, align: Align, kind: MemoryKind) {
let global_state = self.alloc_addresses.get_mut(); let global_state = self.alloc_addresses.get_mut();
let rng = self.rng.get_mut(); let rng = self.rng.get_mut();

View file

@ -192,7 +192,7 @@ impl GlobalStateInner {
id id
} }
pub fn new_frame(&mut self, machine: &MiriMachine<'_, '_>) -> FrameState { pub fn new_frame(&mut self, machine: &MiriMachine<'_>) -> FrameState {
let call_id = self.next_call_id; let call_id = self.next_call_id;
trace!("new_frame: Assigning call ID {}", call_id); trace!("new_frame: Assigning call ID {}", call_id);
if self.tracked_call_ids.contains(&call_id) { if self.tracked_call_ids.contains(&call_id) {
@ -213,7 +213,7 @@ impl GlobalStateInner {
} }
} }
pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_, '_>) -> BorTag { pub fn root_ptr_tag(&mut self, id: AllocId, machine: &MiriMachine<'_>) -> BorTag {
self.root_ptr_tags.get(&id).copied().unwrap_or_else(|| { self.root_ptr_tags.get(&id).copied().unwrap_or_else(|| {
let tag = self.new_ptr(); let tag = self.new_ptr();
if self.tracked_pointer_tags.contains(&tag) { if self.tracked_pointer_tags.contains(&tag) {
@ -229,7 +229,7 @@ impl GlobalStateInner {
}) })
} }
pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_, '_>) { pub fn remove_unreachable_allocs(&mut self, allocs: &LiveAllocs<'_, '_>) {
self.root_ptr_tags.retain(|id, _| allocs.is_live(*id)); self.root_ptr_tags.retain(|id, _| allocs.is_live(*id));
} }
} }
@ -261,7 +261,7 @@ impl GlobalStateInner {
id: AllocId, id: AllocId,
alloc_size: Size, alloc_size: Size,
kind: MemoryKind, kind: MemoryKind,
machine: &MiriMachine<'_, '_>, machine: &MiriMachine<'_>,
) -> AllocState { ) -> AllocState {
match self.borrow_tracker_method { match self.borrow_tracker_method {
BorrowTrackerMethod::StackedBorrows => BorrowTrackerMethod::StackedBorrows =>
@ -276,8 +276,8 @@ impl GlobalStateInner {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn retag_ptr_value( fn retag_ptr_value(
&mut self, &mut self,
kind: RetagKind, kind: RetagKind,
@ -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();
@ -431,7 +431,7 @@ impl AllocState {
alloc_id: AllocId, alloc_id: AllocId,
prov_extra: ProvenanceExtra, prov_extra: ProvenanceExtra,
range: AllocRange, range: AllocRange,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
match self { match self {
AllocState::StackedBorrows(sb) => AllocState::StackedBorrows(sb) =>
@ -452,7 +452,7 @@ impl AllocState {
alloc_id: AllocId, alloc_id: AllocId,
prov_extra: ProvenanceExtra, prov_extra: ProvenanceExtra,
range: AllocRange, range: AllocRange,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
match self { match self {
AllocState::StackedBorrows(sb) => AllocState::StackedBorrows(sb) =>
@ -473,7 +473,7 @@ impl AllocState {
alloc_id: AllocId, alloc_id: AllocId,
prov_extra: ProvenanceExtra, prov_extra: ProvenanceExtra,
size: Size, size: Size,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
match self { match self {
AllocState::StackedBorrows(sb) => AllocState::StackedBorrows(sb) =>
@ -493,7 +493,7 @@ impl AllocState {
/// Tree Borrows needs to be told when a tag stops being protected. /// Tree Borrows needs to be told when a tag stops being protected.
pub fn release_protector<'tcx>( pub fn release_protector<'tcx>(
&self, &self,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
global: &GlobalState, global: &GlobalState,
tag: BorTag, tag: BorTag,
alloc_id: AllocId, // diagnostics alloc_id: AllocId, // diagnostics

View file

@ -115,29 +115,29 @@ pub struct TagHistory {
pub protected: Option<(String, SpanData)>, pub protected: Option<(String, SpanData)>,
} }
pub struct DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { pub struct DiagnosticCxBuilder<'ecx, 'tcx> {
operation: Operation, operation: Operation,
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
} }
pub struct DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { pub struct DiagnosticCx<'history, 'ecx, 'tcx> {
operation: Operation, operation: Operation,
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
history: &'history mut AllocHistory, history: &'history mut AllocHistory,
offset: Size, offset: Size,
} }
impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { impl<'ecx, 'tcx> DiagnosticCxBuilder<'ecx, 'tcx> {
pub fn build<'history>( pub fn build<'history>(
self, self,
history: &'history mut AllocHistory, history: &'history mut AllocHistory,
offset: Size, offset: Size,
) -> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { ) -> DiagnosticCx<'history, 'ecx, 'tcx> {
DiagnosticCx { operation: self.operation, machine: self.machine, history, offset } DiagnosticCx { operation: self.operation, machine: self.machine, history, offset }
} }
pub fn retag( pub fn retag(
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
info: RetagInfo, info: RetagInfo,
new_tag: BorTag, new_tag: BorTag,
orig_tag: ProvenanceExtra, orig_tag: ProvenanceExtra,
@ -150,7 +150,7 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> {
} }
pub fn read( pub fn read(
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
tag: ProvenanceExtra, tag: ProvenanceExtra,
range: AllocRange, range: AllocRange,
) -> Self { ) -> Self {
@ -159,7 +159,7 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> {
} }
pub fn write( pub fn write(
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
tag: ProvenanceExtra, tag: ProvenanceExtra,
range: AllocRange, range: AllocRange,
) -> Self { ) -> Self {
@ -167,14 +167,14 @@ impl<'ecx, 'mir, 'tcx> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> {
DiagnosticCxBuilder { machine, operation } DiagnosticCxBuilder { machine, operation }
} }
pub fn dealloc(machine: &'ecx MiriMachine<'mir, 'tcx>, tag: ProvenanceExtra) -> Self { pub fn dealloc(machine: &'ecx MiriMachine<'tcx>, tag: ProvenanceExtra) -> Self {
let operation = Operation::Dealloc(DeallocOp { tag }); let operation = Operation::Dealloc(DeallocOp { tag });
DiagnosticCxBuilder { machine, operation } DiagnosticCxBuilder { machine, operation }
} }
} }
impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> {
pub fn unbuild(self) -> DiagnosticCxBuilder<'ecx, 'mir, 'tcx> { pub fn unbuild(self) -> DiagnosticCxBuilder<'ecx, 'tcx> {
DiagnosticCxBuilder { machine: self.machine, operation: self.operation } DiagnosticCxBuilder { machine: self.machine, operation: self.operation }
} }
} }
@ -222,7 +222,7 @@ struct DeallocOp {
} }
impl AllocHistory { impl AllocHistory {
pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_, '_>) -> Self { pub fn new(id: AllocId, item: Item, machine: &MiriMachine<'_>) -> Self {
Self { Self {
id, id,
root: (item, machine.current_span()), root: (item, machine.current_span()),
@ -239,7 +239,7 @@ impl AllocHistory {
} }
} }
impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> { impl<'history, 'ecx, 'tcx> DiagnosticCx<'history, 'ecx, 'tcx> {
pub fn start_grant(&mut self, perm: Permission) { pub fn start_grant(&mut self, perm: Permission) {
let Operation::Retag(op) = &mut self.operation else { let Operation::Retag(op) = &mut self.operation else {
unreachable!( unreachable!(

View file

@ -59,11 +59,7 @@ enum NewPermission {
impl NewPermission { impl NewPermission {
/// A key function: determine the permissions to grant at a retag for the given kind of /// A key function: determine the permissions to grant at a retag for the given kind of
/// reference/pointer. /// reference/pointer.
fn from_ref_ty<'tcx>( fn from_ref_ty<'tcx>(ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>) -> Self {
ty: Ty<'tcx>,
kind: RetagKind,
cx: &crate::MiriInterpCx<'_, 'tcx>,
) -> Self {
let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector); let protector = (kind == RetagKind::FnEntry).then_some(ProtectorKind::StrongProtector);
match ty.kind() { match ty.kind() {
ty::Ref(_, pointee, Mutability::Mut) => { ty::Ref(_, pointee, Mutability::Mut) => {
@ -130,11 +126,7 @@ impl NewPermission {
} }
} }
fn from_box_ty<'tcx>( fn from_box_ty<'tcx>(ty: Ty<'tcx>, kind: RetagKind, cx: &crate::MiriInterpCx<'tcx>) -> Self {
ty: Ty<'tcx>,
kind: RetagKind,
cx: &crate::MiriInterpCx<'_, 'tcx>,
) -> Self {
// `ty` is not the `Box` but the field of the Box with this pointer (due to allocator handling). // `ty` is not the `Box` but the field of the Box with this pointer (due to allocator handling).
let pointee = ty.builtin_deref(true).unwrap(); let pointee = ty.builtin_deref(true).unwrap();
if pointee.is_unpin(*cx.tcx, cx.param_env()) { if pointee.is_unpin(*cx.tcx, cx.param_env()) {
@ -230,7 +222,7 @@ impl<'tcx> Stack {
fn item_invalidated( fn item_invalidated(
item: &Item, item: &Item,
global: &GlobalStateInner, global: &GlobalStateInner,
dcx: &DiagnosticCx<'_, '_, '_, 'tcx>, dcx: &DiagnosticCx<'_, '_, 'tcx>,
cause: ItemInvalidationCause, cause: ItemInvalidationCause,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
if !global.tracked_pointer_tags.is_empty() { if !global.tracked_pointer_tags.is_empty() {
@ -275,7 +267,7 @@ impl<'tcx> Stack {
access: AccessKind, access: AccessKind,
tag: ProvenanceExtra, tag: ProvenanceExtra,
global: &GlobalStateInner, global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, dcx: &mut DiagnosticCx<'_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>, exposed_tags: &FxHashSet<BorTag>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Two main steps: Find granting item, remove incompatible items above. // Two main steps: Find granting item, remove incompatible items above.
@ -362,7 +354,7 @@ impl<'tcx> Stack {
&mut self, &mut self,
tag: ProvenanceExtra, tag: ProvenanceExtra,
global: &GlobalStateInner, global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, dcx: &mut DiagnosticCx<'_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>, exposed_tags: &FxHashSet<BorTag>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Step 1: Make a write access. // Step 1: Make a write access.
@ -387,7 +379,7 @@ impl<'tcx> Stack {
new: Item, new: Item,
access: Option<AccessKind>, access: Option<AccessKind>,
global: &GlobalStateInner, global: &GlobalStateInner,
dcx: &mut DiagnosticCx<'_, '_, '_, 'tcx>, dcx: &mut DiagnosticCx<'_, '_, 'tcx>,
exposed_tags: &FxHashSet<BorTag>, exposed_tags: &FxHashSet<BorTag>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
dcx.start_grant(new.perm()); dcx.start_grant(new.perm());
@ -471,7 +463,7 @@ impl<'tcx> Stacks {
perm: Permission, perm: Permission,
tag: BorTag, tag: BorTag,
id: AllocId, id: AllocId,
machine: &MiriMachine<'_, '_>, machine: &MiriMachine<'_>,
) -> Self { ) -> Self {
let item = Item::new(tag, perm, false); let item = Item::new(tag, perm, false);
let stack = Stack::new(item); let stack = Stack::new(item);
@ -487,10 +479,10 @@ impl<'tcx> Stacks {
fn for_each( fn for_each(
&mut self, &mut self,
range: AllocRange, range: AllocRange,
mut dcx_builder: DiagnosticCxBuilder<'_, '_, 'tcx>, mut dcx_builder: DiagnosticCxBuilder<'_, 'tcx>,
mut f: impl FnMut( mut f: impl FnMut(
&mut Stack, &mut Stack,
&mut DiagnosticCx<'_, '_, '_, 'tcx>, &mut DiagnosticCx<'_, '_, 'tcx>,
&mut FxHashSet<BorTag>, &mut FxHashSet<BorTag>,
) -> InterpResult<'tcx>, ) -> InterpResult<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -510,7 +502,7 @@ impl Stacks {
size: Size, size: Size,
state: &mut GlobalStateInner, state: &mut GlobalStateInner,
kind: MemoryKind, kind: MemoryKind,
machine: &MiriMachine<'_, '_>, machine: &MiriMachine<'_>,
) -> Self { ) -> Self {
let (base_tag, perm) = match kind { let (base_tag, perm) = match kind {
// New unique borrow. This tag is not accessible by the program, // New unique borrow. This tag is not accessible by the program,
@ -526,12 +518,12 @@ impl Stacks {
} }
#[inline(always)] #[inline(always)]
pub fn before_memory_read<'tcx, 'mir, 'ecx>( pub fn before_memory_read<'ecx, 'tcx>(
&mut self, &mut self,
alloc_id: AllocId, alloc_id: AllocId,
tag: ProvenanceExtra, tag: ProvenanceExtra,
range: AllocRange, range: AllocRange,
machine: &'ecx MiriMachine<'mir, 'tcx>, machine: &'ecx MiriMachine<'tcx>,
) -> InterpResult<'tcx> ) -> InterpResult<'tcx>
where where
'tcx: 'ecx, 'tcx: 'ecx,
@ -555,7 +547,7 @@ impl Stacks {
alloc_id: AllocId, alloc_id: AllocId,
tag: ProvenanceExtra, tag: ProvenanceExtra,
range: AllocRange, range: AllocRange,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
trace!( trace!(
"write access with tag {:?}: {:?}, size {}", "write access with tag {:?}: {:?}, size {}",
@ -576,7 +568,7 @@ impl Stacks {
alloc_id: AllocId, alloc_id: AllocId,
tag: ProvenanceExtra, tag: ProvenanceExtra,
size: Size, size: Size,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
trace!("deallocation with tag {:?}: {:?}, size {}", tag, alloc_id, size.bytes()); trace!("deallocation with tag {:?}: {:?}, size {}", tag, alloc_id, size.bytes());
let dcx = DiagnosticCxBuilder::dealloc(machine, tag); let dcx = DiagnosticCxBuilder::dealloc(machine, tag);
@ -590,11 +582,8 @@ impl Stacks {
/// Retagging/reborrowing. There is some policy in here, such as which permissions /// Retagging/reborrowing. There is some policy in here, such as which permissions
/// to grant for which references, and when to add protectors. /// to grant for which references, and when to add protectors.
impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx> impl<'tcx, 'ecx> EvalContextPrivExt<'tcx, 'ecx> for crate::MiriInterpCx<'tcx> {}
for crate::MiriInterpCx<'mir, 'tcx> trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
{
}
trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Returns the provenance that should be used henceforth. /// Returns the provenance that should be used henceforth.
fn sb_reborrow( fn sb_reborrow(
&mut self, &mut self,
@ -609,7 +598,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
this.check_ptr_access(place.ptr(), size, CheckInAllocMsg::InboundsTest)?; this.check_ptr_access(place.ptr(), size, CheckInAllocMsg::InboundsTest)?;
// It is crucial that this gets called on all code paths, to ensure we track tag creation. // It is crucial that this gets called on all code paths, to ensure we track tag creation.
let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, let log_creation = |this: &MiriInterpCx<'tcx>,
loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag
-> InterpResult<'tcx> { -> InterpResult<'tcx> {
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
@ -861,8 +850,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn sb_retag_ptr_value( fn sb_retag_ptr_value(
&mut self, &mut self,
kind: RetagKind, kind: RetagKind,
@ -895,14 +884,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
return visitor.visit_value(place); return visitor.visit_value(place);
// The actual visitor. // The actual visitor.
struct RetagVisitor<'ecx, 'mir, 'tcx> { struct RetagVisitor<'ecx, 'tcx> {
ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>, ecx: &'ecx mut MiriInterpCx<'tcx>,
kind: RetagKind, kind: RetagKind,
retag_cause: RetagCause, retag_cause: RetagCause,
retag_fields: RetagFields, retag_fields: RetagFields,
in_field: bool, in_field: bool,
} }
impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> { impl<'ecx, 'tcx> RetagVisitor<'ecx, 'tcx> {
#[inline(always)] // yes this helps in our benchmarks #[inline(always)] // yes this helps in our benchmarks
fn retag_ptr_inplace( fn retag_ptr_inplace(
&mut self, &mut self,
@ -919,13 +908,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
Ok(()) Ok(())
} }
} }
impl<'ecx, 'mir, 'tcx> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> {
for RetagVisitor<'ecx, 'mir, 'tcx>
{
type V = PlaceTy<'tcx, Provenance>; type V = PlaceTy<'tcx, Provenance>;
#[inline(always)] #[inline(always)]
fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { fn ecx(&self) -> &MiriInterpCx<'tcx> {
self.ecx self.ecx
} }

View file

@ -35,7 +35,7 @@ impl<'tcx> Tree {
size: Size, size: Size,
state: &mut GlobalStateInner, state: &mut GlobalStateInner,
_kind: MemoryKind, _kind: MemoryKind,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> Self { ) -> Self {
let tag = state.root_ptr_tag(id, machine); // Fresh tag for the root let tag = state.root_ptr_tag(id, machine); // Fresh tag for the root
let span = machine.current_span(); let span = machine.current_span();
@ -50,7 +50,7 @@ impl<'tcx> Tree {
alloc_id: AllocId, alloc_id: AllocId,
prov: ProvenanceExtra, prov: ProvenanceExtra,
range: AllocRange, range: AllocRange,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
trace!( trace!(
"{} with tag {:?}: {:?}, size {}", "{} with tag {:?}: {:?}, size {}",
@ -84,7 +84,7 @@ impl<'tcx> Tree {
alloc_id: AllocId, alloc_id: AllocId,
prov: ProvenanceExtra, prov: ProvenanceExtra,
size: Size, size: Size,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// TODO: for now we bail out on wildcard pointers. Eventually we should // TODO: for now we bail out on wildcard pointers. Eventually we should
// handle them as much as we can. // handle them as much as we can.
@ -109,7 +109,7 @@ impl<'tcx> Tree {
/// protector. /// protector.
pub fn release_protector( pub fn release_protector(
&mut self, &mut self,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
global: &GlobalState, global: &GlobalState,
tag: BorTag, tag: BorTag,
alloc_id: AllocId, // diagnostics alloc_id: AllocId, // diagnostics
@ -146,7 +146,7 @@ impl<'tcx> NewPermission {
pointee: Ty<'tcx>, pointee: Ty<'tcx>,
mutability: Mutability, mutability: Mutability,
kind: RetagKind, kind: RetagKind,
cx: &crate::MiriInterpCx<'_, 'tcx>, cx: &crate::MiriInterpCx<'tcx>,
) -> Option<Self> { ) -> Option<Self> {
let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.param_env()); let ty_is_freeze = pointee.is_freeze(*cx.tcx, cx.param_env());
let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.param_env()); let ty_is_unpin = pointee.is_unpin(*cx.tcx, cx.param_env());
@ -170,7 +170,7 @@ impl<'tcx> NewPermission {
fn from_unique_ty( fn from_unique_ty(
ty: Ty<'tcx>, ty: Ty<'tcx>,
kind: RetagKind, kind: RetagKind,
cx: &crate::MiriInterpCx<'_, 'tcx>, cx: &crate::MiriInterpCx<'tcx>,
zero_size: bool, zero_size: bool,
) -> Option<Self> { ) -> Option<Self> {
let pointee = ty.builtin_deref(true).unwrap(); let pointee = ty.builtin_deref(true).unwrap();
@ -190,11 +190,8 @@ impl<'tcx> NewPermission {
/// Retagging/reborrowing. /// Retagging/reborrowing.
/// Policy on which permission to grant to each pointer should be left to /// Policy on which permission to grant to each pointer should be left to
/// the implementation of NewPermission. /// the implementation of NewPermission.
impl<'mir: 'ecx, 'tcx: 'mir, 'ecx> EvalContextPrivExt<'mir, 'tcx, 'ecx> impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {}
for crate::MiriInterpCx<'mir, 'tcx> trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
{
}
trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Returns the provenance that should be used henceforth. /// Returns the provenance that should be used henceforth.
fn tb_reborrow( fn tb_reborrow(
&mut self, &mut self,
@ -210,7 +207,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::InboundsTest)?; this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::InboundsTest)?;
// It is crucial that this gets called on all code paths, to ensure we track tag creation. // It is crucial that this gets called on all code paths, to ensure we track tag creation.
let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, let log_creation = |this: &MiriInterpCx<'tcx>,
loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag loc: Option<(AllocId, Size, ProvenanceExtra)>| // alloc_id, base_offset, orig_tag
-> InterpResult<'tcx> { -> InterpResult<'tcx> {
let global = this.machine.borrow_tracker.as_ref().unwrap().borrow(); let global = this.machine.borrow_tracker.as_ref().unwrap().borrow();
@ -379,8 +376,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Retag a pointer. References are passed to `from_ref_ty` and /// Retag a pointer. References are passed to `from_ref_ty` and
/// raw pointers are never reborrowed. /// raw pointers are never reborrowed.
fn tb_retag_ptr_value( fn tb_retag_ptr_value(
@ -416,13 +413,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
return visitor.visit_value(place); return visitor.visit_value(place);
// The actual visitor. // The actual visitor.
struct RetagVisitor<'ecx, 'mir, 'tcx> { struct RetagVisitor<'ecx, 'tcx> {
ecx: &'ecx mut MiriInterpCx<'mir, 'tcx>, ecx: &'ecx mut MiriInterpCx<'tcx>,
kind: RetagKind, kind: RetagKind,
retag_fields: RetagFields, retag_fields: RetagFields,
unique_did: Option<DefId>, unique_did: Option<DefId>,
} }
impl<'ecx, 'mir, 'tcx> RetagVisitor<'ecx, 'mir, 'tcx> { impl<'ecx, 'tcx> RetagVisitor<'ecx, 'tcx> {
#[inline(always)] // yes this helps in our benchmarks #[inline(always)] // yes this helps in our benchmarks
fn retag_ptr_inplace( fn retag_ptr_inplace(
&mut self, &mut self,
@ -437,13 +434,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
Ok(()) Ok(())
} }
} }
impl<'ecx, 'mir, 'tcx> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> {
for RetagVisitor<'ecx, 'mir, 'tcx>
{
type V = PlaceTy<'tcx, Provenance>; type V = PlaceTy<'tcx, Provenance>;
#[inline(always)] #[inline(always)]
fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { fn ecx(&self) -> &MiriInterpCx<'tcx> {
self.ecx self.ecx
} }
@ -608,7 +603,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// I.e. input is what you get from the visitor upon encountering an `adt` that is `Unique`, /// I.e. input is what you get from the visitor upon encountering an `adt` that is `Unique`,
/// and output can be used by `retag_ptr_inplace`. /// and output can be used by `retag_ptr_inplace`.
fn inner_ptr_of_unique<'tcx>( fn inner_ptr_of_unique<'tcx>(
ecx: &MiriInterpCx<'_, 'tcx>, ecx: &MiriInterpCx<'tcx>,
place: &PlaceTy<'tcx, Provenance>, place: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> { ) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> {
// Follows the same layout as `interpret/visitor.rs:walk_value` for `Box` in // Follows the same layout as `interpret/visitor.rs:walk_value` for `Box` in

View file

@ -601,8 +601,8 @@ impl MemoryCellClocks {
} }
/// Evaluation context extensions. /// Evaluation context extensions.
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
/// Perform an atomic read operation at the memory location. /// Perform an atomic read operation at the memory location.
fn read_scalar_atomic( fn read_scalar_atomic(
&self, &self,
@ -828,7 +828,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
/// with this program point. /// with this program point.
fn release_clock<'a>(&'a self) -> Option<Ref<'a, VClock>> fn release_clock<'a>(&'a self) -> Option<Ref<'a, VClock>>
where where
'mir: 'a, 'tcx: 'a,
{ {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
Some(this.machine.data_race.as_ref()?.release_clock(&this.machine.threads)) Some(this.machine.data_race.as_ref()?.release_clock(&this.machine.threads))
@ -861,7 +861,7 @@ impl VClockAlloc {
/// Create a new data-race detector for newly allocated memory. /// Create a new data-race detector for newly allocated memory.
pub fn new_allocation( pub fn new_allocation(
global: &GlobalState, global: &GlobalState,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
len: Size, len: Size,
kind: MemoryKind, kind: MemoryKind,
current_span: Span, current_span: Span,
@ -944,7 +944,7 @@ impl VClockAlloc {
#[inline(never)] #[inline(never)]
fn report_data_race<'tcx>( fn report_data_race<'tcx>(
global: &GlobalState, global: &GlobalState,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
mem_clocks: &MemoryCellClocks, mem_clocks: &MemoryCellClocks,
access: AccessType, access: AccessType,
access_size: Size, access_size: Size,
@ -1042,7 +1042,7 @@ impl VClockAlloc {
access_range: AllocRange, access_range: AllocRange,
read_type: NaReadType, read_type: NaReadType,
ty: Option<Ty<'_>>, ty: Option<Ty<'_>>,
machine: &MiriMachine<'_, '_>, machine: &MiriMachine<'_>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let current_span = machine.current_span(); let current_span = machine.current_span();
let global = machine.data_race.as_ref().unwrap(); let global = machine.data_race.as_ref().unwrap();
@ -1085,7 +1085,7 @@ impl VClockAlloc {
access_range: AllocRange, access_range: AllocRange,
write_type: NaWriteType, write_type: NaWriteType,
ty: Option<Ty<'_>>, ty: Option<Ty<'_>>,
machine: &mut MiriMachine<'_, '_>, machine: &mut MiriMachine<'_>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let current_span = machine.current_span(); let current_span = machine.current_span();
let global = machine.data_race.as_mut().unwrap(); let global = machine.data_race.as_mut().unwrap();
@ -1120,8 +1120,8 @@ impl VClockAlloc {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
/// Temporarily allow data-races to occur. This should only be used in /// Temporarily allow data-races to occur. This should only be used in
/// one of these cases: /// one of these cases:
/// - One of the appropriate `validate_atomic` functions will be called to /// - One of the appropriate `validate_atomic` functions will be called to
@ -1130,7 +1130,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
/// cannot be accessed by the interpreted program. /// cannot be accessed by the interpreted program.
/// - Execution of the interpreted program execution has halted. /// - Execution of the interpreted program execution has halted.
#[inline] #[inline]
fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriInterpCx<'mir, 'tcx>) -> R) -> R { fn allow_data_races_ref<R>(&self, op: impl FnOnce(&MiriInterpCx<'tcx>) -> R) -> R {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
if let Some(data_race) = &this.machine.data_race { if let Some(data_race) = &this.machine.data_race {
let old = data_race.ongoing_action_data_race_free.replace(true); let old = data_race.ongoing_action_data_race_free.replace(true);
@ -1147,10 +1147,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
/// so should only be used for atomic operations or internal state that the program cannot /// so should only be used for atomic operations or internal state that the program cannot
/// access. /// access.
#[inline] #[inline]
fn allow_data_races_mut<R>( fn allow_data_races_mut<R>(&mut self, op: impl FnOnce(&mut MiriInterpCx<'tcx>) -> R) -> R {
&mut self,
op: impl FnOnce(&mut MiriInterpCx<'mir, 'tcx>) -> R,
) -> R {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
if let Some(data_race) = &this.machine.data_race { if let Some(data_race) = &this.machine.data_race {
let old = data_race.ongoing_action_data_race_free.replace(true); let old = data_race.ongoing_action_data_race_free.replace(true);
@ -1523,7 +1520,7 @@ impl GlobalState {
#[inline] #[inline]
pub fn thread_created( pub fn thread_created(
&mut self, &mut self,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
thread: ThreadId, thread: ThreadId,
current_span: Span, current_span: Span,
) { ) {
@ -1591,7 +1588,7 @@ impl GlobalState {
/// thread (the joinee, the thread that someone waited on) and the current thread (the joiner, /// thread (the joinee, the thread that someone waited on) and the current thread (the joiner,
/// the thread who was waiting). /// the thread who was waiting).
#[inline] #[inline]
pub fn thread_joined(&mut self, threads: &ThreadManager<'_, '_>, joinee: ThreadId) { pub fn thread_joined(&mut self, threads: &ThreadManager<'_>, joinee: ThreadId) {
let thread_info = self.thread_info.borrow(); let thread_info = self.thread_info.borrow();
let thread_info = &thread_info[joinee]; let thread_info = &thread_info[joinee];
@ -1633,7 +1630,7 @@ impl GlobalState {
/// This should be called strictly before any calls to /// This should be called strictly before any calls to
/// `thread_joined`. /// `thread_joined`.
#[inline] #[inline]
pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_, '_>) { pub fn thread_terminated(&mut self, thread_mgr: &ThreadManager<'_>) {
let current_thread = thread_mgr.active_thread(); let current_thread = thread_mgr.active_thread();
let current_index = self.active_thread_index(thread_mgr); let current_index = self.active_thread_index(thread_mgr);
@ -1656,7 +1653,7 @@ impl GlobalState {
/// operation may create. /// operation may create.
fn maybe_perform_sync_operation<'tcx>( fn maybe_perform_sync_operation<'tcx>(
&self, &self,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
current_span: Span, current_span: Span,
op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool>, op: impl FnOnce(VectorIdx, RefMut<'_, ThreadClockSet>) -> InterpResult<'tcx, bool>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -1672,11 +1669,7 @@ impl GlobalState {
/// Internal utility to identify a thread stored internally /// Internal utility to identify a thread stored internally
/// returns the id and the name for better diagnostics. /// returns the id and the name for better diagnostics.
fn print_thread_metadata( fn print_thread_metadata(&self, thread_mgr: &ThreadManager<'_>, vector: VectorIdx) -> String {
&self,
thread_mgr: &ThreadManager<'_, '_>,
vector: VectorIdx,
) -> String {
let thread = self.vector_info.borrow()[vector]; let thread = self.vector_info.borrow()[vector];
let thread_name = thread_mgr.get_thread_display_name(thread); let thread_name = thread_mgr.get_thread_display_name(thread);
format!("thread `{thread_name}`") format!("thread `{thread_name}`")
@ -1686,7 +1679,7 @@ impl GlobalState {
/// the moment when that clock snapshot was taken via `release_clock`. /// the moment when that clock snapshot was taken via `release_clock`.
/// As this is an acquire operation, the thread timestamp is not /// As this is an acquire operation, the thread timestamp is not
/// incremented. /// incremented.
pub fn acquire_clock<'mir, 'tcx>(&self, clock: &VClock, threads: &ThreadManager<'mir, 'tcx>) { pub fn acquire_clock<'tcx>(&self, clock: &VClock, threads: &ThreadManager<'tcx>) {
let thread = threads.active_thread(); let thread = threads.active_thread();
let (_, mut clocks) = self.thread_state_mut(thread); let (_, mut clocks) = self.thread_state_mut(thread);
clocks.clock.join(clock); clocks.clock.join(clock);
@ -1695,10 +1688,7 @@ impl GlobalState {
/// Returns the `release` clock of the current thread. /// Returns the `release` clock of the current thread.
/// Other threads can acquire this clock in the future to establish synchronization /// Other threads can acquire this clock in the future to establish synchronization
/// with this program point. /// with this program point.
pub fn release_clock<'mir, 'tcx>( pub fn release_clock<'tcx>(&self, threads: &ThreadManager<'tcx>) -> Ref<'_, VClock> {
&self,
threads: &ThreadManager<'mir, 'tcx>,
) -> Ref<'_, VClock> {
let thread = threads.active_thread(); let thread = threads.active_thread();
let span = threads.active_thread_ref().current_span(); let span = threads.active_thread_ref().current_span();
// We increment the clock each time this happens, to ensure no two releases // We increment the clock each time this happens, to ensure no two releases
@ -1741,7 +1731,7 @@ impl GlobalState {
#[inline] #[inline]
pub(super) fn active_thread_state( pub(super) fn active_thread_state(
&self, &self,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
) -> (VectorIdx, Ref<'_, ThreadClockSet>) { ) -> (VectorIdx, Ref<'_, ThreadClockSet>) {
self.thread_state(thread_mgr.active_thread()) self.thread_state(thread_mgr.active_thread())
} }
@ -1751,7 +1741,7 @@ impl GlobalState {
#[inline] #[inline]
pub(super) fn active_thread_state_mut( pub(super) fn active_thread_state_mut(
&self, &self,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
) -> (VectorIdx, RefMut<'_, ThreadClockSet>) { ) -> (VectorIdx, RefMut<'_, ThreadClockSet>) {
self.thread_state_mut(thread_mgr.active_thread()) self.thread_state_mut(thread_mgr.active_thread())
} }
@ -1759,19 +1749,19 @@ impl GlobalState {
/// Return the current thread, should be the same /// Return the current thread, should be the same
/// as the data-race active thread. /// as the data-race active thread.
#[inline] #[inline]
fn active_thread_index(&self, thread_mgr: &ThreadManager<'_, '_>) -> VectorIdx { fn active_thread_index(&self, thread_mgr: &ThreadManager<'_>) -> VectorIdx {
let active_thread_id = thread_mgr.active_thread(); let active_thread_id = thread_mgr.active_thread();
self.thread_index(active_thread_id) self.thread_index(active_thread_id)
} }
// SC ATOMIC STORE rule in the paper. // SC ATOMIC STORE rule in the paper.
pub(super) fn sc_write(&self, thread_mgr: &ThreadManager<'_, '_>) { pub(super) fn sc_write(&self, thread_mgr: &ThreadManager<'_>) {
let (index, clocks) = self.active_thread_state(thread_mgr); let (index, clocks) = self.active_thread_state(thread_mgr);
self.last_sc_write.borrow_mut().set_at_index(&clocks.clock, index); self.last_sc_write.borrow_mut().set_at_index(&clocks.clock, index);
} }
// SC ATOMIC READ rule in the paper. // SC ATOMIC READ rule in the paper.
pub(super) fn sc_read(&self, thread_mgr: &ThreadManager<'_, '_>) { pub(super) fn sc_read(&self, thread_mgr: &ThreadManager<'_>) {
let (.., mut clocks) = self.active_thread_state_mut(thread_mgr); let (.., mut clocks) = self.active_thread_state_mut(thread_mgr);
clocks.read_seqcst.join(&self.last_sc_fence.borrow()); clocks.read_seqcst.join(&self.last_sc_fence.borrow());
} }

View file

@ -26,15 +26,15 @@ pub(super) struct InitOnce {
clock: VClock, clock: VClock,
} }
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Provides the closure with the next InitOnceId. Creates that InitOnce if the closure returns None, /// Provides the closure with the next InitOnceId. Creates that InitOnce if the closure returns None,
/// otherwise returns the value from the closure. /// otherwise returns the value from the closure.
#[inline] #[inline]
fn init_once_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, InitOnceId> fn init_once_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, InitOnceId>
where where
F: FnOnce( F: FnOnce(
&mut MiriInterpCx<'mir, 'tcx>, &mut MiriInterpCx<'tcx>,
InitOnceId, InitOnceId,
) -> InterpResult<'tcx, Option<InitOnceId>>, ) -> InterpResult<'tcx, Option<InitOnceId>>,
{ {
@ -50,8 +50,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn init_once_get_or_create_id( fn init_once_get_or_create_id(
&mut self, &mut self,
lock_op: &OpTy<'tcx, Provenance>, lock_op: &OpTy<'tcx, Provenance>,

View file

@ -159,9 +159,9 @@ pub struct SynchronizationObjects {
} }
// Private extension trait for local helper methods // Private extension trait for local helper methods
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExtPriv<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
/// Lazily initialize the ID of this Miri sync structure. /// Lazily initialize the ID of this Miri sync structure.
/// ('0' indicates uninit.) /// ('0' indicates uninit.)
@ -202,7 +202,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
#[inline] #[inline]
fn mutex_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, MutexId> fn mutex_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, MutexId>
where where
F: FnOnce(&mut MiriInterpCx<'mir, 'tcx>, MutexId) -> InterpResult<'tcx, Option<MutexId>>, F: FnOnce(&mut MiriInterpCx<'tcx>, MutexId) -> InterpResult<'tcx, Option<MutexId>>,
{ {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
let next_index = this.machine.sync.mutexes.next_index(); let next_index = this.machine.sync.mutexes.next_index();
@ -223,7 +223,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
#[inline] #[inline]
fn rwlock_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, RwLockId> fn rwlock_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, RwLockId>
where where
F: FnOnce(&mut MiriInterpCx<'mir, 'tcx>, RwLockId) -> InterpResult<'tcx, Option<RwLockId>>, F: FnOnce(&mut MiriInterpCx<'tcx>, RwLockId) -> InterpResult<'tcx, Option<RwLockId>>,
{ {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
let next_index = this.machine.sync.rwlocks.next_index(); let next_index = this.machine.sync.rwlocks.next_index();
@ -245,7 +245,7 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
fn condvar_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, CondvarId> fn condvar_get_or_create<F>(&mut self, existing: F) -> InterpResult<'tcx, CondvarId>
where where
F: FnOnce( F: FnOnce(
&mut MiriInterpCx<'mir, 'tcx>, &mut MiriInterpCx<'tcx>,
CondvarId, CondvarId,
) -> InterpResult<'tcx, Option<CondvarId>>, ) -> InterpResult<'tcx, Option<CondvarId>>,
{ {
@ -287,8 +287,8 @@ pub(super) trait EvalContextExtPriv<'mir, 'tcx: 'mir>:
// cases, the function calls are infallible and it is the client's (shim // cases, the function calls are infallible and it is the client's (shim
// implementation's) responsibility to detect and deal with erroneous // implementation's) responsibility to detect and deal with erroneous
// situations. // situations.
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn mutex_get_or_create_id( fn mutex_get_or_create_id(
&mut self, &mut self,
lock_op: &OpTy<'tcx, Provenance>, lock_op: &OpTy<'tcx, Provenance>,

View file

@ -44,17 +44,12 @@ pub enum TlsAllocAction {
pub trait UnblockCallback<'tcx>: VisitProvenance { pub trait UnblockCallback<'tcx>: VisitProvenance {
/// Will be invoked when the thread was unblocked the "regular" way, /// Will be invoked when the thread was unblocked the "regular" way,
/// i.e. whatever event it was blocking on has happened. /// i.e. whatever event it was blocking on has happened.
fn unblock<'mir>( fn unblock(self: Box<Self>, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx>;
self: Box<Self>,
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
) -> InterpResult<'tcx>;
/// Will be invoked when the timeout ellapsed without the event the /// Will be invoked when the timeout ellapsed without the event the
/// thread was blocking on having occurred. /// thread was blocking on having occurred.
fn timeout<'mir>( fn timeout(self: Box<Self>, _ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>)
self: Box<Self>, -> InterpResult<'tcx>;
_ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
) -> InterpResult<'tcx>;
} }
type DynUnblockCallback<'tcx> = Box<dyn UnblockCallback<'tcx> + 'tcx>; type DynUnblockCallback<'tcx> = Box<dyn UnblockCallback<'tcx> + 'tcx>;
@ -94,13 +89,13 @@ macro_rules! callback {
} }
impl<$tcx, $($lft),*> UnblockCallback<$tcx> for Callback<$tcx, $($lft),*> { impl<$tcx, $($lft),*> UnblockCallback<$tcx> for Callback<$tcx, $($lft),*> {
fn unblock<'mir>(self: Box<Self>, $this: &mut MiriInterpCx<'mir, $tcx>) -> InterpResult<$tcx> { fn unblock(self: Box<Self>, $this: &mut MiriInterpCx<$tcx>) -> InterpResult<$tcx> {
#[allow(unused_variables)] #[allow(unused_variables)]
let Callback { $($name,)* _phantom } = *self; let Callback { $($name,)* _phantom } = *self;
$unblock $unblock
} }
fn timeout<'mir>(self: Box<Self>, $this_timeout: &mut MiriInterpCx<'mir, $tcx>) -> InterpResult<$tcx> { fn timeout(self: Box<Self>, $this_timeout: &mut MiriInterpCx<$tcx>) -> InterpResult<$tcx> {
#[allow(unused_variables)] #[allow(unused_variables)]
let Callback { $($name,)* _phantom } = *self; let Callback { $($name,)* _phantom } = *self;
$timeout $timeout
@ -228,20 +223,20 @@ enum ThreadJoinStatus {
} }
/// A thread. /// A thread.
pub struct Thread<'mir, 'tcx> { pub struct Thread<'tcx> {
state: ThreadState<'tcx>, state: ThreadState<'tcx>,
/// Name of the thread. /// Name of the thread.
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
/// Rust language entry point for this thread returns (usually implemented by the C or OS runtime). /// Rust language entry point for this thread returns (usually implemented by the C or OS runtime).
/// (`None` is an error, it means the callback has not been set up yet or is actively running.) /// (`None` is an error, it means the callback has not been set up yet or is actively running.)
pub(crate) on_stack_empty: Option<StackEmptyCallback<'mir, 'tcx>>, pub(crate) on_stack_empty: Option<StackEmptyCallback<'tcx>>,
/// The index of the topmost user-relevant frame in `stack`. This field must contain /// The index of the topmost user-relevant frame in `stack`. This field must contain
/// the value produced by `get_top_user_relevant_frame`. /// the value produced by `get_top_user_relevant_frame`.
@ -267,10 +262,10 @@ pub struct Thread<'mir, 'tcx> {
pub(crate) last_error: Option<MPlaceTy<'tcx, Provenance>>, pub(crate) last_error: Option<MPlaceTy<'tcx, Provenance>>,
} }
pub type StackEmptyCallback<'mir, 'tcx> = pub type StackEmptyCallback<'tcx> =
Box<dyn FnMut(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, Poll<()>> + 'tcx>; Box<dyn FnMut(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx, Poll<()>> + 'tcx>;
impl<'mir, 'tcx> Thread<'mir, 'tcx> { impl<'tcx> Thread<'tcx> {
/// Get the name of the current thread if it was set. /// Get the name of the current thread if it was set.
fn thread_name(&self) -> Option<&[u8]> { fn thread_name(&self) -> Option<&[u8]> {
self.thread_name.as_deref() self.thread_name.as_deref()
@ -326,7 +321,7 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> { impl<'tcx> std::fmt::Debug for Thread<'tcx> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, f,
@ -338,8 +333,8 @@ impl<'mir, 'tcx> std::fmt::Debug for Thread<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> Thread<'mir, 'tcx> { impl<'tcx> Thread<'tcx> {
fn new(name: Option<&str>, on_stack_empty: Option<StackEmptyCallback<'mir, 'tcx>>) -> Self { fn new(name: Option<&str>, on_stack_empty: Option<StackEmptyCallback<'tcx>>) -> Self {
Self { Self {
state: ThreadState::Enabled, state: ThreadState::Enabled,
thread_name: name.map(|name| Vec::from(name.as_bytes())), thread_name: name.map(|name| Vec::from(name.as_bytes())),
@ -353,7 +348,7 @@ impl<'mir, 'tcx> Thread<'mir, 'tcx> {
} }
} }
impl VisitProvenance for Thread<'_, '_> { impl VisitProvenance for Thread<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) { fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
let Thread { let Thread {
panic_payloads: panic_payload, panic_payloads: panic_payload,
@ -376,7 +371,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,
@ -430,13 +425,13 @@ impl Timeout {
/// A set of threads. /// A set of threads.
#[derive(Debug)] #[derive(Debug)]
pub struct ThreadManager<'mir, 'tcx> { pub struct ThreadManager<'tcx> {
/// Identifier of the currently active thread. /// Identifier of the currently active thread.
active_thread: ThreadId, active_thread: ThreadId,
/// Threads used in the program. /// Threads used in the program.
/// ///
/// Note that this vector also contains terminated threads. /// Note that this vector also contains terminated threads.
threads: IndexVec<ThreadId, Thread<'mir, 'tcx>>, threads: IndexVec<ThreadId, Thread<'tcx>>,
/// A mapping from a thread-local static to an allocation id of a thread /// A mapping from a thread-local static to an allocation id of a thread
/// specific allocation. /// specific allocation.
thread_local_alloc_ids: FxHashMap<(DefId, ThreadId), Pointer<Provenance>>, thread_local_alloc_ids: FxHashMap<(DefId, ThreadId), Pointer<Provenance>>,
@ -444,7 +439,7 @@ pub struct ThreadManager<'mir, 'tcx> {
yield_active_thread: bool, yield_active_thread: bool,
} }
impl VisitProvenance for ThreadManager<'_, '_> { impl VisitProvenance for ThreadManager<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) { fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
let ThreadManager { let ThreadManager {
threads, threads,
@ -462,7 +457,7 @@ impl VisitProvenance for ThreadManager<'_, '_> {
} }
} }
impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> { impl<'tcx> Default for ThreadManager<'tcx> {
fn default() -> Self { fn default() -> Self {
let mut threads = IndexVec::new(); let mut threads = IndexVec::new();
// Create the main thread and add it to the list of threads. // Create the main thread and add it to the list of threads.
@ -476,10 +471,10 @@ impl<'mir, 'tcx> Default for ThreadManager<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { impl<'tcx> ThreadManager<'tcx> {
pub(crate) fn init( pub(crate) fn init(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
on_main_stack_empty: StackEmptyCallback<'mir, 'tcx>, on_main_stack_empty: StackEmptyCallback<'tcx>,
) { ) {
ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty = ecx.machine.threads.threads[ThreadId::MAIN_THREAD].on_stack_empty =
Some(on_main_stack_empty); Some(on_main_stack_empty);
@ -505,24 +500,22 @@ 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>>])> {
self.threads.iter_enumerated().map(|(id, t)| (id, &t.stack[..])) self.threads.iter_enumerated().map(|(id, t)| (id, &t.stack[..]))
} }
/// Create a new thread and returns its id. /// Create a new thread and returns its id.
fn create_thread(&mut self, on_stack_empty: StackEmptyCallback<'mir, 'tcx>) -> ThreadId { fn create_thread(&mut self, on_stack_empty: StackEmptyCallback<'tcx>) -> ThreadId {
let new_thread_id = ThreadId::new(self.threads.len()); let new_thread_id = ThreadId::new(self.threads.len());
self.threads.push(Thread::new(None, Some(on_stack_empty))); self.threads.push(Thread::new(None, Some(on_stack_empty)));
new_thread_id new_thread_id
@ -572,12 +565,12 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
} }
/// Get a mutable borrow of the currently active thread. /// Get a mutable borrow of the currently active thread.
pub fn active_thread_mut(&mut self) -> &mut Thread<'mir, 'tcx> { pub fn active_thread_mut(&mut self) -> &mut Thread<'tcx> {
&mut self.threads[self.active_thread] &mut self.threads[self.active_thread]
} }
/// Get a shared borrow of the currently active thread. /// Get a shared borrow of the currently active thread.
pub fn active_thread_ref(&self) -> &Thread<'mir, 'tcx> { pub fn active_thread_ref(&self) -> &Thread<'tcx> {
&self.threads[self.active_thread] &self.threads[self.active_thread]
} }
@ -791,8 +784,8 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
/// Execute a timeout callback on the callback's thread. /// Execute a timeout callback on the callback's thread.
#[inline] #[inline]
fn run_timeout_callback(&mut self) -> InterpResult<'tcx> { fn run_timeout_callback(&mut self) -> InterpResult<'tcx> {
@ -848,8 +841,8 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
} }
// Public interface to thread management. // Public interface to thread management.
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Get a thread-specific allocation id for the given thread-local static. /// Get a thread-specific allocation id for the given thread-local static.
/// If needed, allocate a new one. /// If needed, allocate a new one.
fn get_or_create_thread_local_alloc( fn get_or_create_thread_local_alloc(
@ -1069,13 +1062,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
#[inline] #[inline]
fn active_thread_mut(&mut self) -> &mut Thread<'mir, 'tcx> { fn active_thread_mut(&mut self) -> &mut Thread<'tcx> {
let this = self.eval_context_mut(); let this = self.eval_context_mut();
this.machine.threads.active_thread_mut() this.machine.threads.active_thread_mut()
} }
#[inline] #[inline]
fn active_thread_ref(&self) -> &Thread<'mir, 'tcx> { fn active_thread_ref(&self) -> &Thread<'tcx> {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
this.machine.threads.active_thread_ref() this.machine.threads.active_thread_ref()
} }
@ -1099,15 +1092,15 @@ 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>>] {
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>>> {
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()
} }
@ -1122,7 +1115,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
#[inline] #[inline]
fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&[u8]> fn get_thread_name<'c>(&'c self, thread: ThreadId) -> Option<&[u8]>
where where
'mir: 'c, 'tcx: 'c,
{ {
self.eval_context_ref().machine.threads.get_thread_name(thread) self.eval_context_ref().machine.threads.get_thread_name(thread)
} }

View file

@ -243,7 +243,7 @@ impl StoreBufferAlloc {
} }
} }
impl<'mir, 'tcx: 'mir> StoreBuffer { impl<'tcx> StoreBuffer {
fn new(init: Scalar<Provenance>) -> Self { fn new(init: Scalar<Provenance>) -> Self {
let mut buffer = VecDeque::new(); let mut buffer = VecDeque::new();
buffer.reserve(STORE_BUFFER_LIMIT); buffer.reserve(STORE_BUFFER_LIMIT);
@ -265,7 +265,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
fn read_from_last_store( fn read_from_last_store(
&self, &self,
global: &DataRaceState, global: &DataRaceState,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
is_seqcst: bool, is_seqcst: bool,
) { ) {
let store_elem = self.buffer.back(); let store_elem = self.buffer.back();
@ -278,7 +278,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
fn buffered_read( fn buffered_read(
&self, &self,
global: &DataRaceState, global: &DataRaceState,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
is_seqcst: bool, is_seqcst: bool,
rng: &mut (impl rand::Rng + ?Sized), rng: &mut (impl rand::Rng + ?Sized),
validate: impl FnOnce() -> InterpResult<'tcx>, validate: impl FnOnce() -> InterpResult<'tcx>,
@ -309,7 +309,7 @@ impl<'mir, 'tcx: 'mir> StoreBuffer {
&mut self, &mut self,
val: Scalar<Provenance>, val: Scalar<Provenance>,
global: &DataRaceState, global: &DataRaceState,
thread_mgr: &ThreadManager<'_, '_>, thread_mgr: &ThreadManager<'_>,
is_seqcst: bool, is_seqcst: bool,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
let (index, clocks) = global.active_thread_state(thread_mgr); let (index, clocks) = global.active_thread_state(thread_mgr);
@ -463,10 +463,8 @@ impl StoreElement {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
crate::MiriInterpCxExt<'mir, 'tcx>
{
fn buffered_atomic_rmw( fn buffered_atomic_rmw(
&mut self, &mut self,
new_val: Scalar<Provenance>, new_val: Scalar<Provenance>,

View file

@ -144,7 +144,7 @@ pub enum DiagLevel {
/// be pointing to a problem in the Rust runtime itself, and do not prune it at all. /// be pointing to a problem in the Rust runtime itself, and do not prune it at all.
pub fn prune_stacktrace<'tcx>( pub fn prune_stacktrace<'tcx>(
mut stacktrace: Vec<FrameInfo<'tcx>>, mut stacktrace: Vec<FrameInfo<'tcx>>,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) -> (Vec<FrameInfo<'tcx>>, bool) { ) -> (Vec<FrameInfo<'tcx>>, bool) {
match machine.backtrace_style { match machine.backtrace_style {
BacktraceStyle::Off => { BacktraceStyle::Off => {
@ -201,8 +201,8 @@ pub fn prune_stacktrace<'tcx>(
/// Emit a custom diagnostic without going through the miri-engine machinery. /// Emit a custom diagnostic without going through the miri-engine machinery.
/// ///
/// Returns `Some` if this was regular program termination with a given exit code and a `bool` indicating whether a leak check should happen; `None` otherwise. /// Returns `Some` if this was regular program termination with a given exit code and a `bool` indicating whether a leak check should happen; `None` otherwise.
pub fn report_error<'tcx, 'mir>( pub fn report_error<'tcx>(
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
e: InterpErrorInfo<'tcx>, e: InterpErrorInfo<'tcx>,
) -> Option<(i64, bool)> { ) -> Option<(i64, bool)> {
use InterpError::*; use InterpError::*;
@ -457,8 +457,8 @@ pub fn report_error<'tcx, 'mir>(
None None
} }
pub fn report_leaks<'mir, 'tcx>( pub fn report_leaks<'tcx>(
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
leaks: Vec<(AllocId, MemoryKind, Allocation<Provenance, AllocExtra<'tcx>, MiriAllocBytes>)>, leaks: Vec<(AllocId, MemoryKind, Allocation<Provenance, AllocExtra<'tcx>, MiriAllocBytes>)>,
) { ) {
let mut any_pruned = false; let mut any_pruned = false;
@ -504,7 +504,7 @@ pub fn report_msg<'tcx>(
helps: Vec<(Option<SpanData>, String)>, helps: Vec<(Option<SpanData>, String)>,
stacktrace: &[FrameInfo<'tcx>], stacktrace: &[FrameInfo<'tcx>],
thread: Option<ThreadId>, thread: Option<ThreadId>,
machine: &MiriMachine<'_, 'tcx>, machine: &MiriMachine<'tcx>,
) { ) {
let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span); let span = stacktrace.first().map_or(DUMMY_SP, |fi| fi.span);
let sess = machine.tcx.sess; let sess = machine.tcx.sess;
@ -577,7 +577,7 @@ pub fn report_msg<'tcx>(
err.emit(); err.emit();
} }
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { impl<'tcx> MiriMachine<'tcx> {
pub fn emit_diagnostic(&self, e: NonHaltingDiagnostic) { pub fn emit_diagnostic(&self, e: NonHaltingDiagnostic) {
use NonHaltingDiagnostic::*; use NonHaltingDiagnostic::*;
@ -690,8 +690,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emit_diagnostic(&self, e: NonHaltingDiagnostic) { fn emit_diagnostic(&self, e: NonHaltingDiagnostic) {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
this.machine.emit_diagnostic(e); this.machine.emit_diagnostic(e);

View file

@ -214,7 +214,7 @@ enum MainThreadState<'tcx> {
impl<'tcx> MainThreadState<'tcx> { impl<'tcx> MainThreadState<'tcx> {
fn on_main_stack_empty( fn on_main_stack_empty(
&mut self, &mut self,
this: &mut MiriInterpCx<'_, 'tcx>, this: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, Poll<()>> { ) -> InterpResult<'tcx, Poll<()>> {
use MainThreadState::*; use MainThreadState::*;
match self { match self {
@ -263,12 +263,12 @@ impl<'tcx> MainThreadState<'tcx> {
/// Returns a freshly created `InterpCx`. /// Returns a freshly created `InterpCx`.
/// Public because this is also used by `priroda`. /// Public because this is also used by `priroda`.
pub fn create_ecx<'mir, 'tcx: 'mir>( pub fn create_ecx<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
entry_id: DefId, entry_id: DefId,
entry_type: EntryFnType, entry_type: EntryFnType,
config: &MiriConfig, config: &MiriConfig,
) -> InterpResult<'tcx, InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>> { ) -> InterpResult<'tcx, InterpCx<'tcx, MiriMachine<'tcx>>> {
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
let layout_cx = LayoutCx { tcx, param_env }; let layout_cx = LayoutCx { tcx, param_env };
let mut ecx = let mut ecx =

View file

@ -234,8 +234,8 @@ impl ToSoft for f32 {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Checks if the given crate/module exists. /// Checks if the given crate/module exists.
fn have_module(&self, path: &[&str]) -> bool { fn have_module(&self, path: &[&str]) -> bool {
try_resolve_did(*self.eval_context_ref().tcx, path, None).is_some() try_resolve_did(*self.eval_context_ref().tcx, path, None).is_some()
@ -573,23 +573,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Visiting the memory covered by a `MemPlace`, being aware of /// Visiting the memory covered by a `MemPlace`, being aware of
/// whether we are inside an `UnsafeCell` or not. /// whether we are inside an `UnsafeCell` or not.
struct UnsafeCellVisitor<'ecx, 'mir, 'tcx, F> struct UnsafeCellVisitor<'ecx, 'tcx, F>
where where
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>, F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
{ {
ecx: &'ecx MiriInterpCx<'mir, 'tcx>, ecx: &'ecx MiriInterpCx<'tcx>,
unsafe_cell_action: F, unsafe_cell_action: F,
} }
impl<'ecx, 'mir, 'tcx: 'mir, F> ValueVisitor<'mir, 'tcx, MiriMachine<'mir, 'tcx>> impl<'ecx, 'tcx, F> ValueVisitor<'tcx, MiriMachine<'tcx>> for UnsafeCellVisitor<'ecx, 'tcx, F>
for UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
where where
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>, F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
{ {
type V = MPlaceTy<'tcx, Provenance>; type V = MPlaceTy<'tcx, Provenance>;
#[inline(always)] #[inline(always)]
fn ecx(&self) -> &MiriInterpCx<'mir, 'tcx> { fn ecx(&self) -> &MiriInterpCx<'tcx> {
self.ecx self.ecx
} }
@ -920,7 +919,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
slice: &ImmTy<'tcx, Provenance>, slice: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, &'a [u8]> ) -> InterpResult<'tcx, &'a [u8]>
where where
'mir: 'a, 'tcx: 'a,
{ {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let (ptr, len) = slice.to_scalar_pair(); let (ptr, len) = slice.to_scalar_pair();
@ -933,7 +932,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Read a sequence of bytes until the first null terminator. /// Read a sequence of bytes until the first null terminator.
fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, &'a [u8]> fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, &'a [u8]>
where where
'mir: 'a, 'tcx: 'a,
{ {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let size1 = Size::from_bytes(1); let size1 = Size::from_bytes(1);
@ -1176,7 +1175,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>( fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>(
this: &MiriInterpCx<'_, 'tcx>, this: &MiriInterpCx<'tcx>,
src: F, src: F,
cast_to: TyAndLayout<'tcx>, cast_to: TyAndLayout<'tcx>,
round: rustc_apfloat::Round, round: rustc_apfloat::Round,
@ -1299,7 +1298,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { impl<'tcx> MiriMachine<'tcx> {
/// Get the current span in the topmost function which is workspace-local and not /// Get the current span in the topmost function which is workspace-local and not
/// `#[track_caller]`. /// `#[track_caller]`.
/// This function is backed by a cache, and can be assumed to be very fast. /// This function is backed by a cache, and can be assumed to be very fast.
@ -1321,7 +1320,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 +1329,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

@ -11,8 +11,8 @@ pub enum AtomicOp {
Min, Min,
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Calls the atomic intrinsic `intrinsic`; the `atomic_` prefix has already been removed. /// Calls the atomic intrinsic `intrinsic`; the `atomic_` prefix has already been removed.
/// Returns `Ok(true)` if the intrinsic was handled. /// Returns `Ok(true)` if the intrinsic was handled.
fn emulate_atomic_intrinsic( fn emulate_atomic_intrinsic(
@ -120,8 +120,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
fn atomic_load( fn atomic_load(
&mut self, &mut self,
args: &[OpTy<'tcx, Provenance>], args: &[OpTy<'tcx, Provenance>],

View file

@ -18,8 +18,8 @@ use atomic::EvalContextExt as _;
use helpers::{check_arg_count, ToHost, ToSoft}; use helpers::{check_arg_count, ToHost, ToSoft};
use simd::EvalContextExt as _; use simd::EvalContextExt as _;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn call_intrinsic( fn call_intrinsic(
&mut self, &mut self,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,

View file

@ -15,8 +15,8 @@ pub(crate) enum MinMax {
Max, Max,
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Calls the simd intrinsic `intrinsic`; the `simd_` prefix has already been removed. /// Calls the simd intrinsic `intrinsic`; the `simd_` prefix has already been removed.
/// Returns `Ok(true)` if the intrinsic was handled. /// Returns `Ok(true)` if the intrinsic was handled.
fn emulate_simd_intrinsic( fn emulate_simd_intrinsic(

View file

@ -373,7 +373,7 @@ pub struct PrimitiveLayouts<'tcx> {
pub const_raw_ptr: TyAndLayout<'tcx>, // *const () pub const_raw_ptr: TyAndLayout<'tcx>, // *const ()
} }
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> { impl<'tcx> PrimitiveLayouts<'tcx> {
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> { fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, &'tcx LayoutError<'tcx>> {
let tcx = layout_cx.tcx; let tcx = layout_cx.tcx;
let mut_raw_ptr = Ty::new_mut_ptr(tcx, tcx.types.unit); let mut_raw_ptr = Ty::new_mut_ptr(tcx, tcx.types.unit);
@ -425,7 +425,7 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
/// ///
/// If you add anything here that stores machine values, remember to update /// If you add anything here that stores machine values, remember to update
/// `visit_all_machine_values`! /// `visit_all_machine_values`!
pub struct MiriMachine<'mir, 'tcx> { pub struct MiriMachine<'tcx> {
// We carry a copy of the global `TyCtxt` for convenience, so methods taking just `&Evaluator` have `tcx` access. // We carry a copy of the global `TyCtxt` for convenience, so methods taking just `&Evaluator` have `tcx` access.
pub tcx: TyCtxt<'tcx>, pub tcx: TyCtxt<'tcx>,
@ -471,7 +471,7 @@ pub struct MiriMachine<'mir, 'tcx> {
pub(crate) clock: Clock, pub(crate) clock: Clock,
/// The set of threads. /// The set of threads.
pub(crate) threads: ThreadManager<'mir, 'tcx>, pub(crate) threads: ThreadManager<'tcx>,
/// The state of the primitive synchronization objects. /// The state of the primitive synchronization objects.
pub(crate) sync: SynchronizationObjects, pub(crate) sync: SynchronizationObjects,
@ -576,7 +576,7 @@ pub struct MiriMachine<'mir, 'tcx> {
pub(crate) symbolic_alignment: RefCell<FxHashMap<AllocId, (Size, Align)>>, pub(crate) symbolic_alignment: RefCell<FxHashMap<AllocId, (Size, Align)>>,
} }
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { impl<'tcx> MiriMachine<'tcx> {
pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self { pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Self {
let tcx = layout_cx.tcx; let tcx = layout_cx.tcx;
let local_crates = helpers::get_local_crates(tcx); let local_crates = helpers::get_local_crates(tcx);
@ -706,9 +706,9 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
pub(crate) fn late_init( pub(crate) fn late_init(
this: &mut MiriInterpCx<'mir, 'tcx>, this: &mut MiriInterpCx<'tcx>,
config: &MiriConfig, config: &MiriConfig,
on_main_stack_empty: StackEmptyCallback<'mir, 'tcx>, on_main_stack_empty: StackEmptyCallback<'tcx>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
EnvVars::init(this, config)?; EnvVars::init(this, config)?;
MiriMachine::init_extern_statics(this)?; MiriMachine::init_extern_statics(this)?;
@ -717,7 +717,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
pub(crate) fn add_extern_static( pub(crate) fn add_extern_static(
this: &mut MiriInterpCx<'mir, 'tcx>, this: &mut MiriInterpCx<'tcx>,
name: &str, name: &str,
ptr: Pointer<Option<Provenance>>, ptr: Pointer<Option<Provenance>>,
) { ) {
@ -765,7 +765,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
} }
impl VisitProvenance for MiriMachine<'_, '_> { impl VisitProvenance for MiriMachine<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) { fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
#[rustfmt::skip] #[rustfmt::skip]
let MiriMachine { let MiriMachine {
@ -837,26 +837,26 @@ impl VisitProvenance for MiriMachine<'_, '_> {
} }
/// A rustc InterpCx for Miri. /// A rustc InterpCx for Miri.
pub type MiriInterpCx<'mir, 'tcx> = InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>; pub type MiriInterpCx<'tcx> = InterpCx<'tcx, MiriMachine<'tcx>>;
/// A little trait that's useful to be inherited by extension traits. /// A little trait that's useful to be inherited by extension traits.
pub trait MiriInterpCxExt<'mir, 'tcx> { pub trait MiriInterpCxExt<'tcx> {
fn eval_context_ref<'a>(&'a self) -> &'a MiriInterpCx<'mir, 'tcx>; fn eval_context_ref<'a>(&'a self) -> &'a MiriInterpCx<'tcx>;
fn eval_context_mut<'a>(&'a mut self) -> &'a mut MiriInterpCx<'mir, 'tcx>; fn eval_context_mut<'a>(&'a mut self) -> &'a mut MiriInterpCx<'tcx>;
} }
impl<'mir, 'tcx> MiriInterpCxExt<'mir, 'tcx> for MiriInterpCx<'mir, 'tcx> { impl<'tcx> MiriInterpCxExt<'tcx> for MiriInterpCx<'tcx> {
#[inline(always)] #[inline(always)]
fn eval_context_ref(&self) -> &MiriInterpCx<'mir, 'tcx> { fn eval_context_ref(&self) -> &MiriInterpCx<'tcx> {
self self
} }
#[inline(always)] #[inline(always)]
fn eval_context_mut(&mut self) -> &mut MiriInterpCx<'mir, 'tcx> { fn eval_context_mut(&mut self) -> &mut MiriInterpCx<'tcx> {
self self
} }
} }
/// Machine hook implementations. /// Machine hook implementations.
impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
type MemoryKind = MiriMemoryKind; type MemoryKind = MiriMemoryKind;
type ExtraFnVal = DynSym; type ExtraFnVal = DynSym;
@ -875,13 +875,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
const PANIC_ON_ALLOC_FAIL: bool = false; const PANIC_ON_ALLOC_FAIL: bool = false;
#[inline(always)] #[inline(always)]
fn enforce_alignment(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { fn enforce_alignment(ecx: &MiriInterpCx<'tcx>) -> bool {
ecx.machine.check_alignment != AlignmentCheck::None ecx.machine.check_alignment != AlignmentCheck::None
} }
#[inline(always)] #[inline(always)]
fn alignment_check( fn alignment_check(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
alloc_id: AllocId, alloc_id: AllocId,
alloc_align: Align, alloc_align: Align,
alloc_kind: AllocKind, alloc_kind: AllocKind,
@ -926,30 +926,30 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
#[inline(always)] #[inline(always)]
fn enforce_validity(ecx: &MiriInterpCx<'mir, 'tcx>, _layout: TyAndLayout<'tcx>) -> bool { fn enforce_validity(ecx: &MiriInterpCx<'tcx>, _layout: TyAndLayout<'tcx>) -> bool {
ecx.machine.validate ecx.machine.validate
} }
#[inline(always)] #[inline(always)]
fn enforce_abi(_ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { fn enforce_abi(_ecx: &MiriInterpCx<'tcx>) -> bool {
true true
} }
#[inline(always)] #[inline(always)]
fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'mir, 'tcx>) -> bool { fn ignore_optional_overflow_checks(ecx: &MiriInterpCx<'tcx>) -> bool {
!ecx.tcx.sess.overflow_checks() !ecx.tcx.sess.overflow_checks()
} }
#[inline(always)] #[inline(always)]
fn find_mir_or_eval_fn( fn find_mir_or_eval_fn(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
abi: Abi, abi: Abi,
args: &[FnArg<'tcx, Provenance>], args: &[FnArg<'tcx, Provenance>],
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
@ -969,7 +969,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn call_extra_fn( fn call_extra_fn(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
fn_val: DynSym, fn_val: DynSym,
abi: Abi, abi: Abi,
args: &[FnArg<'tcx, Provenance>], args: &[FnArg<'tcx, Provenance>],
@ -983,7 +983,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn call_intrinsic( fn call_intrinsic(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
instance: ty::Instance<'tcx>, instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Provenance>], args: &[OpTy<'tcx, Provenance>],
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -995,19 +995,19 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn assert_panic( fn assert_panic(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
msg: &mir::AssertMessage<'tcx>, msg: &mir::AssertMessage<'tcx>,
unwind: mir::UnwindAction, unwind: mir::UnwindAction,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
ecx.assert_panic(msg, unwind) ecx.assert_panic(msg, unwind)
} }
fn panic_nounwind(ecx: &mut InterpCx<'mir, 'tcx, Self>, msg: &str) -> InterpResult<'tcx> { fn panic_nounwind(ecx: &mut InterpCx<'tcx, Self>, msg: &str) -> InterpResult<'tcx> {
ecx.start_panic_nounwind(msg) ecx.start_panic_nounwind(msg)
} }
fn unwind_terminate( fn unwind_terminate(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
reason: mir::UnwindTerminateReason, reason: mir::UnwindTerminateReason,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Call the lang item. // Call the lang item.
@ -1025,7 +1025,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn binary_ptr_op( fn binary_ptr_op(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
bin_op: mir::BinOp, bin_op: mir::BinOp,
left: &ImmTy<'tcx, Provenance>, left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>, right: &ImmTy<'tcx, Provenance>,
@ -1038,21 +1038,21 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F2>, F1: rustc_apfloat::Float + rustc_apfloat::FloatConvert<F2>,
F2: rustc_apfloat::Float, F2: rustc_apfloat::Float,
>( >(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
inputs: &[F1], inputs: &[F1],
) -> F2 { ) -> F2 {
ecx.generate_nan(inputs) ecx.generate_nan(inputs)
} }
fn thread_local_static_pointer( fn thread_local_static_pointer(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
def_id: DefId, def_id: DefId,
) -> InterpResult<'tcx, Pointer<Provenance>> { ) -> InterpResult<'tcx, Pointer<Provenance>> {
ecx.get_or_create_thread_local_alloc(def_id) ecx.get_or_create_thread_local_alloc(def_id)
} }
fn extern_static_pointer( fn extern_static_pointer(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
def_id: DefId, def_id: DefId,
) -> InterpResult<'tcx, Pointer<Provenance>> { ) -> InterpResult<'tcx, Pointer<Provenance>> {
let link_name = ecx.item_link_name(def_id); let link_name = ecx.item_link_name(def_id);
@ -1087,7 +1087,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
fn adjust_allocation<'b>( fn adjust_allocation<'b>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
id: AllocId, id: AllocId,
alloc: Cow<'b, Allocation>, alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind>, kind: Option<MemoryKind>,
@ -1152,7 +1152,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
fn adjust_alloc_root_pointer( fn adjust_alloc_root_pointer(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
ptr: Pointer<CtfeProvenance>, ptr: Pointer<CtfeProvenance>,
kind: Option<MemoryKind>, kind: Option<MemoryKind>,
) -> InterpResult<'tcx, Pointer<Provenance>> { ) -> InterpResult<'tcx, Pointer<Provenance>> {
@ -1183,7 +1183,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
/// Called on `usize as ptr` casts. /// Called on `usize as ptr` casts.
#[inline(always)] #[inline(always)]
fn ptr_from_addr_cast( fn ptr_from_addr_cast(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
addr: u64, addr: u64,
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>> { ) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>> {
ecx.ptr_from_addr_cast(addr) ecx.ptr_from_addr_cast(addr)
@ -1193,7 +1193,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
/// (Actually computing the resulting `usize` doesn't need machine help, /// (Actually computing the resulting `usize` doesn't need machine help,
/// that's just `Scalar::try_to_int`.) /// that's just `Scalar::try_to_int`.)
fn expose_ptr( fn expose_ptr(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
ptr: Pointer<Self::Provenance>, ptr: Pointer<Self::Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
match ptr.provenance { match ptr.provenance {
@ -1215,7 +1215,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
/// (i.e., we'll never turn the data returned here back into a `Pointer` that might be /// (i.e., we'll never turn the data returned here back into a `Pointer` that might be
/// stored in machine state). /// stored in machine state).
fn ptr_get_alloc( fn ptr_get_alloc(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
ptr: Pointer<Self::Provenance>, ptr: Pointer<Self::Provenance>,
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> { ) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
let rel = ecx.ptr_get_alloc(ptr); let rel = ecx.ptr_get_alloc(ptr);
@ -1312,7 +1312,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn retag_ptr_value( fn retag_ptr_value(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
kind: mir::RetagKind, kind: mir::RetagKind,
val: &ImmTy<'tcx, Provenance>, val: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> { ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
@ -1325,7 +1325,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
#[inline(always)] #[inline(always)]
fn retag_place_contents( fn retag_place_contents(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
kind: mir::RetagKind, kind: mir::RetagKind,
place: &PlaceTy<'tcx, Provenance>, place: &PlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -1336,7 +1336,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
fn protect_in_place_function_argument( fn protect_in_place_function_argument(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
place: &MPlaceTy<'tcx, Provenance>, place: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// If we have a borrow tracker, we also have it set up protection so that all reads *and // If we have a borrow tracker, we also have it set up protection so that all reads *and
@ -1358,9 +1358,9 @@ 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<'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();
@ -1390,18 +1390,18 @@ 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<'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<'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()
} }
fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn before_terminator(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
ecx.machine.basic_block_count += 1u64; // a u64 that is only incremented by 1 will "never" overflow ecx.machine.basic_block_count += 1u64; // a u64 that is only incremented by 1 will "never" overflow
ecx.machine.since_gc += 1; ecx.machine.since_gc += 1;
// Possibly report our progress. // Possibly report our progress.
@ -1432,7 +1432,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
#[inline(always)] #[inline(always)]
fn after_stack_push(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> { fn after_stack_push(ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> {
if ecx.frame().extra.is_user_relevant { if ecx.frame().extra.is_user_relevant {
// We just pushed a local frame, so we know that the topmost local frame is the topmost // We just pushed a local frame, so we know that the topmost local frame is the topmost
// frame. If we push a non-local frame, there's no need to do anything. // frame. If we push a non-local frame, there's no need to do anything.
@ -1443,8 +1443,8 @@ 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<'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.
@ -1460,8 +1460,8 @@ 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<'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 {
@ -1490,7 +1490,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
fn after_local_allocated( fn after_local_allocated(
ecx: &mut InterpCx<'mir, 'tcx, Self>, ecx: &mut InterpCx<'tcx, Self>,
local: mir::Local, local: mir::Local,
mplace: &MPlaceTy<'tcx, Provenance>, mplace: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -1504,7 +1504,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
} }
fn eval_mir_constant<F>( fn eval_mir_constant<F>(
ecx: &InterpCx<'mir, 'tcx, Self>, ecx: &InterpCx<'tcx, Self>,
val: mir::Const<'tcx>, val: mir::Const<'tcx>,
span: Span, span: Span,
layout: Option<TyAndLayout<'tcx>>, layout: Option<TyAndLayout<'tcx>>,
@ -1512,7 +1512,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>> ) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
where where
F: Fn( F: Fn(
&InterpCx<'mir, 'tcx, Self>, &InterpCx<'tcx, Self>,
mir::Const<'tcx>, mir::Const<'tcx>,
Span, Span,
Option<TyAndLayout<'tcx>>, Option<TyAndLayout<'tcx>>,

View file

@ -7,8 +7,8 @@ use rustc_target::abi::Size;
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn binary_ptr_op( fn binary_ptr_op(
&self, &self,
bin_op: mir::BinOp, bin_op: mir::BinOp,

View file

@ -144,7 +144,7 @@ impl VisitProvenance for Allocation<Provenance, AllocExtra<'_>, MiriAllocBytes>
} }
} }
impl VisitProvenance for crate::MiriInterpCx<'_, '_> { impl VisitProvenance for crate::MiriInterpCx<'_> {
fn visit_provenance(&self, visit: &mut VisitWith<'_>) { fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
// Visit the contents of the allocations and the IDs themselves, to account for all // Visit the contents of the allocations and the IDs themselves, to account for all
// live allocation IDs and all provenance in the allocation bytes, even if they are leaked. // live allocation IDs and all provenance in the allocation bytes, even if they are leaked.
@ -162,19 +162,19 @@ impl VisitProvenance for crate::MiriInterpCx<'_, '_> {
} }
} }
pub struct LiveAllocs<'a, 'mir, 'tcx> { pub struct LiveAllocs<'a, 'tcx> {
collected: FxHashSet<AllocId>, collected: FxHashSet<AllocId>,
ecx: &'a MiriInterpCx<'mir, 'tcx>, ecx: &'a MiriInterpCx<'tcx>,
} }
impl LiveAllocs<'_, '_, '_> { impl LiveAllocs<'_, '_> {
pub fn is_live(&self, id: AllocId) -> bool { pub fn is_live(&self, id: AllocId) -> bool {
self.collected.contains(&id) || self.ecx.is_alloc_live(id) self.collected.contains(&id) || self.ecx.is_alloc_live(id)
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
fn run_provenance_gc(&mut self) { fn run_provenance_gc(&mut self) {
// We collect all tags from various parts of the interpreter, but also // We collect all tags from various parts of the interpreter, but also
let this = self.eval_context_mut(); let this = self.eval_context_mut();

View file

@ -17,8 +17,8 @@ pub(super) fn check_alloc_request<'tcx>(size: u64, align: u64) -> InterpResult<'
Ok(()) Ok(())
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Returns the alignment that `malloc` would guarantee for requests of the given size. /// Returns the alignment that `malloc` would guarantee for requests of the given size.
fn malloc_align(&self, size: u64) -> Align { fn malloc_align(&self, size: u64) -> Align {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
@ -67,7 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
/// Emulates calling the internal __rust_* allocator functions /// Emulates calling the internal __rust_* allocator functions
fn emulate_allocator( fn emulate_allocator(
&mut self, &mut self,
default: impl FnOnce(&mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx>, default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> { ) -> InterpResult<'tcx, EmulateItemResult> {
let this = self.eval_context_mut(); let this = self.eval_context_mut();

View file

@ -5,8 +5,8 @@ use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{hygiene, BytePos, Loc, Symbol}; use rustc_span::{hygiene, BytePos, Loc, Symbol};
use rustc_target::{abi::Size, spec::abi::Abi}; use rustc_target::{abi::Size, spec::abi::Abi};
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn handle_miri_backtrace_size( fn handle_miri_backtrace_size(
&mut self, &mut self,
abi: Abi, abi: Abi,

View file

@ -24,8 +24,8 @@ impl VisitProvenance for EnvVars<'_> {
} }
impl<'tcx> EnvVars<'tcx> { impl<'tcx> EnvVars<'tcx> {
pub(crate) fn init<'mir>( pub(crate) fn init(
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
config: &MiriConfig, config: &MiriConfig,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
// Initialize the `env_vars` map. // Initialize the `env_vars` map.
@ -58,9 +58,7 @@ impl<'tcx> EnvVars<'tcx> {
Ok(()) Ok(())
} }
pub(crate) fn cleanup<'mir>( pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> {
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
) -> InterpResult<'tcx> {
let this = ecx.eval_context_mut(); let this = ecx.eval_context_mut();
match this.machine.env_vars { match this.machine.env_vars {
EnvVars::Unix(_) => UnixEnvVars::cleanup(this), EnvVars::Unix(_) => UnixEnvVars::cleanup(this),
@ -98,8 +96,8 @@ impl<'tcx> EnvVars<'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Try to get an environment variable from the interpreted program's environment. This is /// Try to get an environment variable from the interpreted program's environment. This is
/// useful for implementing shims which are documented to read from the environment. /// useful for implementing shims which are documented to read from the environment.
fn get_env_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option<OsString>> { fn get_env_var(&mut self, name: &OsStr) -> InterpResult<'tcx, Option<OsString>> {

View file

@ -2,9 +2,9 @@
use crate::*; use crate::*;
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { impl<'tcx> MiriMachine<'tcx> {
fn alloc_extern_static( fn alloc_extern_static(
this: &mut MiriInterpCx<'mir, 'tcx>, this: &mut MiriInterpCx<'tcx>,
name: &str, name: &str,
val: ImmTy<'tcx, Provenance>, val: ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
@ -19,7 +19,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
/// symbol is not supported, and triggering fallback code which ends up calling /// symbol is not supported, and triggering fallback code which ends up calling
/// some other shim that we do support). /// some other shim that we do support).
fn null_ptr_extern_statics( fn null_ptr_extern_statics(
this: &mut MiriInterpCx<'mir, 'tcx>, this: &mut MiriInterpCx<'tcx>,
names: &[&str], names: &[&str],
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
for name in names { for name in names {
@ -31,7 +31,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
/// Extern statics that are initialized with function pointers to the symbols of the same name. /// Extern statics that are initialized with function pointers to the symbols of the same name.
fn weak_symbol_extern_statics( fn weak_symbol_extern_statics(
this: &mut MiriInterpCx<'mir, 'tcx>, this: &mut MiriInterpCx<'tcx>,
names: &[&str], names: &[&str],
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {
for name in names { for name in names {
@ -45,7 +45,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
} }
/// Sets up the "extern statics" for this machine. /// Sets up the "extern statics" for this machine.
pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> { pub fn init_extern_statics(this: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> {
// "__rust_no_alloc_shim_is_unstable" // "__rust_no_alloc_shim_is_unstable"
let val = ImmTy::from_int(0, this.machine.layouts.u8); // always 0, value does not matter let val = ImmTy::from_int(0, this.machine.layouts.u8); // always 0, value does not matter
Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?; Self::alloc_extern_static(this, "__rust_no_alloc_shim_is_unstable", val)?;

View file

@ -28,8 +28,8 @@ impl DynSym {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Emulates calling a foreign item, failing if the item is not supported. /// Emulates calling a foreign item, failing if the item is not supported.
/// This function will handle `goto_block` if needed. /// This function will handle `goto_block` if needed.
/// Returns Ok(None) if the foreign item was completely handled /// Returns Ok(None) if the foreign item was completely handled
@ -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;
@ -202,8 +202,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,
@ -455,7 +455,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// Rust allocation // Rust allocation
"__rust_alloc" | "miri_alloc" => { "__rust_alloc" | "miri_alloc" => {
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { let default = |this: &mut MiriInterpCx<'tcx>| {
// Only call `check_shim` when `#[global_allocator]` isn't used. When that // Only call `check_shim` when `#[global_allocator]` isn't used. When that
// macro is used, we act like no shim exists, so that the exported function can run. // macro is used, we act like no shim exists, so that the exported function can run.
let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?; let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@ -514,7 +514,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}); });
} }
"__rust_dealloc" | "miri_dealloc" => { "__rust_dealloc" | "miri_dealloc" => {
let default = |this: &mut MiriInterpCx<'mir, 'tcx>| { let default = |this: &mut MiriInterpCx<'tcx>| {
// See the comment for `__rust_alloc` why `check_shim` is only called in the // See the comment for `__rust_alloc` why `check_shim` is only called in the
// default case. // default case.
let [ptr, old_size, align] = let [ptr, old_size, align] =

View file

@ -8,8 +8,8 @@ use rustc_target::abi::{Abi, HasDataLayout};
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Call native host function and return the output as an immediate. /// Call native host function and return the output as an immediate.
fn call_native_with_args<'a>( fn call_native_with_args<'a>(
&mut self, &mut self,
@ -122,8 +122,8 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Call the native host function, with supplied arguments. /// Call the native host function, with supplied arguments.
/// Needs to convert all the arguments from their Miri representations to /// Needs to convert all the arguments from their Miri representations to
/// a native form (through `libffi` call). /// a native form (through `libffi` call).

View file

@ -30,8 +30,8 @@ pub fn bytes_to_os_str<'tcx>(bytes: &[u8]) -> InterpResult<'tcx, &OsStr> {
Ok(OsStr::new(s)) Ok(OsStr::new(s))
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what /// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
/// the Unix APIs usually handle. /// the Unix APIs usually handle.
fn read_os_str_from_c_str<'a>( fn read_os_str_from_c_str<'a>(
@ -40,7 +40,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
) -> InterpResult<'tcx, &'a OsStr> ) -> InterpResult<'tcx, &'a OsStr>
where where
'tcx: 'a, 'tcx: 'a,
'mir: 'a,
{ {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let bytes = this.read_c_str(ptr)?; let bytes = this.read_c_str(ptr)?;
@ -55,7 +54,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
) -> InterpResult<'tcx, OsString> ) -> InterpResult<'tcx, OsString>
where where
'tcx: 'a, 'tcx: 'a,
'mir: 'a,
{ {
#[cfg(windows)] #[cfg(windows)]
pub fn u16vec_to_osstring<'tcx>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsString> { pub fn u16vec_to_osstring<'tcx>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsString> {
@ -183,7 +181,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
) -> InterpResult<'tcx, Cow<'a, Path>> ) -> InterpResult<'tcx, Cow<'a, Path>>
where where
'tcx: 'a, 'tcx: 'a,
'mir: 'a,
{ {
let this = self.eval_context_ref(); let this = self.eval_context_ref();
let os_str = this.read_os_str_from_c_str(ptr)?; let os_str = this.read_os_str_from_c_str(ptr)?;

View file

@ -41,8 +41,8 @@ impl VisitProvenance for CatchUnwindData<'_> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Handles the special `miri_start_unwind` intrinsic, which is called /// Handles the special `miri_start_unwind` intrinsic, which is called
/// by libpanic_unwind to delegate the actual unwinding process to Miri. /// by libpanic_unwind to delegate the actual unwinding process to Miri.
fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> { fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {

View file

@ -14,8 +14,8 @@ pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Du
.map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into()) .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn clock_gettime( fn clock_gettime(
&mut self, &mut self,
clk_id_op: &OpTy<'tcx, Provenance>, clk_id_op: &OpTy<'tcx, Provenance>,

View file

@ -235,7 +235,7 @@ enum TlsDtorsStatePriv<'tcx> {
impl<'tcx> TlsDtorsState<'tcx> { impl<'tcx> TlsDtorsState<'tcx> {
pub fn on_stack_empty( pub fn on_stack_empty(
&mut self, &mut self,
this: &mut MiriInterpCx<'_, 'tcx>, this: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, Poll<()>> { ) -> InterpResult<'tcx, Poll<()>> {
use TlsDtorsStatePriv::*; use TlsDtorsStatePriv::*;
let new_state = 'new_state: { let new_state = 'new_state: {
@ -293,8 +293,8 @@ impl<'tcx> TlsDtorsState<'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextPrivExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Schedule TLS destructors for Windows. /// Schedule TLS destructors for Windows.
/// On windows, TLS destructors are managed by std. /// On windows, TLS destructors are managed by std.
fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec<ImmTy<'tcx, Provenance>>> { fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec<ImmTy<'tcx, Provenance>>> {

View file

@ -7,8 +7,8 @@ pub fn is_dyn_sym(_name: &str) -> bool {
false false
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -31,8 +31,8 @@ impl VisitProvenance for UnixEnvVars<'_> {
} }
impl<'tcx> UnixEnvVars<'tcx> { impl<'tcx> UnixEnvVars<'tcx> {
pub(crate) fn new<'mir>( pub(crate) fn new(
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
env_vars: FxHashMap<OsString, OsString>, env_vars: FxHashMap<OsString, OsString>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
// Allocate memory for all these env vars. // Allocate memory for all these env vars.
@ -51,9 +51,7 @@ impl<'tcx> UnixEnvVars<'tcx> {
Ok(UnixEnvVars { map: env_vars_machine, environ }) Ok(UnixEnvVars { map: env_vars_machine, environ })
} }
pub(crate) fn cleanup<'mir>( pub(crate) fn cleanup(ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>) -> InterpResult<'tcx> {
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>,
) -> InterpResult<'tcx> {
// Deallocate individual env vars. // Deallocate individual env vars.
let env_vars = mem::take(&mut ecx.machine.env_vars.unix_mut().map); let env_vars = mem::take(&mut ecx.machine.env_vars.unix_mut().map);
for (_name, ptr) in env_vars { for (_name, ptr) in env_vars {
@ -71,9 +69,9 @@ impl<'tcx> UnixEnvVars<'tcx> {
self.environ.ptr() self.environ.ptr()
} }
fn get_ptr<'mir>( fn get_ptr(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
name: &OsStr, name: &OsStr,
) -> InterpResult<'tcx, Option<Pointer<Option<Provenance>>>> { ) -> InterpResult<'tcx, Option<Pointer<Option<Provenance>>>> {
// We don't care about the value as we have the `map` to keep track of everything, // We don't care about the value as we have the `map` to keep track of everything,
@ -92,9 +90,9 @@ impl<'tcx> UnixEnvVars<'tcx> {
/// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete /// Implementation detail for [`InterpCx::get_env_var`]. This basically does `getenv`, complete
/// with the reads of the environment, but returns an [`OsString`] instead of a pointer. /// with the reads of the environment, but returns an [`OsString`] instead of a pointer.
pub(crate) fn get<'mir>( pub(crate) fn get(
&self, &self,
ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
name: &OsStr, name: &OsStr,
) -> InterpResult<'tcx, Option<OsString>> { ) -> InterpResult<'tcx, Option<OsString>> {
let var_ptr = self.get_ptr(ecx, name)?; let var_ptr = self.get_ptr(ecx, name)?;
@ -107,8 +105,8 @@ impl<'tcx> UnixEnvVars<'tcx> {
} }
} }
fn alloc_env_var<'mir, 'tcx>( fn alloc_env_var<'tcx>(
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
name: &OsStr, name: &OsStr,
value: &OsStr, value: &OsStr,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
@ -119,8 +117,8 @@ fn alloc_env_var<'mir, 'tcx>(
} }
/// Allocates an `environ` block with the given list of pointers. /// Allocates an `environ` block with the given list of pointers.
fn alloc_environ_block<'mir, 'tcx>( fn alloc_environ_block<'tcx>(
ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
mut vars: Vec<Pointer<Option<Provenance>>>, mut vars: Vec<Pointer<Option<Provenance>>>,
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> { ) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
// Add trailing null. // Add trailing null.
@ -139,8 +137,8 @@ fn alloc_environ_block<'mir, 'tcx>(
Ok(vars_place.ptr()) Ok(vars_place.ptr())
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn getenv( fn getenv(
&mut self, &mut self,
name_op: &OpTy<'tcx, Provenance>, name_op: &OpTy<'tcx, Provenance>,

View file

@ -21,7 +21,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
_bytes: &mut [u8], _bytes: &mut [u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot read from {}", self.name()); throw_unsup_format!("cannot read from {}", self.name());
} }
@ -31,7 +31,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
_bytes: &[u8], _bytes: &[u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
throw_unsup_format!("cannot write to {}", self.name()); throw_unsup_format!("cannot write to {}", self.name());
} }
@ -81,7 +81,7 @@ impl FileDescription for io::Stdin {
&mut self, &mut self,
communicate_allowed: bool, communicate_allowed: bool,
bytes: &mut [u8], bytes: &mut [u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
if !communicate_allowed { if !communicate_allowed {
// We want isolation mode to be deterministic, so we have to disallow all reads, even stdin. // We want isolation mode to be deterministic, so we have to disallow all reads, even stdin.
@ -104,7 +104,7 @@ impl FileDescription for io::Stdout {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
bytes: &[u8], bytes: &[u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
// We allow writing to stderr even with isolation enabled. // We allow writing to stderr even with isolation enabled.
let result = Write::write(self, bytes); let result = Write::write(self, bytes);
@ -132,7 +132,7 @@ impl FileDescription for io::Stderr {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
bytes: &[u8], bytes: &[u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
// We allow writing to stderr even with isolation enabled. // We allow writing to stderr even with isolation enabled.
// No need to flush, stderr is not buffered. // No need to flush, stderr is not buffered.
@ -157,7 +157,7 @@ impl FileDescription for NullOutput {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
bytes: &[u8], bytes: &[u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
// We just don't write anything, but report to the user that we did. // We just don't write anything, but report to the user that we did.
Ok(Ok(bytes.len())) Ok(Ok(bytes.len()))
@ -271,8 +271,8 @@ impl FdTable {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> { fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut(); let this = self.eval_context_mut();

View file

@ -37,8 +37,8 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,
@ -326,7 +326,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let name = this.read_scalar(name)?.to_i32()?; let name = this.read_scalar(name)?.to_i32()?;
// FIXME: Which of these are POSIX, and which are GNU/Linux? // FIXME: Which of these are POSIX, and which are GNU/Linux?
// At least the names seem to all also exist on macOS. // At least the names seem to all also exist on macOS.
let sysconfs: &[(&str, fn(&MiriInterpCx<'_, '_>) -> Scalar<Provenance>)] = &[ let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar<Provenance>)] = &[
("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())), ("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())), ("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())), ("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),

View file

@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool {
false false
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -33,7 +33,7 @@ impl FileDescription for FileHandle {
&mut self, &mut self,
communicate_allowed: bool, communicate_allowed: bool,
bytes: &mut [u8], bytes: &mut [u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
assert!(communicate_allowed, "isolation should have prevented even opening a file"); assert!(communicate_allowed, "isolation should have prevented even opening a file");
Ok(self.file.read(bytes)) Ok(self.file.read(bytes))
@ -43,7 +43,7 @@ impl FileDescription for FileHandle {
&mut self, &mut self,
communicate_allowed: bool, communicate_allowed: bool,
bytes: &[u8], bytes: &[u8],
_ecx: &mut MiriInterpCx<'_, 'tcx>, _ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
assert!(communicate_allowed, "isolation should have prevented even opening a file"); assert!(communicate_allowed, "isolation should have prevented even opening a file");
Ok(self.file.write(bytes)) Ok(self.file.write(bytes))
@ -86,8 +86,8 @@ impl FileDescription for FileHandle {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExtPrivate<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn macos_stat_write_buf( fn macos_stat_write_buf(
&mut self, &mut self,
metadata: FileMetadata, metadata: FileMetadata,
@ -254,8 +254,8 @@ fn maybe_sync_file(
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> { fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
if args.len() < 2 { if args.len() < 2 {
throw_ub_format!( throw_ub_format!(
@ -1540,7 +1540,7 @@ struct FileMetadata {
impl FileMetadata { impl FileMetadata {
fn from_path<'tcx>( fn from_path<'tcx>(
ecx: &mut MiriInterpCx<'_, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
path: &Path, path: &Path,
follow_symlink: bool, follow_symlink: bool,
) -> InterpResult<'tcx, Option<FileMetadata>> { ) -> InterpResult<'tcx, Option<FileMetadata>> {
@ -1551,7 +1551,7 @@ impl FileMetadata {
} }
fn from_fd<'tcx>( fn from_fd<'tcx>(
ecx: &mut MiriInterpCx<'_, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
fd: i32, fd: i32,
) -> InterpResult<'tcx, Option<FileMetadata>> { ) -> InterpResult<'tcx, Option<FileMetadata>> {
let Some(file_descriptor) = ecx.machine.fds.get(fd) else { let Some(file_descriptor) = ecx.machine.fds.get(fd) else {
@ -1573,7 +1573,7 @@ impl FileMetadata {
} }
fn from_meta<'tcx>( fn from_meta<'tcx>(
ecx: &mut MiriInterpCx<'_, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
metadata: Result<std::fs::Metadata, std::io::Error>, metadata: Result<std::fs::Metadata, std::io::Error>,
) -> InterpResult<'tcx, Option<FileMetadata>> { ) -> InterpResult<'tcx, Option<FileMetadata>> {
let metadata = match metadata { let metadata = match metadata {

View file

@ -44,8 +44,8 @@ impl FileDescription for Epoll {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// This function returns a file descriptor referring to the new `Epoll` instance. This file /// This function returns a file descriptor referring to the new `Epoll` instance. This file
/// descriptor is used for all subsequent calls to the epoll interface. If the `flags` argument /// descriptor is used for all subsequent calls to the epoll interface. If the `flags` argument
/// is 0, then this function is the same as `epoll_create()`. /// is 0, then this function is the same as `epoll_create()`.

View file

@ -51,7 +51,7 @@ impl FileDescription for Event {
&mut self, &mut self,
_communicate_allowed: bool, _communicate_allowed: bool,
bytes: &[u8], bytes: &[u8],
ecx: &mut MiriInterpCx<'_, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, io::Result<usize>> { ) -> InterpResult<'tcx, io::Result<usize>> {
let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size let bytes: [u8; 8] = bytes.try_into().unwrap(); // FIXME fail gracefully when this has the wrong size
// Convert from target endianness to host endianness. // Convert from target endianness to host endianness.
@ -66,8 +66,8 @@ impl FileDescription for Event {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// This function creates an `Event` that is used as an event wait/notify mechanism by /// This function creates an `Event` that is used as an event wait/notify mechanism by
/// user-space applications, and by the kernel to notify user-space applications of events. /// user-space applications, and by the kernel to notify user-space applications of events.
/// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized /// The `Event` contains an `u64` counter maintained by the kernel. The counter is initialized

View file

@ -14,8 +14,8 @@ pub fn is_dyn_sym(name: &str) -> bool {
matches!(name, "statx") matches!(name, "statx")
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -4,8 +4,8 @@
use crate::*; use crate::*;
use rustc_target::abi::Size; use rustc_target::abi::Size;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn mremap( fn mremap(
&mut self, &mut self,
old_address: &OpTy<'tcx, Provenance>, old_address: &OpTy<'tcx, Provenance>,

View file

@ -5,7 +5,7 @@ use crate::*;
/// Implementation of the SYS_futex syscall. /// Implementation of the SYS_futex syscall.
/// `args` is the arguments *after* the syscall number. /// `args` is the arguments *after* the syscall number.
pub fn futex<'tcx>( pub fn futex<'tcx>(
this: &mut MiriInterpCx<'_, 'tcx>, this: &mut MiriInterpCx<'tcx>,
args: &[OpTy<'tcx, Provenance>], args: &[OpTy<'tcx, Provenance>],
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx> { ) -> InterpResult<'tcx> {

View file

@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool {
false false
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -17,8 +17,8 @@
use crate::*; use crate::*;
use rustc_target::abi::Size; use rustc_target::abi::Size;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn mmap( fn mmap(
&mut self, &mut self,
addr: &OpTy<'tcx, Provenance>, addr: &OpTy<'tcx, Provenance>,

View file

@ -24,8 +24,8 @@ impl FileDescription for SocketPair {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
/// Currently this function this function is a stub. Eventually we need to /// Currently this function this function is a stub. Eventually we need to
/// properly implement an FD type for sockets and have this function create /// properly implement an FD type for sockets and have this function create
/// two sockets and associated FDs such that writing to one will produce /// two sockets and associated FDs such that writing to one will produce

View file

@ -8,8 +8,8 @@ pub fn is_dyn_sym(name: &str) -> bool {
matches!(name, "pthread_setname_np") matches!(name, "pthread_setname_np")
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -10,8 +10,8 @@ use crate::*;
// - kind: i32 // - kind: i32
#[inline] #[inline]
fn mutexattr_kind_offset<'mir, 'tcx: 'mir>( fn mutexattr_kind_offset<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, u64> { ) -> InterpResult<'tcx, u64> {
Ok(match &*ecx.tcx.sess.target.os { Ok(match &*ecx.tcx.sess.target.os {
"linux" | "illumos" | "solaris" | "macos" => 0, "linux" | "illumos" | "solaris" | "macos" => 0,
@ -19,8 +19,8 @@ fn mutexattr_kind_offset<'mir, 'tcx: 'mir>(
}) })
} }
fn mutexattr_get_kind<'mir, 'tcx: 'mir>( fn mutexattr_get_kind<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
attr_op: &OpTy<'tcx, Provenance>, attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> { ) -> InterpResult<'tcx, i32> {
ecx.deref_pointer_and_read( ecx.deref_pointer_and_read(
@ -32,8 +32,8 @@ fn mutexattr_get_kind<'mir, 'tcx: 'mir>(
.to_i32() .to_i32()
} }
fn mutexattr_set_kind<'mir, 'tcx: 'mir>( fn mutexattr_set_kind<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
attr_op: &OpTy<'tcx, Provenance>, attr_op: &OpTy<'tcx, Provenance>,
kind: i32, kind: i32,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
@ -53,15 +53,15 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
/// in `pthread_mutexattr_settype` function. /// in `pthread_mutexattr_settype` function.
const PTHREAD_MUTEX_NORMAL_FLAG: i32 = 0x8000000; const PTHREAD_MUTEX_NORMAL_FLAG: i32 = 0x8000000;
fn is_mutex_kind_default<'mir, 'tcx: 'mir>( fn is_mutex_kind_default<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
kind: i32, kind: i32,
) -> InterpResult<'tcx, bool> { ) -> InterpResult<'tcx, bool> {
Ok(kind == ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT")) Ok(kind == ecx.eval_libc_i32("PTHREAD_MUTEX_DEFAULT"))
} }
fn is_mutex_kind_normal<'mir, 'tcx: 'mir>( fn is_mutex_kind_normal<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
kind: i32, kind: i32,
) -> InterpResult<'tcx, bool> { ) -> InterpResult<'tcx, bool> {
let mutex_normal_kind = ecx.eval_libc_i32("PTHREAD_MUTEX_NORMAL"); let mutex_normal_kind = ecx.eval_libc_i32("PTHREAD_MUTEX_NORMAL");
@ -73,7 +73,7 @@ fn is_mutex_kind_normal<'mir, 'tcx: 'mir>(
// - id: u32 // - id: u32
// - kind: i32 // - kind: i32
fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { fn mutex_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
let offset = match &*ecx.tcx.sess.target.os { let offset = match &*ecx.tcx.sess.target.os {
"linux" | "illumos" | "solaris" => 0, "linux" | "illumos" | "solaris" => 0,
// macOS stores a signature in the first bytes, so we have to move to offset 4. // macOS stores a signature in the first bytes, so we have to move to offset 4.
@ -99,7 +99,7 @@ fn mutex_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpRe
Ok(offset) Ok(offset)
} }
fn mutex_kind_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { fn mutex_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
// These offsets are picked for compatibility with Linux's static initializer // These offsets are picked for compatibility with Linux's static initializer
// macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.) // macros, e.g. PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP.)
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 }; let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
@ -123,8 +123,8 @@ fn mutex_kind_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
offset offset
} }
fn mutex_get_id<'mir, 'tcx: 'mir>( fn mutex_get_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
mutex_op: &OpTy<'tcx, Provenance>, mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, MutexId> { ) -> InterpResult<'tcx, MutexId> {
ecx.mutex_get_or_create_id( ecx.mutex_get_or_create_id(
@ -134,8 +134,8 @@ fn mutex_get_id<'mir, 'tcx: 'mir>(
) )
} }
fn mutex_reset_id<'mir, 'tcx: 'mir>( fn mutex_reset_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
mutex_op: &OpTy<'tcx, Provenance>, mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
ecx.deref_pointer_and_write( ecx.deref_pointer_and_write(
@ -147,8 +147,8 @@ fn mutex_reset_id<'mir, 'tcx: 'mir>(
) )
} }
fn mutex_get_kind<'mir, 'tcx: 'mir>( fn mutex_get_kind<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
mutex_op: &OpTy<'tcx, Provenance>, mutex_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> { ) -> InterpResult<'tcx, i32> {
ecx.deref_pointer_and_read( ecx.deref_pointer_and_read(
@ -160,8 +160,8 @@ fn mutex_get_kind<'mir, 'tcx: 'mir>(
.to_i32() .to_i32()
} }
fn mutex_set_kind<'mir, 'tcx: 'mir>( fn mutex_set_kind<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
mutex_op: &OpTy<'tcx, Provenance>, mutex_op: &OpTy<'tcx, Provenance>,
kind: i32, kind: i32,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
@ -178,7 +178,7 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
// We ignore the platform layout and store our own fields: // We ignore the platform layout and store our own fields:
// - id: u32 // - id: u32
fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
let offset = match &*ecx.tcx.sess.target.os { let offset = match &*ecx.tcx.sess.target.os {
"linux" | "illumos" | "solaris" => 0, "linux" | "illumos" | "solaris" => 0,
// macOS stores a signature in the first bytes, so we have to move to offset 4. // macOS stores a signature in the first bytes, so we have to move to offset 4.
@ -204,8 +204,8 @@ fn rwlock_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpR
Ok(offset) Ok(offset)
} }
fn rwlock_get_id<'mir, 'tcx: 'mir>( fn rwlock_get_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
rwlock_op: &OpTy<'tcx, Provenance>, rwlock_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, RwLockId> { ) -> InterpResult<'tcx, RwLockId> {
ecx.rwlock_get_or_create_id( ecx.rwlock_get_or_create_id(
@ -220,8 +220,8 @@ fn rwlock_get_id<'mir, 'tcx: 'mir>(
// - clock: i32 // - clock: i32
#[inline] #[inline]
fn condattr_clock_offset<'mir, 'tcx: 'mir>( fn condattr_clock_offset<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
) -> InterpResult<'tcx, u64> { ) -> InterpResult<'tcx, u64> {
Ok(match &*ecx.tcx.sess.target.os { Ok(match &*ecx.tcx.sess.target.os {
"linux" | "illumos" | "solaris" => 0, "linux" | "illumos" | "solaris" => 0,
@ -230,8 +230,8 @@ fn condattr_clock_offset<'mir, 'tcx: 'mir>(
}) })
} }
fn condattr_get_clock_id<'mir, 'tcx: 'mir>( fn condattr_get_clock_id<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
attr_op: &OpTy<'tcx, Provenance>, attr_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> { ) -> InterpResult<'tcx, i32> {
ecx.deref_pointer_and_read( ecx.deref_pointer_and_read(
@ -243,8 +243,8 @@ fn condattr_get_clock_id<'mir, 'tcx: 'mir>(
.to_i32() .to_i32()
} }
fn condattr_set_clock_id<'mir, 'tcx: 'mir>( fn condattr_set_clock_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
attr_op: &OpTy<'tcx, Provenance>, attr_op: &OpTy<'tcx, Provenance>,
clock_id: i32, clock_id: i32,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
@ -262,7 +262,7 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
// - id: u32 // - id: u32
// - clock: i32 // - clock: i32
fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx, u64> { fn cond_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
let offset = match &*ecx.tcx.sess.target.os { let offset = match &*ecx.tcx.sess.target.os {
"linux" | "illumos" | "solaris" => 0, "linux" | "illumos" | "solaris" => 0,
// macOS stores a signature in the first bytes, so we have to move to offset 4. // macOS stores a signature in the first bytes, so we have to move to offset 4.
@ -289,7 +289,7 @@ fn cond_id_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> InterpRes
} }
/// Determines whether this clock represents the real-time clock, CLOCK_REALTIME. /// Determines whether this clock represents the real-time clock, CLOCK_REALTIME.
fn is_cond_clock_realtime<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>, clock_id: i32) -> bool { fn is_cond_clock_realtime<'tcx>(ecx: &MiriInterpCx<'tcx>, clock_id: i32) -> bool {
// To ensure compatibility with PTHREAD_COND_INITIALIZER on all platforms, // To ensure compatibility with PTHREAD_COND_INITIALIZER on all platforms,
// we can't just compare with CLOCK_REALTIME: on Solarish, PTHREAD_COND_INITIALIZER // we can't just compare with CLOCK_REALTIME: on Solarish, PTHREAD_COND_INITIALIZER
// makes the clock 0 but CLOCK_REALTIME is 3. // makes the clock 0 but CLOCK_REALTIME is 3.
@ -298,7 +298,7 @@ fn is_cond_clock_realtime<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>, cloc
|| (clock_id == 0 && clock_id != ecx.eval_libc_i32("CLOCK_MONOTONIC")) || (clock_id == 0 && clock_id != ecx.eval_libc_i32("CLOCK_MONOTONIC"))
} }
fn cond_clock_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 { fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
// macOS doesn't have a clock attribute, but to keep the code uniform we store // macOS doesn't have a clock attribute, but to keep the code uniform we store
// a clock ID in the pthread_cond_t anyway. There's enough space. // a clock ID in the pthread_cond_t anyway. There's enough space.
let offset = 8; let offset = 8;
@ -321,8 +321,8 @@ fn cond_clock_offset<'mir, 'tcx: 'mir>(ecx: &MiriInterpCx<'mir, 'tcx>) -> u64 {
offset offset
} }
fn cond_get_id<'mir, 'tcx: 'mir>( fn cond_get_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
cond_op: &OpTy<'tcx, Provenance>, cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, CondvarId> { ) -> InterpResult<'tcx, CondvarId> {
ecx.condvar_get_or_create_id( ecx.condvar_get_or_create_id(
@ -332,8 +332,8 @@ fn cond_get_id<'mir, 'tcx: 'mir>(
) )
} }
fn cond_reset_id<'mir, 'tcx: 'mir>( fn cond_reset_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
cond_op: &OpTy<'tcx, Provenance>, cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
ecx.deref_pointer_and_write( ecx.deref_pointer_and_write(
@ -345,8 +345,8 @@ fn cond_reset_id<'mir, 'tcx: 'mir>(
) )
} }
fn cond_get_clock_id<'mir, 'tcx: 'mir>( fn cond_get_clock_id<'tcx>(
ecx: &MiriInterpCx<'mir, 'tcx>, ecx: &MiriInterpCx<'tcx>,
cond_op: &OpTy<'tcx, Provenance>, cond_op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, i32> { ) -> InterpResult<'tcx, i32> {
ecx.deref_pointer_and_read( ecx.deref_pointer_and_read(
@ -358,8 +358,8 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>(
.to_i32() .to_i32()
} }
fn cond_set_clock_id<'mir, 'tcx: 'mir>( fn cond_set_clock_id<'tcx>(
ecx: &mut MiriInterpCx<'mir, 'tcx>, ecx: &mut MiriInterpCx<'tcx>,
cond_op: &OpTy<'tcx, Provenance>, cond_op: &OpTy<'tcx, Provenance>,
clock_id: i32, clock_id: i32,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
@ -372,8 +372,8 @@ fn cond_set_clock_id<'mir, 'tcx: 'mir>(
) )
} }
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn pthread_mutexattr_init( fn pthread_mutexattr_init(
&mut self, &mut self,
attr_op: &OpTy<'tcx, Provenance>, attr_op: &OpTy<'tcx, Provenance>,

View file

@ -2,8 +2,8 @@ use crate::*;
use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::layout::LayoutOf;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn pthread_create( fn pthread_create(
&mut self, &mut self,
thread: &OpTy<'tcx, Provenance>, thread: &OpTy<'tcx, Provenance>,

View file

@ -8,8 +8,8 @@ pub fn is_dyn_sym(_name: &str) -> bool {
false false
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -20,8 +20,8 @@ impl VisitProvenance for WindowsEnvVars {
} }
impl WindowsEnvVars { impl WindowsEnvVars {
pub(crate) fn new<'mir, 'tcx>( pub(crate) fn new<'tcx>(
_ecx: &mut InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, _ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
env_vars: FxHashMap<OsString, OsString>, env_vars: FxHashMap<OsString, OsString>,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
Ok(Self { map: env_vars }) Ok(Self { map: env_vars })
@ -33,8 +33,8 @@ impl WindowsEnvVars {
} }
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn GetEnvironmentVariableW( fn GetEnvironmentVariableW(
&mut self, &mut self,

View file

@ -76,8 +76,8 @@ fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
Ok(path::absolute(bytes_to_os_str(&result)?)) Ok(path::absolute(bytes_to_os_str(&result)?))
} }
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner( fn emulate_foreign_item_inner(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,

View file

@ -145,10 +145,10 @@ impl Handle {
} }
} }
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn invalid_handle(&mut self, function_name: &str) -> InterpResult<'tcx, !> { fn invalid_handle(&mut self, function_name: &str) -> InterpResult<'tcx, !> {
throw_machine_stop!(TerminationInfo::Abort(format!( throw_machine_stop!(TerminationInfo::Abort(format!(
"invalid handle passed to `{function_name}`" "invalid handle passed to `{function_name}`"

View file

@ -5,8 +5,8 @@ use rustc_target::abi::Size;
use crate::concurrency::init_once::InitOnceStatus; use crate::concurrency::init_once::InitOnceStatus;
use crate::*; use crate::*;
impl<'mir, 'tcx> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Windows sync primitives are pointer sized. // Windows sync primitives are pointer sized.
// We only use the first 4 bytes for the id. // We only use the first 4 bytes for the id.
@ -44,9 +44,9 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
} }
} }
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn InitOnceBeginInitialize( fn InitOnceBeginInitialize(
&mut self, &mut self,
init_once_op: &OpTy<'tcx, Provenance>, init_once_op: &OpTy<'tcx, Provenance>,

View file

@ -4,10 +4,10 @@ use rustc_target::spec::abi::Abi;
use crate::*; use crate::*;
use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle}; use shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn CreateThread( fn CreateThread(
&mut self, &mut self,
security_op: &OpTy<'tcx, Provenance>, security_op: &OpTy<'tcx, Provenance>,

View file

@ -5,9 +5,9 @@ use rustc_target::spec::abi::Abi;
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_aesni_intrinsic( fn emulate_x86_aesni_intrinsic(
&mut self, &mut self,
@ -134,7 +134,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
// Performs an AES round (given by `f`) on each 128-bit word of // Performs an AES round (given by `f`) on each 128-bit word of
// `state` with the corresponding 128-bit key of `key`. // `state` with the corresponding 128-bit key of `key`.
fn aes_round<'tcx>( fn aes_round<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
state: &OpTy<'tcx, Provenance>, state: &OpTy<'tcx, Provenance>,
key: &OpTy<'tcx, Provenance>, key: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,

View file

@ -12,9 +12,9 @@ use super::{
}; };
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_avx_intrinsic( fn emulate_x86_avx_intrinsic(
&mut self, &mut self,

View file

@ -10,9 +10,9 @@ use super::{
}; };
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_avx2_intrinsic( fn emulate_x86_avx2_intrinsic(
&mut self, &mut self,

View file

@ -20,10 +20,8 @@ mod sse3;
mod sse41; mod sse41;
mod ssse3; mod ssse3;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
crate::MiriInterpCxExt<'mir, 'tcx>
{
fn emulate_x86_intrinsic( fn emulate_x86_intrinsic(
&mut self, &mut self,
link_name: Symbol, link_name: Symbol,
@ -200,7 +198,7 @@ impl FloatBinOp {
/// Convert from the `imm` argument used to specify the comparison /// Convert from the `imm` argument used to specify the comparison
/// operation in intrinsics such as `llvm.x86.sse.cmp.ss`. /// operation in intrinsics such as `llvm.x86.sse.cmp.ss`.
fn cmp_from_imm<'tcx>( fn cmp_from_imm<'tcx>(
this: &crate::MiriInterpCx<'_, 'tcx>, this: &crate::MiriInterpCx<'tcx>,
imm: i8, imm: i8,
intrinsic: Symbol, intrinsic: Symbol,
) -> InterpResult<'tcx, Self> { ) -> InterpResult<'tcx, Self> {
@ -244,7 +242,7 @@ impl FloatBinOp {
/// Performs `which` scalar operation on `left` and `right` and returns /// Performs `which` scalar operation on `left` and `right` and returns
/// the result. /// the result.
fn bin_op_float<'tcx, F: rustc_apfloat::Float>( fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
this: &crate::MiriInterpCx<'_, 'tcx>, this: &crate::MiriInterpCx<'tcx>,
which: FloatBinOp, which: FloatBinOp,
left: &ImmTy<'tcx, Provenance>, left: &ImmTy<'tcx, Provenance>,
right: &ImmTy<'tcx, Provenance>, right: &ImmTy<'tcx, Provenance>,
@ -306,7 +304,7 @@ fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
/// Performs `which` operation on the first component of `left` and `right` /// Performs `which` operation on the first component of `left` and `right`
/// and copies the other components from `left`. The result is stored in `dest`. /// and copies the other components from `left`. The result is stored in `dest`.
fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>( fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: FloatBinOp, which: FloatBinOp,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
@ -337,7 +335,7 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
/// Performs `which` operation on each component of `left` and /// Performs `which` operation on each component of `left` and
/// `right`, storing the result is stored in `dest`. /// `right`, storing the result is stored in `dest`.
fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>( fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: FloatBinOp, which: FloatBinOp,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
@ -384,7 +382,7 @@ enum FloatUnaryOp {
/// Performs `which` scalar operation on `op` and returns the result. /// Performs `which` scalar operation on `op` and returns the result.
#[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects #[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects
fn unary_op_f32<'tcx>( fn unary_op_f32<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: FloatUnaryOp, which: FloatUnaryOp,
op: &ImmTy<'tcx, Provenance>, op: &ImmTy<'tcx, Provenance>,
) -> InterpResult<'tcx, Scalar<Provenance>> { ) -> InterpResult<'tcx, Scalar<Provenance>> {
@ -418,7 +416,7 @@ fn unary_op_f32<'tcx>(
/// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale). /// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
#[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic #[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic
fn apply_random_float_error<F: rustc_apfloat::Float>( fn apply_random_float_error<F: rustc_apfloat::Float>(
this: &mut crate::MiriInterpCx<'_, '_>, this: &mut crate::MiriInterpCx<'_>,
val: F, val: F,
err_scale: i32, err_scale: i32,
) -> F { ) -> F {
@ -435,7 +433,7 @@ fn apply_random_float_error<F: rustc_apfloat::Float>(
/// Performs `which` operation on the first component of `op` and copies /// Performs `which` operation on the first component of `op` and copies
/// the other components. The result is stored in `dest`. /// the other components. The result is stored in `dest`.
fn unary_op_ss<'tcx>( fn unary_op_ss<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: FloatUnaryOp, which: FloatUnaryOp,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -458,7 +456,7 @@ fn unary_op_ss<'tcx>(
/// Performs `which` operation on each component of `op`, storing the /// Performs `which` operation on each component of `op`, storing the
/// result is stored in `dest`. /// result is stored in `dest`.
fn unary_op_ps<'tcx>( fn unary_op_ps<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: FloatUnaryOp, which: FloatUnaryOp,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -495,7 +493,7 @@ enum ShiftOp {
/// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign
/// bit is copied to all bits. /// bit is copied to all bits.
fn shift_simd_by_scalar<'tcx>( fn shift_simd_by_scalar<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
which: ShiftOp, which: ShiftOp,
@ -551,7 +549,7 @@ fn shift_simd_by_scalar<'tcx>(
/// For arithmetic right-shifts, when right is larger than BITS - 1, the sign /// For arithmetic right-shifts, when right is larger than BITS - 1, the sign
/// bit is copied to all bits. /// bit is copied to all bits.
fn shift_simd_by_simd<'tcx>( fn shift_simd_by_simd<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
which: ShiftOp, which: ShiftOp,
@ -603,7 +601,7 @@ fn shift_simd_by_simd<'tcx>(
/// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts /// Takes a 128-bit vector, transmutes it to `[u64; 2]` and extracts
/// the first value. /// the first value.
fn extract_first_u64<'tcx>( fn extract_first_u64<'tcx>(
this: &crate::MiriInterpCx<'_, 'tcx>, this: &crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, u64> { ) -> InterpResult<'tcx, u64> {
// Transmute vector to `[u64; 2]` // Transmute vector to `[u64; 2]`
@ -617,7 +615,7 @@ fn extract_first_u64<'tcx>(
// Rounds the first element of `right` according to `rounding` // Rounds the first element of `right` according to `rounding`
// and copies the remaining elements from `left`. // and copies the remaining elements from `left`.
fn round_first<'tcx, F: rustc_apfloat::Float>( fn round_first<'tcx, F: rustc_apfloat::Float>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
rounding: &OpTy<'tcx, Provenance>, rounding: &OpTy<'tcx, Provenance>,
@ -648,7 +646,7 @@ fn round_first<'tcx, F: rustc_apfloat::Float>(
// Rounds all elements of `op` according to `rounding`. // Rounds all elements of `op` according to `rounding`.
fn round_all<'tcx, F: rustc_apfloat::Float>( fn round_all<'tcx, F: rustc_apfloat::Float>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
rounding: &OpTy<'tcx, Provenance>, rounding: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -700,7 +698,7 @@ fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::R
/// If `op` has more elements than `dest`, extra elements are ignored. If `op` /// If `op` has more elements than `dest`, extra elements are ignored. If `op`
/// has less elements than `dest`, the rest is filled with zeros. /// has less elements than `dest`, the rest is filled with zeros.
fn convert_float_to_int<'tcx>( fn convert_float_to_int<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
rnd: rustc_apfloat::Round, rnd: rustc_apfloat::Round,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -735,7 +733,7 @@ fn convert_float_to_int<'tcx>(
/// In case of overflow (when the operand is the minimum value), the operation /// In case of overflow (when the operand is the minimum value), the operation
/// will wrap around. /// will wrap around.
fn int_abs<'tcx>( fn int_abs<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
) -> InterpResult<'tcx, ()> { ) -> InterpResult<'tcx, ()> {
@ -768,7 +766,7 @@ fn int_abs<'tcx>(
/// * The third element is the `op` vector split into chunks, i.e, it's /// * The third element is the `op` vector split into chunks, i.e, it's
/// type is `[[T; M]; N]` where `T` is the element type of `op`. /// type is `[[T; M]; N]` where `T` is the element type of `op`.
fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>( fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
op: &P, op: &P,
) -> InterpResult<'tcx, (u64, u64, P)> { ) -> InterpResult<'tcx, (u64, u64, P)> {
let simd_layout = op.layout(); let simd_layout = op.layout();
@ -801,7 +799,7 @@ fn split_simd_to_128bit_chunks<'tcx, P: Projectable<'tcx, Provenance>>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn horizontal_bin_op<'tcx>( fn horizontal_bin_op<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
which: mir::BinOp, which: mir::BinOp,
saturating: bool, saturating: bool,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
@ -854,7 +852,7 @@ fn horizontal_bin_op<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit blocks of `left` and `right`). /// 128-bit blocks of `left` and `right`).
fn conditional_dot_product<'tcx>( fn conditional_dot_product<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
imm: &OpTy<'tcx, Provenance>, imm: &OpTy<'tcx, Provenance>,
@ -912,7 +910,7 @@ fn conditional_dot_product<'tcx>(
/// The first is true when all the bits of `op & mask` are zero. /// The first is true when all the bits of `op & mask` are zero.
/// The second is true when `(op & mask) == mask` /// The second is true when `(op & mask) == mask`
fn test_bits_masked<'tcx>( fn test_bits_masked<'tcx>(
this: &crate::MiriInterpCx<'_, 'tcx>, this: &crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
mask: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (bool, bool)> { ) -> InterpResult<'tcx, (bool, bool)> {
@ -943,7 +941,7 @@ fn test_bits_masked<'tcx>(
/// The first is true when the highest bit of each element of `op & mask` is zero. /// The first is true when the highest bit of each element of `op & mask` is zero.
/// The second is true when the highest bit of each element of `!op & mask` is zero. /// The second is true when the highest bit of each element of `!op & mask` is zero.
fn test_high_bits_masked<'tcx>( fn test_high_bits_masked<'tcx>(
this: &crate::MiriInterpCx<'_, 'tcx>, this: &crate::MiriInterpCx<'tcx>,
op: &OpTy<'tcx, Provenance>, op: &OpTy<'tcx, Provenance>,
mask: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>,
) -> InterpResult<'tcx, (bool, bool)> { ) -> InterpResult<'tcx, (bool, bool)> {
@ -974,7 +972,7 @@ fn test_high_bits_masked<'tcx>(
/// Conditionally loads from `ptr` according the high bit of each /// Conditionally loads from `ptr` according the high bit of each
/// element of `mask`. `ptr` does not need to be aligned. /// element of `mask`. `ptr` does not need to be aligned.
fn mask_load<'tcx>( fn mask_load<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
ptr: &OpTy<'tcx, Provenance>, ptr: &OpTy<'tcx, Provenance>,
mask: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1007,7 +1005,7 @@ fn mask_load<'tcx>(
/// Conditionally stores into `ptr` according the high bit of each /// Conditionally stores into `ptr` according the high bit of each
/// element of `mask`. `ptr` does not need to be aligned. /// element of `mask`. `ptr` does not need to be aligned.
fn mask_store<'tcx>( fn mask_store<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
ptr: &OpTy<'tcx, Provenance>, ptr: &OpTy<'tcx, Provenance>,
mask: &OpTy<'tcx, Provenance>, mask: &OpTy<'tcx, Provenance>,
value: &OpTy<'tcx, Provenance>, value: &OpTy<'tcx, Provenance>,
@ -1047,7 +1045,7 @@ fn mask_store<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn mpsadbw<'tcx>( fn mpsadbw<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
imm: &OpTy<'tcx, Provenance>, imm: &OpTy<'tcx, Provenance>,
@ -1104,7 +1102,7 @@ fn mpsadbw<'tcx>(
/// <https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16> /// <https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16>
/// <https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16> /// <https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16>
fn pmulhrsw<'tcx>( fn pmulhrsw<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1143,7 +1141,7 @@ fn pmulhrsw<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn pack_generic<'tcx>( fn pack_generic<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1188,7 +1186,7 @@ fn pack_generic<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn packsswb<'tcx>( fn packsswb<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1207,7 +1205,7 @@ fn packsswb<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn packuswb<'tcx>( fn packuswb<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1226,7 +1224,7 @@ fn packuswb<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn packssdw<'tcx>( fn packssdw<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1245,7 +1243,7 @@ fn packssdw<'tcx>(
/// the is i-th 128-bit chunk of `dest` is calculated with the i-th /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
/// 128-bit chunks of `left` and `right`). /// 128-bit chunks of `left` and `right`).
fn packusdw<'tcx>( fn packusdw<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,
@ -1262,7 +1260,7 @@ fn packusdw<'tcx>(
/// is written to the corresponding output element. /// is written to the corresponding output element.
/// In other words, multiplies `left` with `right.signum()`. /// In other words, multiplies `left` with `right.signum()`.
fn psign<'tcx>( fn psign<'tcx>(
this: &mut crate::MiriInterpCx<'_, 'tcx>, this: &mut crate::MiriInterpCx<'tcx>,
left: &OpTy<'tcx, Provenance>, left: &OpTy<'tcx, Provenance>,
right: &OpTy<'tcx, Provenance>, right: &OpTy<'tcx, Provenance>,
dest: &MPlaceTy<'tcx, Provenance>, dest: &MPlaceTy<'tcx, Provenance>,

View file

@ -9,9 +9,9 @@ use super::{
}; };
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_sse_intrinsic( fn emulate_x86_sse_intrinsic(
&mut self, &mut self,

View file

@ -8,9 +8,9 @@ use super::{
}; };
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_sse2_intrinsic( fn emulate_x86_sse2_intrinsic(
&mut self, &mut self,

View file

@ -5,9 +5,9 @@ use rustc_target::spec::abi::Abi;
use super::horizontal_bin_op; use super::horizontal_bin_op;
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_sse3_intrinsic( fn emulate_x86_sse3_intrinsic(
&mut self, &mut self,

View file

@ -4,9 +4,9 @@ use rustc_target::spec::abi::Abi;
use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked}; use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked};
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_sse41_intrinsic( fn emulate_x86_sse41_intrinsic(
&mut self, &mut self,

View file

@ -5,9 +5,9 @@ use rustc_target::spec::abi::Abi;
use super::{horizontal_bin_op, int_abs, pmulhrsw, psign}; use super::{horizontal_bin_op, int_abs, pmulhrsw, psign};
use crate::*; use crate::*;
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {} impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: pub(super) trait EvalContextExt<'tcx>:
crate::MiriInterpCxExt<'mir, 'tcx> crate::MiriInterpCxExt<'tcx>
{ {
fn emulate_x86_ssse3_intrinsic( fn emulate_x86_ssse3_intrinsic(
&mut self, &mut self,