Rollup merge of #71615 - RalfJung:share-machine-code, r=oli-obk
share some common code for compile-time miri instances Fixes https://github.com/rust-lang/rust/issues/71129 r? @oli-obk
This commit is contained in:
commit
0bcdd5ffb8
@ -1,7 +1,7 @@
|
|||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::layout::HasTyCtxt;
|
use rustc_middle::ty::layout::HasTyCtxt;
|
||||||
use rustc_middle::ty::{self, Ty};
|
use rustc_middle::ty::{self, Ty};
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::Borrow;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
@ -13,8 +13,8 @@ use rustc_middle::mir::AssertMessage;
|
|||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
|
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
self, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
|
self, compile_time_machine, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx,
|
||||||
OpTy, PlaceTy, Pointer, Scalar,
|
InterpResult, Memory, OpTy, PlaceTy, Pointer, Scalar,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::error::*;
|
use super::error::*;
|
||||||
@ -171,29 +171,9 @@ impl interpret::MayLeak for ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> {
|
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, 'tcx> {
|
||||||
type MemoryKind = !;
|
compile_time_machine!(<'mir, 'tcx>);
|
||||||
type PointerTag = ();
|
|
||||||
type ExtraFnVal = !;
|
|
||||||
|
|
||||||
type FrameExtra = ();
|
|
||||||
type MemoryExtra = MemoryExtra;
|
type MemoryExtra = MemoryExtra;
|
||||||
type AllocExtra = ();
|
|
||||||
|
|
||||||
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
|
|
||||||
|
|
||||||
const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool {
|
|
||||||
// We do not check for alignment to avoid having to carry an `Align`
|
|
||||||
// in `ConstValue::ByRef`.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
|
||||||
false // for now, we don't enforce validity
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_mir_or_eval_fn(
|
fn find_mir_or_eval_fn(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
@ -241,16 +221,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_extra_fn(
|
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
|
||||||
fn_val: !,
|
|
||||||
_args: &[OpTy<'tcx>],
|
|
||||||
_ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
|
|
||||||
_unwind: Option<mir::BasicBlock>,
|
|
||||||
) -> InterpResult<'tcx> {
|
|
||||||
match fn_val {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_intrinsic(
|
fn call_intrinsic(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
@ -310,20 +280,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||||||
Err(ConstEvalErrKind::NeedsRfc("pointer arithmetic or comparison".to_string()).into())
|
Err(ConstEvalErrKind::NeedsRfc("pointer arithmetic or comparison".to_string()).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn init_allocation_extra<'b>(
|
|
||||||
_memory_extra: &MemoryExtra,
|
|
||||||
_id: AllocId,
|
|
||||||
alloc: Cow<'b, Allocation>,
|
|
||||||
_kind: Option<MemoryKind<!>>,
|
|
||||||
) -> (Cow<'b, Allocation<Self::PointerTag>>, Self::PointerTag) {
|
|
||||||
// We do not use a tag so we can just cheaply forward the allocation
|
|
||||||
(alloc, ())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn tag_global_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag {}
|
|
||||||
|
|
||||||
fn box_alloc(
|
fn box_alloc(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_dest: PlaceTy<'tcx>,
|
_dest: PlaceTy<'tcx>,
|
||||||
@ -345,14 +301,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn init_frame_extra(
|
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
|
||||||
frame: Frame<'mir, 'tcx>,
|
|
||||||
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
|
|
||||||
Ok(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn stack(
|
fn stack(
|
||||||
ecx: &'a InterpCx<'mir, 'tcx, Self>,
|
ecx: &'a InterpCx<'mir, 'tcx, Self>,
|
||||||
|
@ -357,3 +357,67 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||||||
_ptr: Pointer<Self::PointerTag>,
|
_ptr: Pointer<Self::PointerTag>,
|
||||||
) -> InterpResult<'tcx, u64>;
|
) -> InterpResult<'tcx, u64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||||
|
type PointerTag = ();
|
||||||
|
type ExtraFnVal = !;
|
||||||
|
|
||||||
|
type MemoryKind = !;
|
||||||
|
type MemoryMap = rustc_data_structures::fx::FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
|
||||||
|
const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
|
||||||
|
|
||||||
|
type AllocExtra = ();
|
||||||
|
type FrameExtra = ();
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool {
|
||||||
|
// We do not check for alignment to avoid having to carry an `Align`
|
||||||
|
// in `ConstValue::ByRef`.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn enforce_validity(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
|
||||||
|
false // for now, we don't enforce validity
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn call_extra_fn(
|
||||||
|
_ecx: &mut InterpCx<$mir, $tcx, Self>,
|
||||||
|
fn_val: !,
|
||||||
|
_args: &[OpTy<$tcx>],
|
||||||
|
_ret: Option<(PlaceTy<$tcx>, mir::BasicBlock)>,
|
||||||
|
_unwind: Option<mir::BasicBlock>,
|
||||||
|
) -> InterpResult<$tcx> {
|
||||||
|
match fn_val {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn init_allocation_extra<'b>(
|
||||||
|
_memory_extra: &Self::MemoryExtra,
|
||||||
|
_id: AllocId,
|
||||||
|
alloc: Cow<'b, Allocation>,
|
||||||
|
_kind: Option<MemoryKind<!>>,
|
||||||
|
) -> (Cow<'b, Allocation<Self::PointerTag>>, Self::PointerTag) {
|
||||||
|
// We do not use a tag so we can just cheaply forward the allocation
|
||||||
|
(alloc, ())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn tag_global_base_pointer(
|
||||||
|
_memory_extra: &Self::MemoryExtra,
|
||||||
|
_id: AllocId,
|
||||||
|
) -> Self::PointerTag {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn init_frame_extra(
|
||||||
|
_ecx: &mut InterpCx<$mir, $tcx, Self>,
|
||||||
|
frame: Frame<$mir, $tcx>,
|
||||||
|
) -> InterpResult<$tcx, Frame<$mir, $tcx>> {
|
||||||
|
Ok(frame)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@ pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in
|
|||||||
|
|
||||||
pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup};
|
pub use self::eval_context::{Frame, InterpCx, LocalState, LocalValue, StackPopCleanup};
|
||||||
pub use self::intern::{intern_const_alloc_recursive, InternKind};
|
pub use self::intern::{intern_const_alloc_recursive, InternKind};
|
||||||
pub use self::machine::{AllocMap, Machine, MayLeak, StackPopJump};
|
pub use self::machine::{compile_time_machine, AllocMap, Machine, MayLeak, StackPopJump};
|
||||||
pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
|
pub use self::memory::{AllocCheck, FnVal, Memory, MemoryKind};
|
||||||
pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
|
pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
|
||||||
pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
|
pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
|
||||||
|
@ -13,6 +13,7 @@ Rust MIR: a lowered representation of Rust.
|
|||||||
#![feature(const_fn)]
|
#![feature(const_fn)]
|
||||||
#![feature(const_panic)]
|
#![feature(const_panic)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
|
#![feature(decl_macro)]
|
||||||
#![feature(drain_filter)]
|
#![feature(drain_filter)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
#![feature(iter_order_by)]
|
#![feature(iter_order_by)]
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
//! Propagates constants for early reporting of statically known
|
//! Propagates constants for early reporting of statically known
|
||||||
//! assertion failures
|
//! assertion failures
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
use rustc_ast::ast::Mutability;
|
use rustc_ast::ast::Mutability;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::HirId;
|
use rustc_hir::HirId;
|
||||||
use rustc_index::bit_set::BitSet;
|
use rustc_index::bit_set::BitSet;
|
||||||
@ -29,9 +27,9 @@ use rustc_trait_selection::traits;
|
|||||||
|
|
||||||
use crate::const_eval::error_to_const_error;
|
use crate::const_eval::error_to_const_error;
|
||||||
use crate::interpret::{
|
use crate::interpret::{
|
||||||
self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InternKind,
|
self, compile_time_machine, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy,
|
||||||
InterpCx, LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy,
|
Immediate, InternKind, InterpCx, LocalState, LocalValue, Memory, MemoryKind, OpTy,
|
||||||
Pointer, ScalarMaybeUndef, StackPopCleanup,
|
Operand as InterpOperand, PlaceTy, Pointer, ScalarMaybeUndef, StackPopCleanup,
|
||||||
};
|
};
|
||||||
use crate::transform::{MirPass, MirSource};
|
use crate::transform::{MirPass, MirSource};
|
||||||
|
|
||||||
@ -162,27 +160,9 @@ impl<'mir, 'tcx> ConstPropMachine<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> {
|
impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx> {
|
||||||
type MemoryKind = !;
|
compile_time_machine!(<'mir, 'tcx>);
|
||||||
type PointerTag = ();
|
|
||||||
type ExtraFnVal = !;
|
|
||||||
|
|
||||||
type FrameExtra = ();
|
|
||||||
type MemoryExtra = ();
|
type MemoryExtra = ();
|
||||||
type AllocExtra = ();
|
|
||||||
|
|
||||||
type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;
|
|
||||||
|
|
||||||
const GLOBAL_KIND: Option<!> = None; // no copying of globals from `tcx` to machine memory
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn enforce_alignment(_memory_extra: &Self::MemoryExtra) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn enforce_validity(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_mir_or_eval_fn(
|
fn find_mir_or_eval_fn(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
@ -194,16 +174,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
|||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_extra_fn(
|
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
|
||||||
fn_val: !,
|
|
||||||
_args: &[OpTy<'tcx>],
|
|
||||||
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
|
|
||||||
_unwind: Option<BasicBlock>,
|
|
||||||
) -> InterpResult<'tcx> {
|
|
||||||
match fn_val {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call_intrinsic(
|
fn call_intrinsic(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_instance: ty::Instance<'tcx>,
|
_instance: ty::Instance<'tcx>,
|
||||||
@ -236,20 +206,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
|||||||
throw_machine_stop_str!("pointer arithmetic or comparisons aren't supported in ConstProp")
|
throw_machine_stop_str!("pointer arithmetic or comparisons aren't supported in ConstProp")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn init_allocation_extra<'b>(
|
|
||||||
_memory_extra: &(),
|
|
||||||
_id: AllocId,
|
|
||||||
alloc: Cow<'b, Allocation>,
|
|
||||||
_kind: Option<MemoryKind<!>>,
|
|
||||||
) -> (Cow<'b, Allocation<Self::PointerTag>>, Self::PointerTag) {
|
|
||||||
// We do not use a tag so we can just cheaply forward the allocation
|
|
||||||
(alloc, ())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn tag_global_base_pointer(_memory_extra: &(), _id: AllocId) -> Self::PointerTag {}
|
|
||||||
|
|
||||||
fn box_alloc(
|
fn box_alloc(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_dest: PlaceTy<'tcx>,
|
_dest: PlaceTy<'tcx>,
|
||||||
@ -290,14 +246,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn init_frame_extra(
|
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
|
||||||
frame: Frame<'mir, 'tcx>,
|
|
||||||
) -> InterpResult<'tcx, Frame<'mir, 'tcx>> {
|
|
||||||
Ok(frame)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn stack(
|
fn stack(
|
||||||
ecx: &'a InterpCx<'mir, 'tcx, Self>,
|
ecx: &'a InterpCx<'mir, 'tcx, Self>,
|
||||||
|
Loading…
Reference in New Issue
Block a user