rustc_const_eval/const_eval/
dummy_machine.rs1use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult};
2use rustc_middle::mir::*;
3use rustc_middle::query::TyCtxtAt;
4use rustc_middle::ty::Ty;
5use rustc_middle::ty::layout::TyAndLayout;
6use rustc_middle::{bug, span_bug, ty};
7use rustc_span::def_id::DefId;
8use rustc_target::callconv::FnAbi;
9
10use crate::interpret::{
11 self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, interp_ok,
12 throw_machine_stop,
13};
14
15pub macro throw_machine_stop_str($($tt:tt)*) {{
18 #[derive(Debug)]
21 struct Zst;
22 impl std::fmt::Display for Zst {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(f, $($tt)*)
26 }
27 }
28
29 impl rustc_middle::mir::interpret::MachineStopType for Zst {
30 fn diagnostic_message(&self) -> rustc_errors::DiagMessage {
31 self.to_string().into()
32 }
33
34 fn add_args(
35 self: Box<Self>,
36 _: &mut dyn FnMut(rustc_errors::DiagArgName, rustc_errors::DiagArgValue),
37 ) {}
38 }
39 throw_machine_stop!(Zst)
40}}
41
42pub struct DummyMachine;
43
44impl HasStaticRootDefId for DummyMachine {
45 fn static_def_id(&self) -> Option<rustc_hir::def_id::LocalDefId> {
46 None
47 }
48}
49
50impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
51 interpret::compile_time_machine!(<'tcx>);
52 const PANIC_ON_ALLOC_FAIL: bool = true;
53
54 const ALL_CONSTS_ARE_PRECHECKED: bool = false;
56
57 #[inline(always)]
58 fn enforce_alignment(_ecx: &InterpCx<'tcx, Self>) -> bool {
59 false }
61
62 fn enforce_validity(_ecx: &InterpCx<'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
63 false
64 }
65
66 fn before_access_global(
67 _tcx: TyCtxtAt<'tcx>,
68 _machine: &Self,
69 _alloc_id: AllocId,
70 alloc: ConstAllocation<'tcx>,
71 _static_def_id: Option<DefId>,
72 is_write: bool,
73 ) -> InterpResult<'tcx> {
74 if is_write {
75 throw_machine_stop_str!("can't write to global");
76 }
77
78 if alloc.inner().mutability.is_mut() {
81 throw_machine_stop_str!("can't access mutable globals in ConstProp");
82 }
83
84 interp_ok(())
85 }
86
87 fn find_mir_or_eval_fn(
88 _ecx: &mut InterpCx<'tcx, Self>,
89 _instance: ty::Instance<'tcx>,
90 _abi: &FnAbi<'tcx, Ty<'tcx>>,
91 _args: &[interpret::FnArg<'tcx, Self::Provenance>],
92 _destination: &interpret::PlaceTy<'tcx, Self::Provenance>,
93 _target: Option<BasicBlock>,
94 _unwind: UnwindAction,
95 ) -> interpret::InterpResult<'tcx, Option<(&'tcx Body<'tcx>, ty::Instance<'tcx>)>> {
96 unimplemented!()
97 }
98
99 fn panic_nounwind(
100 _ecx: &mut InterpCx<'tcx, Self>,
101 _msg: &str,
102 ) -> interpret::InterpResult<'tcx> {
103 unimplemented!()
104 }
105
106 fn call_intrinsic(
107 _ecx: &mut InterpCx<'tcx, Self>,
108 _instance: ty::Instance<'tcx>,
109 _args: &[interpret::OpTy<'tcx, Self::Provenance>],
110 _destination: &interpret::PlaceTy<'tcx, Self::Provenance>,
111 _target: Option<BasicBlock>,
112 _unwind: UnwindAction,
113 ) -> interpret::InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
114 unimplemented!()
115 }
116
117 fn assert_panic(
118 _ecx: &mut InterpCx<'tcx, Self>,
119 _msg: &rustc_middle::mir::AssertMessage<'tcx>,
120 _unwind: UnwindAction,
121 ) -> interpret::InterpResult<'tcx> {
122 unimplemented!()
123 }
124
125 #[inline(always)]
126 fn runtime_checks(_ecx: &InterpCx<'tcx, Self>, r: RuntimeChecks) -> InterpResult<'tcx, bool> {
127 panic!("compiletime machine evaluated {r:?}")
130 }
131
132 fn binary_ptr_op(
133 ecx: &InterpCx<'tcx, Self>,
134 bin_op: BinOp,
135 left: &interpret::ImmTy<'tcx, Self::Provenance>,
136 right: &interpret::ImmTy<'tcx, Self::Provenance>,
137 ) -> interpret::InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
138 use rustc_middle::mir::BinOp::*;
139 interp_ok(match bin_op {
140 Eq | Ne | Lt | Le | Gt | Ge => {
141 assert_eq!(left.layout.backend_repr, right.layout.backend_repr);
143 let size = ecx.pointer_size();
144 let left = match **left {
148 Immediate::Scalar(l) => (l.to_bits(size)?, 0),
149 Immediate::ScalarPair(l1, l2) => (l1.to_bits(size)?, l2.to_bits(size)?),
150 Immediate::Uninit => panic!("we should never see uninit data here"),
151 };
152 let right = match **right {
153 Immediate::Scalar(r) => (r.to_bits(size)?, 0),
154 Immediate::ScalarPair(r1, r2) => (r1.to_bits(size)?, r2.to_bits(size)?),
155 Immediate::Uninit => panic!("we should never see uninit data here"),
156 };
157 let res = match bin_op {
158 Eq => left == right,
159 Ne => left != right,
160 Lt => left < right,
161 Le => left <= right,
162 Gt => left > right,
163 Ge => left >= right,
164 _ => bug!(),
165 };
166 ImmTy::from_bool(res, *ecx.tcx)
167 }
168
169 Add | Sub | BitOr | BitAnd | BitXor => {
172 throw_machine_stop_str!("pointer arithmetic is not handled")
173 }
174
175 _ => span_bug!(ecx.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
176 })
177 }
178
179 fn expose_provenance(
180 _ecx: &InterpCx<'tcx, Self>,
181 _provenance: Self::Provenance,
182 ) -> interpret::InterpResult<'tcx> {
183 unimplemented!()
184 }
185
186 fn init_frame(
187 _ecx: &mut InterpCx<'tcx, Self>,
188 _frame: interpret::Frame<'tcx, Self::Provenance>,
189 ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
190 {
191 unimplemented!()
192 }
193
194 fn stack<'a>(
195 _ecx: &'a InterpCx<'tcx, Self>,
196 ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
197 &[]
199 }
200
201 fn stack_mut<'a>(
202 _ecx: &'a mut InterpCx<'tcx, Self>,
203 ) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
204 unimplemented!()
205 }
206
207 fn get_default_alloc_params(
208 &self,
209 ) -> <Self::Bytes as rustc_middle::mir::interpret::AllocBytes>::AllocParams {
210 }
211}