use rustc_span::def_id::DefId;
use super::{
- AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
- OpTy, Operand, PlaceTy, Pointer, Scalar,
+ AllocId, Allocation, AllocationExtra, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult,
+ Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar,
};
/// Data returned by Machine::stack_pop,
/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
/// The `default()` is used for pointers to consts, statics, vtables and functions.
+ /// The `Debug` formatting is used for displaying pointers; we cannot use `Display`
+ /// as `()` does not implement that, but it should be "nice" output.
type PointerTag: ::std::fmt::Debug + Copy + Eq + Hash + 'static;
/// Machines can define extra (non-instance) things that represent values of function pointers.
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
Err((if int == 0 {
// This is UB, seriously.
- err_ub!(InvalidIntPointerUsage(0))
+ err_ub!(DanglingIntPointer(0, CheckInAllocMsg::InboundsTest))
} else {
// This is just something we cannot support during const-eval.
err_unsup!(ReadBytesAsPointer)
_ptr: Pointer<Self::PointerTag>,
) -> 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)
+ }
+}