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 fn binary_ptr_op(
126 ecx: &InterpCx<'tcx, Self>,
127 bin_op: BinOp,
128 left: &interpret::ImmTy<'tcx, Self::Provenance>,
129 right: &interpret::ImmTy<'tcx, Self::Provenance>,
130 ) -> interpret::InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
131 use rustc_middle::mir::BinOp::*;
132 interp_ok(match bin_op {
133 Eq | Ne | Lt | Le | Gt | Ge => {
134 assert_eq!(left.layout.backend_repr, right.layout.backend_repr);
136 let size = ecx.pointer_size();
137 let left = match **left {
141 Immediate::Scalar(l) => (l.to_bits(size)?, 0),
142 Immediate::ScalarPair(l1, l2) => (l1.to_bits(size)?, l2.to_bits(size)?),
143 Immediate::Uninit => panic!("we should never see uninit data here"),
144 };
145 let right = match **right {
146 Immediate::Scalar(r) => (r.to_bits(size)?, 0),
147 Immediate::ScalarPair(r1, r2) => (r1.to_bits(size)?, r2.to_bits(size)?),
148 Immediate::Uninit => panic!("we should never see uninit data here"),
149 };
150 let res = match bin_op {
151 Eq => left == right,
152 Ne => left != right,
153 Lt => left < right,
154 Le => left <= right,
155 Gt => left > right,
156 Ge => left >= right,
157 _ => bug!(),
158 };
159 ImmTy::from_bool(res, *ecx.tcx)
160 }
161
162 Add | Sub | BitOr | BitAnd | BitXor => {
165 throw_machine_stop_str!("pointer arithmetic is not handled")
166 }
167
168 _ => span_bug!(ecx.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
169 })
170 }
171
172 fn expose_provenance(
173 _ecx: &InterpCx<'tcx, Self>,
174 _provenance: Self::Provenance,
175 ) -> interpret::InterpResult<'tcx> {
176 unimplemented!()
177 }
178
179 fn init_frame(
180 _ecx: &mut InterpCx<'tcx, Self>,
181 _frame: interpret::Frame<'tcx, Self::Provenance>,
182 ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
183 {
184 unimplemented!()
185 }
186
187 fn stack<'a>(
188 _ecx: &'a InterpCx<'tcx, Self>,
189 ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
190 &[]
192 }
193
194 fn stack_mut<'a>(
195 _ecx: &'a mut InterpCx<'tcx, Self>,
196 ) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
197 unimplemented!()
198 }
199
200 fn get_default_alloc_params(
201 &self,
202 ) -> <Self::Bytes as rustc_middle::mir::interpret::AllocBytes>::AllocParams {
203 }
204}