1use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult};
2use rustc_middle::mir::*;
3use rustc_middle::query::TyCtxtAt;
4use rustc_middle::ty;
5use rustc_middle::ty::Ty;
6use rustc_middle::ty::layout::TyAndLayout;
7use rustc_span::def_id::DefId;
8use rustc_span::{bug, span_bug};
9use rustc_target::callconv::FnAbi;
10
11use crate::interpret::{
12 self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, interp_ok,
13 throw_machine_stop,
14};
15
16pub macro throw_machine_stop_str($($tt:tt)*) {{
19 #[derive(Debug)]
22 struct Zst;
23 impl std::fmt::Display for Zst {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 write!(f, $($tt)*)
27 }
28 }
29 impl rustc_middle::mir::interpret::MachineStopType for Zst {}
30
31 throw_machine_stop!(Zst)
32}}
33
34pub struct DummyMachine;
35
36impl HasStaticRootDefId for DummyMachine {
37 fn static_def_id(&self) -> Option<rustc_hir::def_id::LocalDefId> {
38 None
39 }
40}
41
42impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
43 type Provenance = CtfeProvenance;
type ProvenanceExtra = bool;
type ExtraFnVal = !;
type MemoryKind = crate::const_eval::MemoryKind;
type MemoryMap =
rustc_data_structures::fx::FxIndexMap<AllocId,
(MemoryKind<Self::MemoryKind>, Allocation)>;
const GLOBAL_KIND: Option<Self::MemoryKind> = None;
type AllocExtra = ();
type FrameExtra = ();
type Bytes = Box<[u8]>;
#[inline(always)]
fn ignore_optional_overflow_checks(_ecx: &InterpCx<'tcx, Self>) -> bool {
false
}
#[inline(always)]
fn unwind_terminate(_ecx: &mut InterpCx<'tcx, Self>,
_reason: mir::UnwindTerminateReason) -> InterpResult<'tcx> {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("unwinding cannot happen during compile-time evaluation")));
}
}
#[inline(always)]
fn check_fn_target_features(_ecx: &InterpCx<'tcx, Self>,
_instance: ty::Instance<'tcx>) -> InterpResult<'tcx> {
interp_ok(())
}
#[inline(always)]
fn call_extra_fn(_ecx: &mut InterpCx<'tcx, Self>, fn_val: !,
_abi: &FnAbi<'tcx, Ty<'tcx>>, _args: &[FnArg<'tcx>],
_destination: &PlaceTy<'tcx, Self::Provenance>,
_target: Option<mir::BasicBlock>, _unwind: mir::UnwindAction)
-> InterpResult<'tcx> {
match fn_val {}
}
#[inline(always)]
fn float_fuse_mul_add(_ecx: &InterpCx<'tcx, Self>) -> bool { true }
#[inline(always)]
fn atomic_load(ecx: &InterpCx<'tcx, Self>,
place: &MPlaceTy<'tcx, Self::Provenance>, _ordering: AtomicOrdering)
-> InterpResult<'tcx, Scalar<Self::Provenance>> {
ecx.read_scalar(place)
}
#[inline(always)]
fn atomic_store(ecx: &mut InterpCx<'tcx, Self>,
place: &MPlaceTy<'tcx, Self::Provenance>,
val: &ImmTy<'tcx, Self::Provenance>, _ordering: AtomicOrdering)
-> InterpResult<'tcx> {
ecx.write_scalar(val.to_scalar(), place)
}
fn atomic_rmw(ecx: &mut InterpCx<'tcx, Self>,
place: &MPlaceTy<'tcx, Self::Provenance>, op: AtomicRmwOp,
operand: &ImmTy<'tcx, Self::Provenance>, _ordering: AtomicOrdering)
-> InterpResult<'tcx, Scalar<Self::Provenance>> {
let old_val = ecx.read_immediate(place)?;
let new_val = ecx.atomic_rmw_op(op, &old_val, operand)?;
ecx.write_immediate(*new_val, place)?;
interp_ok(old_val.to_scalar())
}
fn atomic_compare_exchange(ecx: &mut InterpCx<'tcx, Self>,
place: &MPlaceTy<'tcx, Self::Provenance>,
expected_old: &ImmTy<'tcx, Self::Provenance>,
new: &ImmTy<'tcx, Self::Provenance>, _can_fail_spuriously: bool,
_success_ordering: AtomicOrdering, _failure_ordering: AtomicOrdering)
-> InterpResult<'tcx, (Scalar<Self::Provenance>, bool)> {
let actual_old = ecx.read_immediate(place)?;
let eq =
ecx.binary_op(mir::BinOp::Eq, &actual_old,
expected_old)?.to_scalar().to_bool()?;
if eq { ecx.write_immediate(**new, place)?; }
interp_ok((actual_old.to_scalar(), eq))
}
#[inline(always)]
fn atomic_fence(_ecx: &InterpCx<'tcx, Self>, _ordering: AtomicOrdering,
_singlethread: bool) -> InterpResult<'tcx> {
interp_ok(())
}
#[inline(always)]
fn adjust_global_allocation<'b>(_ecx: &InterpCx<'tcx, Self>, _id: AllocId,
alloc: &'b Allocation)
-> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance>>> {
interp_ok(Cow::Borrowed(alloc))
}
fn init_local_allocation(_ecx: &InterpCx<'tcx, Self>, _id: AllocId,
_kind: MemoryKind<Self::MemoryKind>, _size: Size, _align: Align)
-> InterpResult<'tcx, Self::AllocExtra> {
interp_ok(())
}
fn extern_static_pointer(ecx: &InterpCx<'tcx, Self>, def_id: DefId)
-> InterpResult<'tcx, Pointer> {
interp_ok(Pointer::new(ecx.tcx.reserve_and_set_static_alloc(def_id).into(),
Size::ZERO))
}
#[inline(always)]
fn adjust_alloc_root_pointer(_ecx: &InterpCx<'tcx, Self>,
ptr: Pointer<CtfeProvenance>, _kind: Option<MemoryKind<Self::MemoryKind>>)
-> InterpResult<'tcx, Pointer<CtfeProvenance>> {
interp_ok(ptr)
}
#[inline(always)]
fn ptr_from_addr_cast(_ecx: &InterpCx<'tcx, Self>, addr: u64)
-> InterpResult<'tcx, Pointer<Option<CtfeProvenance>>> {
interp_ok(Pointer::without_provenance(addr))
}
#[inline(always)]
fn ptr_get_alloc(_ecx: &InterpCx<'tcx, Self>, ptr: Pointer<CtfeProvenance>,
_size: i64) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
let (prov, offset) = ptr.prov_and_relative_offset();
Some((prov.alloc_id(), offset, prov.immutable()))
}
#[inline(always)]
fn get_global_alloc_salt(_ecx: &InterpCx<'tcx, Self>,
_instance: Option<ty::Instance<'tcx>>) -> usize {
CTFE_ALLOC_SALT
}interpret::compile_time_machine!(<'tcx>);
44 const PANIC_ON_ALLOC_FAIL: bool = true;
45
46 const ALL_CONSTS_ARE_PRECHECKED: bool = false;
48
49 #[inline(always)]
50 fn enforce_alignment(_ecx: &InterpCx<'tcx, Self>) -> bool {
51 false }
53
54 fn enforce_validity(_ecx: &InterpCx<'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
55 false
56 }
57
58 fn before_access_global(
59 _tcx: TyCtxtAt<'tcx>,
60 _machine: &Self,
61 _alloc_id: AllocId,
62 alloc: ConstAllocation<'tcx>,
63 _static_def_id: Option<DefId>,
64 is_write: bool,
65 ) -> InterpResult<'tcx> {
66 if is_write {
67 {
struct Zst;
#[automatically_derived]
impl ::core::fmt::Debug for Zst {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Zst")
}
}
impl std::fmt::Display for Zst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("can\'t write to global"))
}
}
impl rustc_middle::mir::interpret::MachineStopType for Zst {}
do yeet ::rustc_middle::mir::interpret::InterpErrorKind::MachineStop(Box::new(Zst))
};throw_machine_stop_str!("can't write to global");
68 }
69
70 if alloc.inner().mutability.is_mut() {
73 {
struct Zst;
#[automatically_derived]
impl ::core::fmt::Debug for Zst {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Zst")
}
}
impl std::fmt::Display for Zst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("can\'t access mutable globals in ConstProp"))
}
}
impl rustc_middle::mir::interpret::MachineStopType for Zst {}
do yeet ::rustc_middle::mir::interpret::InterpErrorKind::MachineStop(Box::new(Zst))
};throw_machine_stop_str!("can't access mutable globals in ConstProp");
74 }
75
76 interp_ok(())
77 }
78
79 fn find_mir_or_eval_fn(
80 _ecx: &mut InterpCx<'tcx, Self>,
81 _instance: ty::Instance<'tcx>,
82 _abi: &FnAbi<'tcx, Ty<'tcx>>,
83 _args: &[interpret::FnArg<'tcx, Self::Provenance>],
84 _destination: &interpret::PlaceTy<'tcx, Self::Provenance>,
85 _target: Option<BasicBlock>,
86 _unwind: UnwindAction,
87 ) -> interpret::InterpResult<'tcx, Option<(&'tcx Body<'tcx>, ty::Instance<'tcx>)>> {
88 ::core::panicking::panic("not implemented")unimplemented!()
89 }
90
91 fn panic_nounwind(
92 _ecx: &mut InterpCx<'tcx, Self>,
93 _msg: &str,
94 ) -> interpret::InterpResult<'tcx> {
95 ::core::panicking::panic("not implemented")unimplemented!()
96 }
97
98 fn call_intrinsic(
99 _ecx: &mut InterpCx<'tcx, Self>,
100 _instance: ty::Instance<'tcx>,
101 _args: &[interpret::OpTy<'tcx, Self::Provenance>],
102 _destination: &interpret::PlaceTy<'tcx, Self::Provenance>,
103 _target: Option<BasicBlock>,
104 _unwind: UnwindAction,
105 ) -> interpret::InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
106 ::core::panicking::panic("not implemented")unimplemented!()
107 }
108
109 fn call_llvm_intrinsic(
110 _ecx: &mut InterpCx<'tcx, Self>,
111 _instance: ty::Instance<'tcx>,
112 _args: &[interpret::OpTy<'tcx, Self::Provenance>],
113 _destination: &interpret::PlaceTy<'tcx, Self::Provenance>,
114 _target: Option<BasicBlock>,
115 ) -> interpret::InterpResult<'tcx> {
116 ::core::panicking::panic("not implemented")unimplemented!()
117 }
118
119 fn assert_panic(
120 _ecx: &mut InterpCx<'tcx, Self>,
121 _msg: &rustc_middle::mir::AssertMessage<'tcx>,
122 _unwind: UnwindAction,
123 ) -> interpret::InterpResult<'tcx> {
124 ::core::panicking::panic("not implemented")unimplemented!()
125 }
126
127 #[inline(always)]
128 fn runtime_checks(_ecx: &InterpCx<'tcx, Self>, r: RuntimeChecks) -> InterpResult<'tcx, bool> {
129 {
::core::panicking::panic_fmt(format_args!("compiletime machine evaluated {0:?}",
r));
}panic!("compiletime machine evaluated {r:?}")
132 }
133
134 fn binary_ptr_op(
135 ecx: &InterpCx<'tcx, Self>,
136 bin_op: BinOp,
137 left: &interpret::ImmTy<'tcx, Self::Provenance>,
138 right: &interpret::ImmTy<'tcx, Self::Provenance>,
139 ) -> interpret::InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
140 use rustc_middle::mir::BinOp::*;
141 interp_ok(match bin_op {
142 Eq | Ne | Lt | Le | Gt | Ge => {
143 {
match (&left.layout.backend_repr, &right.layout.backend_repr) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(left.layout.backend_repr, right.layout.backend_repr);
145 let size = ecx.pointer_size();
146 let left = match **left {
150 Immediate::Scalar(l) => (l.to_bits(size)?, 0),
151 Immediate::ScalarPair(l1, l2) => (l1.to_bits(size)?, l2.to_bits(size)?),
152 Immediate::Uninit => {
::core::panicking::panic_fmt(format_args!("we should never see uninit data here"));
}panic!("we should never see uninit data here"),
153 };
154 let right = match **right {
155 Immediate::Scalar(r) => (r.to_bits(size)?, 0),
156 Immediate::ScalarPair(r1, r2) => (r1.to_bits(size)?, r2.to_bits(size)?),
157 Immediate::Uninit => {
::core::panicking::panic_fmt(format_args!("we should never see uninit data here"));
}panic!("we should never see uninit data here"),
158 };
159 let res = match bin_op {
160 Eq => left == right,
161 Ne => left != right,
162 Lt => left < right,
163 Le => left <= right,
164 Gt => left > right,
165 Ge => left >= right,
166 _ => bug_impl(None, format_args!("impossible case reached"), Location::caller())bug!(),
167 };
168 ImmTy::from_bool(res, *ecx.tcx)
169 }
170
171 Add | Sub | BitOr | BitAnd | BitXor => {
174 {
struct Zst;
#[automatically_derived]
impl ::core::fmt::Debug for Zst {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Zst")
}
}
impl std::fmt::Display for Zst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("pointer arithmetic is not handled"))
}
}
impl rustc_middle::mir::interpret::MachineStopType for Zst {}
do yeet ::rustc_middle::mir::interpret::InterpErrorKind::MachineStop(Box::new(Zst))
}throw_machine_stop_str!("pointer arithmetic is not handled")
175 }
176
177 _ => bug_impl(Some(ecx.cur_span()),
format_args!("Invalid operator on pointers: {0:?}", bin_op),
Location::caller())span_bug!(ecx.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
178 })
179 }
180
181 fn expose_provenance(
182 _ecx: &InterpCx<'tcx, Self>,
183 _provenance: Self::Provenance,
184 ) -> interpret::InterpResult<'tcx> {
185 ::core::panicking::panic("not implemented")unimplemented!()
186 }
187
188 fn init_frame(
189 _ecx: &mut InterpCx<'tcx, Self>,
190 _frame: interpret::Frame<'tcx, Self::Provenance>,
191 ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
192 {
193 ::core::panicking::panic("not implemented")unimplemented!()
194 }
195
196 fn stack<'a>(
197 _ecx: &'a InterpCx<'tcx, Self>,
198 ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
199 &[]
201 }
202
203 fn stack_mut<'a>(
204 _ecx: &'a mut InterpCx<'tcx, Self>,
205 ) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
206 ::core::panicking::panic("not implemented")unimplemented!()
207 }
208
209 fn get_default_alloc_params(
210 &self,
211 ) -> <Self::Bytes as rustc_middle::mir::interpret::AllocBytes>::AllocParams {
212 }
213}