rustc_const_eval/const_eval/
dummy_machine.rs
1use 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 type MemoryKind = !;
53 const PANIC_ON_ALLOC_FAIL: bool = true;
54
55 const ALL_CONSTS_ARE_PRECHECKED: bool = false;
57
58 #[inline(always)]
59 fn enforce_alignment(_ecx: &InterpCx<'tcx, Self>) -> bool {
60 false }
62
63 fn enforce_validity(_ecx: &InterpCx<'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
64 false
65 }
66
67 fn before_access_global(
68 _tcx: TyCtxtAt<'tcx>,
69 _machine: &Self,
70 _alloc_id: AllocId,
71 alloc: ConstAllocation<'tcx>,
72 _static_def_id: Option<DefId>,
73 is_write: bool,
74 ) -> InterpResult<'tcx> {
75 if is_write {
76 throw_machine_stop_str!("can't write to global");
77 }
78
79 if alloc.inner().mutability.is_mut() {
82 throw_machine_stop_str!("can't access mutable globals in ConstProp");
83 }
84
85 interp_ok(())
86 }
87
88 fn find_mir_or_eval_fn(
89 _ecx: &mut InterpCx<'tcx, Self>,
90 _instance: ty::Instance<'tcx>,
91 _abi: &FnAbi<'tcx, Ty<'tcx>>,
92 _args: &[interpret::FnArg<'tcx, Self::Provenance>],
93 _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>,
94 _target: Option<BasicBlock>,
95 _unwind: UnwindAction,
96 ) -> interpret::InterpResult<'tcx, Option<(&'tcx Body<'tcx>, ty::Instance<'tcx>)>> {
97 unimplemented!()
98 }
99
100 fn panic_nounwind(
101 _ecx: &mut InterpCx<'tcx, Self>,
102 _msg: &str,
103 ) -> interpret::InterpResult<'tcx> {
104 unimplemented!()
105 }
106
107 fn call_intrinsic(
108 _ecx: &mut InterpCx<'tcx, Self>,
109 _instance: ty::Instance<'tcx>,
110 _args: &[interpret::OpTy<'tcx, Self::Provenance>],
111 _destination: &interpret::MPlaceTy<'tcx, Self::Provenance>,
112 _target: Option<BasicBlock>,
113 _unwind: UnwindAction,
114 ) -> interpret::InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
115 unimplemented!()
116 }
117
118 fn assert_panic(
119 _ecx: &mut InterpCx<'tcx, Self>,
120 _msg: &rustc_middle::mir::AssertMessage<'tcx>,
121 _unwind: UnwindAction,
122 ) -> interpret::InterpResult<'tcx> {
123 unimplemented!()
124 }
125
126 fn binary_ptr_op(
127 ecx: &InterpCx<'tcx, Self>,
128 bin_op: BinOp,
129 left: &interpret::ImmTy<'tcx, Self::Provenance>,
130 right: &interpret::ImmTy<'tcx, Self::Provenance>,
131 ) -> interpret::InterpResult<'tcx, ImmTy<'tcx, Self::Provenance>> {
132 use rustc_middle::mir::BinOp::*;
133 interp_ok(match bin_op {
134 Eq | Ne | Lt | Le | Gt | Ge => {
135 assert_eq!(left.layout.backend_repr, right.layout.backend_repr);
137 let size = ecx.pointer_size();
138 let left = match **left {
142 Immediate::Scalar(l) => (l.to_bits(size)?, 0),
143 Immediate::ScalarPair(l1, l2) => (l1.to_bits(size)?, l2.to_bits(size)?),
144 Immediate::Uninit => panic!("we should never see uninit data here"),
145 };
146 let right = match **right {
147 Immediate::Scalar(r) => (r.to_bits(size)?, 0),
148 Immediate::ScalarPair(r1, r2) => (r1.to_bits(size)?, r2.to_bits(size)?),
149 Immediate::Uninit => panic!("we should never see uninit data here"),
150 };
151 let res = match bin_op {
152 Eq => left == right,
153 Ne => left != right,
154 Lt => left < right,
155 Le => left <= right,
156 Gt => left > right,
157 Ge => left >= right,
158 _ => bug!(),
159 };
160 ImmTy::from_bool(res, *ecx.tcx)
161 }
162
163 Add | Sub | BitOr | BitAnd | BitXor => {
166 throw_machine_stop_str!("pointer arithmetic is not handled")
167 }
168
169 _ => span_bug!(ecx.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
170 })
171 }
172
173 fn expose_provenance(
174 _ecx: &InterpCx<'tcx, Self>,
175 _provenance: Self::Provenance,
176 ) -> interpret::InterpResult<'tcx> {
177 unimplemented!()
178 }
179
180 fn init_frame(
181 _ecx: &mut InterpCx<'tcx, Self>,
182 _frame: interpret::Frame<'tcx, Self::Provenance>,
183 ) -> interpret::InterpResult<'tcx, interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>>
184 {
185 unimplemented!()
186 }
187
188 fn stack<'a>(
189 _ecx: &'a InterpCx<'tcx, Self>,
190 ) -> &'a [interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>] {
191 &[]
193 }
194
195 fn stack_mut<'a>(
196 _ecx: &'a mut InterpCx<'tcx, Self>,
197 ) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
198 unimplemented!()
199 }
200}