1use rustc_middle::mir::mono::MonoItem;
4use rustc_middle::{bug, mir};
5use rustc_smir::Tables;
6use rustc_smir::bridge::SmirError;
7use rustc_smir::context::SmirCtxt;
8
9use crate::compiler_interface::BridgeTys;
10use crate::mir::alloc::GlobalAlloc;
11use crate::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment};
12use crate::ty::{Allocation, ConstantKind, MirConst};
13use crate::unstable::Stable;
14use crate::{Error, alloc, opaque};
15
16impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
17 type T = crate::mir::Body;
18
19 fn stable<'cx>(
20 &self,
21 tables: &mut Tables<'cx, BridgeTys>,
22 cx: &SmirCtxt<'cx, BridgeTys>,
23 ) -> Self::T {
24 crate::mir::Body::new(
25 self.basic_blocks
26 .iter()
27 .map(|block| crate::mir::BasicBlock {
28 terminator: block.terminator().stable(tables, cx),
29 statements: block
30 .statements
31 .iter()
32 .map(|statement| statement.stable(tables, cx))
33 .collect(),
34 })
35 .collect(),
36 self.local_decls
37 .iter()
38 .map(|decl| crate::mir::LocalDecl {
39 ty: decl.ty.stable(tables, cx),
40 span: decl.source_info.span.stable(tables, cx),
41 mutability: decl.mutability.stable(tables, cx),
42 })
43 .collect(),
44 self.arg_count,
45 self.var_debug_info.iter().map(|info| info.stable(tables, cx)).collect(),
46 self.spread_arg.stable(tables, cx),
47 self.span.stable(tables, cx),
48 )
49 }
50}
51
52impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> {
53 type T = crate::mir::VarDebugInfo;
54 fn stable<'cx>(
55 &self,
56 tables: &mut Tables<'cx, BridgeTys>,
57 cx: &SmirCtxt<'cx, BridgeTys>,
58 ) -> Self::T {
59 crate::mir::VarDebugInfo {
60 name: self.name.to_string(),
61 source_info: self.source_info.stable(tables, cx),
62 composite: self.composite.as_ref().map(|composite| composite.stable(tables, cx)),
63 value: self.value.stable(tables, cx),
64 argument_index: self.argument_index,
65 }
66 }
67}
68
69impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
70 type T = crate::mir::Statement;
71 fn stable<'cx>(
72 &self,
73 tables: &mut Tables<'cx, BridgeTys>,
74 cx: &SmirCtxt<'cx, BridgeTys>,
75 ) -> Self::T {
76 Statement {
77 kind: self.kind.stable(tables, cx),
78 span: self.source_info.span.stable(tables, cx),
79 }
80 }
81}
82
83impl<'tcx> Stable<'tcx> for mir::SourceInfo {
84 type T = crate::mir::SourceInfo;
85 fn stable<'cx>(
86 &self,
87 tables: &mut Tables<'cx, BridgeTys>,
88 cx: &SmirCtxt<'cx, BridgeTys>,
89 ) -> Self::T {
90 crate::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() }
91 }
92}
93
94impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> {
95 type T = crate::mir::VarDebugInfoFragment;
96 fn stable<'cx>(
97 &self,
98 tables: &mut Tables<'cx, BridgeTys>,
99 cx: &SmirCtxt<'cx, BridgeTys>,
100 ) -> Self::T {
101 VarDebugInfoFragment {
102 ty: self.ty.stable(tables, cx),
103 projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(),
104 }
105 }
106}
107
108impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> {
109 type T = crate::mir::VarDebugInfoContents;
110 fn stable<'cx>(
111 &self,
112 tables: &mut Tables<'cx, BridgeTys>,
113 cx: &SmirCtxt<'cx, BridgeTys>,
114 ) -> Self::T {
115 match self {
116 mir::VarDebugInfoContents::Place(place) => {
117 crate::mir::VarDebugInfoContents::Place(place.stable(tables, cx))
118 }
119 mir::VarDebugInfoContents::Const(const_operand) => {
120 let op = ConstOperand {
121 span: const_operand.span.stable(tables, cx),
122 user_ty: const_operand.user_ty.map(|index| index.as_usize()),
123 const_: const_operand.const_.stable(tables, cx),
124 };
125 crate::mir::VarDebugInfoContents::Const(op)
126 }
127 }
128 }
129}
130
131impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> {
132 type T = crate::mir::StatementKind;
133 fn stable<'cx>(
134 &self,
135 tables: &mut Tables<'cx, BridgeTys>,
136 cx: &SmirCtxt<'cx, BridgeTys>,
137 ) -> Self::T {
138 match self {
139 mir::StatementKind::Assign(assign) => crate::mir::StatementKind::Assign(
140 assign.0.stable(tables, cx),
141 assign.1.stable(tables, cx),
142 ),
143 mir::StatementKind::FakeRead(fake_read_place) => crate::mir::StatementKind::FakeRead(
144 fake_read_place.0.stable(tables, cx),
145 fake_read_place.1.stable(tables, cx),
146 ),
147 mir::StatementKind::SetDiscriminant { place, variant_index } => {
148 crate::mir::StatementKind::SetDiscriminant {
149 place: place.as_ref().stable(tables, cx),
150 variant_index: variant_index.stable(tables, cx),
151 }
152 }
153 mir::StatementKind::Deinit(place) => {
154 crate::mir::StatementKind::Deinit(place.stable(tables, cx))
155 }
156
157 mir::StatementKind::StorageLive(place) => {
158 crate::mir::StatementKind::StorageLive(place.stable(tables, cx))
159 }
160
161 mir::StatementKind::StorageDead(place) => {
162 crate::mir::StatementKind::StorageDead(place.stable(tables, cx))
163 }
164 mir::StatementKind::Retag(retag, place) => {
165 crate::mir::StatementKind::Retag(retag.stable(tables, cx), place.stable(tables, cx))
166 }
167 mir::StatementKind::PlaceMention(place) => {
168 crate::mir::StatementKind::PlaceMention(place.stable(tables, cx))
169 }
170 mir::StatementKind::AscribeUserType(place_projection, variance) => {
171 crate::mir::StatementKind::AscribeUserType {
172 place: place_projection.as_ref().0.stable(tables, cx),
173 projections: place_projection.as_ref().1.stable(tables, cx),
174 variance: variance.stable(tables, cx),
175 }
176 }
177 mir::StatementKind::Coverage(coverage) => {
178 crate::mir::StatementKind::Coverage(opaque(coverage))
179 }
180 mir::StatementKind::Intrinsic(intrinstic) => {
181 crate::mir::StatementKind::Intrinsic(intrinstic.stable(tables, cx))
182 }
183 mir::StatementKind::ConstEvalCounter => crate::mir::StatementKind::ConstEvalCounter,
184 mir::StatementKind::BackwardIncompatibleDropHint { .. } => {
186 crate::mir::StatementKind::Nop
187 }
188 mir::StatementKind::Nop => crate::mir::StatementKind::Nop,
189 }
190 }
191}
192
193impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
194 type T = crate::mir::Rvalue;
195 fn stable<'cx>(
196 &self,
197 tables: &mut Tables<'cx, BridgeTys>,
198 cx: &SmirCtxt<'cx, BridgeTys>,
199 ) -> Self::T {
200 use rustc_middle::mir::Rvalue::*;
201 match self {
202 Use(op) => crate::mir::Rvalue::Use(op.stable(tables, cx)),
203 Repeat(op, len) => {
204 let len = len.stable(tables, cx);
205 crate::mir::Rvalue::Repeat(op.stable(tables, cx), len)
206 }
207 Ref(region, kind, place) => crate::mir::Rvalue::Ref(
208 region.stable(tables, cx),
209 kind.stable(tables, cx),
210 place.stable(tables, cx),
211 ),
212 ThreadLocalRef(def_id) => {
213 crate::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
214 }
215 RawPtr(mutability, place) => crate::mir::Rvalue::AddressOf(
216 mutability.stable(tables, cx),
217 place.stable(tables, cx),
218 ),
219 Len(place) => crate::mir::Rvalue::Len(place.stable(tables, cx)),
220 Cast(cast_kind, op, ty) => crate::mir::Rvalue::Cast(
221 cast_kind.stable(tables, cx),
222 op.stable(tables, cx),
223 ty.stable(tables, cx),
224 ),
225 BinaryOp(bin_op, ops) => {
226 if let Some(bin_op) = bin_op.overflowing_to_wrapping() {
227 crate::mir::Rvalue::CheckedBinaryOp(
228 bin_op.stable(tables, cx),
229 ops.0.stable(tables, cx),
230 ops.1.stable(tables, cx),
231 )
232 } else {
233 crate::mir::Rvalue::BinaryOp(
234 bin_op.stable(tables, cx),
235 ops.0.stable(tables, cx),
236 ops.1.stable(tables, cx),
237 )
238 }
239 }
240 NullaryOp(null_op, ty) => {
241 crate::mir::Rvalue::NullaryOp(null_op.stable(tables, cx), ty.stable(tables, cx))
242 }
243 UnaryOp(un_op, op) => {
244 crate::mir::Rvalue::UnaryOp(un_op.stable(tables, cx), op.stable(tables, cx))
245 }
246 Discriminant(place) => crate::mir::Rvalue::Discriminant(place.stable(tables, cx)),
247 Aggregate(agg_kind, operands) => {
248 let operands = operands.iter().map(|op| op.stable(tables, cx)).collect();
249 crate::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands)
250 }
251 ShallowInitBox(op, ty) => {
252 crate::mir::Rvalue::ShallowInitBox(op.stable(tables, cx), ty.stable(tables, cx))
253 }
254 CopyForDeref(place) => crate::mir::Rvalue::CopyForDeref(place.stable(tables, cx)),
255 WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
256 }
257 }
258}
259
260impl<'tcx> Stable<'tcx> for mir::Mutability {
261 type T = crate::mir::Mutability;
262 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
263 use rustc_hir::Mutability::*;
264 match *self {
265 Not => crate::mir::Mutability::Not,
266 Mut => crate::mir::Mutability::Mut,
267 }
268 }
269}
270
271impl<'tcx> Stable<'tcx> for mir::RawPtrKind {
272 type T = crate::mir::RawPtrKind;
273 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
274 use mir::RawPtrKind::*;
275 match *self {
276 Const => crate::mir::RawPtrKind::Const,
277 Mut => crate::mir::RawPtrKind::Mut,
278 FakeForPtrMetadata => crate::mir::RawPtrKind::FakeForPtrMetadata,
279 }
280 }
281}
282
283impl<'tcx> Stable<'tcx> for mir::BorrowKind {
284 type T = crate::mir::BorrowKind;
285 fn stable<'cx>(
286 &self,
287 tables: &mut Tables<'cx, BridgeTys>,
288 cx: &SmirCtxt<'cx, BridgeTys>,
289 ) -> Self::T {
290 use rustc_middle::mir::BorrowKind::*;
291 match *self {
292 Shared => crate::mir::BorrowKind::Shared,
293 Fake(kind) => crate::mir::BorrowKind::Fake(kind.stable(tables, cx)),
294 Mut { kind } => crate::mir::BorrowKind::Mut { kind: kind.stable(tables, cx) },
295 }
296 }
297}
298
299impl<'tcx> Stable<'tcx> for mir::MutBorrowKind {
300 type T = crate::mir::MutBorrowKind;
301 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
302 use rustc_middle::mir::MutBorrowKind::*;
303 match *self {
304 Default => crate::mir::MutBorrowKind::Default,
305 TwoPhaseBorrow => crate::mir::MutBorrowKind::TwoPhaseBorrow,
306 ClosureCapture => crate::mir::MutBorrowKind::ClosureCapture,
307 }
308 }
309}
310
311impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind {
312 type T = crate::mir::FakeBorrowKind;
313 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
314 use rustc_middle::mir::FakeBorrowKind::*;
315 match *self {
316 Deep => crate::mir::FakeBorrowKind::Deep,
317 Shallow => crate::mir::FakeBorrowKind::Shallow,
318 }
319 }
320}
321
322impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
323 type T = crate::mir::NullOp;
324 fn stable<'cx>(
325 &self,
326 tables: &mut Tables<'cx, BridgeTys>,
327 cx: &SmirCtxt<'cx, BridgeTys>,
328 ) -> Self::T {
329 use rustc_middle::mir::NullOp::*;
330 match self {
331 SizeOf => crate::mir::NullOp::SizeOf,
332 AlignOf => crate::mir::NullOp::AlignOf,
333 OffsetOf(indices) => crate::mir::NullOp::OffsetOf(
334 indices.iter().map(|idx| idx.stable(tables, cx)).collect(),
335 ),
336 UbChecks => crate::mir::NullOp::UbChecks,
337 ContractChecks => crate::mir::NullOp::ContractChecks,
338 }
339 }
340}
341
342impl<'tcx> Stable<'tcx> for mir::CastKind {
343 type T = crate::mir::CastKind;
344 fn stable<'cx>(
345 &self,
346 tables: &mut Tables<'cx, BridgeTys>,
347 cx: &SmirCtxt<'cx, BridgeTys>,
348 ) -> Self::T {
349 use rustc_middle::mir::CastKind::*;
350 match self {
351 PointerExposeProvenance => crate::mir::CastKind::PointerExposeAddress,
352 PointerWithExposedProvenance => crate::mir::CastKind::PointerWithExposedProvenance,
353 PointerCoercion(c, _) => crate::mir::CastKind::PointerCoercion(c.stable(tables, cx)),
354 IntToInt => crate::mir::CastKind::IntToInt,
355 FloatToInt => crate::mir::CastKind::FloatToInt,
356 FloatToFloat => crate::mir::CastKind::FloatToFloat,
357 IntToFloat => crate::mir::CastKind::IntToFloat,
358 PtrToPtr => crate::mir::CastKind::PtrToPtr,
359 FnPtrToPtr => crate::mir::CastKind::FnPtrToPtr,
360 Transmute => crate::mir::CastKind::Transmute,
361 }
362 }
363}
364
365impl<'tcx> Stable<'tcx> for mir::FakeReadCause {
366 type T = crate::mir::FakeReadCause;
367 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
368 use rustc_middle::mir::FakeReadCause::*;
369 match self {
370 ForMatchGuard => crate::mir::FakeReadCause::ForMatchGuard,
371 ForMatchedPlace(local_def_id) => {
372 crate::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id))
373 }
374 ForGuardBinding => crate::mir::FakeReadCause::ForGuardBinding,
375 ForLet(local_def_id) => crate::mir::FakeReadCause::ForLet(opaque(local_def_id)),
376 ForIndex => crate::mir::FakeReadCause::ForIndex,
377 }
378 }
379}
380
381impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> {
382 type T = crate::mir::Operand;
383 fn stable<'cx>(
384 &self,
385 tables: &mut Tables<'cx, BridgeTys>,
386 cx: &SmirCtxt<'cx, BridgeTys>,
387 ) -> Self::T {
388 use rustc_middle::mir::Operand::*;
389 match self {
390 Copy(place) => crate::mir::Operand::Copy(place.stable(tables, cx)),
391 Move(place) => crate::mir::Operand::Move(place.stable(tables, cx)),
392 Constant(c) => crate::mir::Operand::Constant(c.stable(tables, cx)),
393 }
394 }
395}
396
397impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> {
398 type T = crate::mir::ConstOperand;
399
400 fn stable<'cx>(
401 &self,
402 tables: &mut Tables<'cx, BridgeTys>,
403 cx: &SmirCtxt<'cx, BridgeTys>,
404 ) -> Self::T {
405 crate::mir::ConstOperand {
406 span: self.span.stable(tables, cx),
407 user_ty: self.user_ty.map(|u| u.as_usize()).or(None),
408 const_: self.const_.stable(tables, cx),
409 }
410 }
411}
412
413impl<'tcx> Stable<'tcx> for mir::Place<'tcx> {
414 type T = crate::mir::Place;
415 fn stable<'cx>(
416 &self,
417 tables: &mut Tables<'cx, BridgeTys>,
418 cx: &SmirCtxt<'cx, BridgeTys>,
419 ) -> Self::T {
420 crate::mir::Place {
421 local: self.local.as_usize(),
422 projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(),
423 }
424 }
425}
426
427impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> {
428 type T = crate::mir::ProjectionElem;
429 fn stable<'cx>(
430 &self,
431 tables: &mut Tables<'cx, BridgeTys>,
432 cx: &SmirCtxt<'cx, BridgeTys>,
433 ) -> Self::T {
434 use rustc_middle::mir::ProjectionElem::*;
435 match self {
436 Deref => crate::mir::ProjectionElem::Deref,
437 Field(idx, ty) => {
438 crate::mir::ProjectionElem::Field(idx.stable(tables, cx), ty.stable(tables, cx))
439 }
440 Index(local) => crate::mir::ProjectionElem::Index(local.stable(tables, cx)),
441 ConstantIndex { offset, min_length, from_end } => {
442 crate::mir::ProjectionElem::ConstantIndex {
443 offset: *offset,
444 min_length: *min_length,
445 from_end: *from_end,
446 }
447 }
448 Subslice { from, to, from_end } => {
449 crate::mir::ProjectionElem::Subslice { from: *from, to: *to, from_end: *from_end }
450 }
451 Downcast(_, idx) => crate::mir::ProjectionElem::Downcast(idx.stable(tables, cx)),
457 OpaqueCast(ty) => crate::mir::ProjectionElem::OpaqueCast(ty.stable(tables, cx)),
458 Subtype(ty) => crate::mir::ProjectionElem::Subtype(ty.stable(tables, cx)),
459 UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"),
460 }
461 }
462}
463
464impl<'tcx> Stable<'tcx> for mir::UserTypeProjection {
465 type T = crate::mir::UserTypeProjection;
466
467 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
468 UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) }
469 }
470}
471
472impl<'tcx> Stable<'tcx> for mir::Local {
473 type T = crate::mir::Local;
474 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
475 self.as_usize()
476 }
477}
478
479impl<'tcx> Stable<'tcx> for mir::RetagKind {
480 type T = crate::mir::RetagKind;
481 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
482 use rustc_middle::mir::RetagKind;
483 match self {
484 RetagKind::FnEntry => crate::mir::RetagKind::FnEntry,
485 RetagKind::TwoPhase => crate::mir::RetagKind::TwoPhase,
486 RetagKind::Raw => crate::mir::RetagKind::Raw,
487 RetagKind::Default => crate::mir::RetagKind::Default,
488 }
489 }
490}
491
492impl<'tcx> Stable<'tcx> for mir::UnwindAction {
493 type T = crate::mir::UnwindAction;
494 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
495 use rustc_middle::mir::UnwindAction;
496 match self {
497 UnwindAction::Continue => crate::mir::UnwindAction::Continue,
498 UnwindAction::Unreachable => crate::mir::UnwindAction::Unreachable,
499 UnwindAction::Terminate(_) => crate::mir::UnwindAction::Terminate,
500 UnwindAction::Cleanup(bb) => crate::mir::UnwindAction::Cleanup(bb.as_usize()),
501 }
502 }
503}
504
505impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> {
506 type T = crate::mir::NonDivergingIntrinsic;
507
508 fn stable<'cx>(
509 &self,
510 tables: &mut Tables<'cx, BridgeTys>,
511 cx: &SmirCtxt<'cx, BridgeTys>,
512 ) -> Self::T {
513 use rustc_middle::mir::NonDivergingIntrinsic;
514
515 use crate::mir::CopyNonOverlapping;
516 match self {
517 NonDivergingIntrinsic::Assume(op) => {
518 crate::mir::NonDivergingIntrinsic::Assume(op.stable(tables, cx))
519 }
520 NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => {
521 crate::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
522 src: copy_non_overlapping.src.stable(tables, cx),
523 dst: copy_non_overlapping.dst.stable(tables, cx),
524 count: copy_non_overlapping.count.stable(tables, cx),
525 })
526 }
527 }
528 }
529}
530
531impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> {
532 type T = crate::mir::AssertMessage;
533 fn stable<'cx>(
534 &self,
535 tables: &mut Tables<'cx, BridgeTys>,
536 cx: &SmirCtxt<'cx, BridgeTys>,
537 ) -> Self::T {
538 use rustc_middle::mir::AssertKind;
539 match self {
540 AssertKind::BoundsCheck { len, index } => crate::mir::AssertMessage::BoundsCheck {
541 len: len.stable(tables, cx),
542 index: index.stable(tables, cx),
543 },
544 AssertKind::Overflow(bin_op, op1, op2) => crate::mir::AssertMessage::Overflow(
545 bin_op.stable(tables, cx),
546 op1.stable(tables, cx),
547 op2.stable(tables, cx),
548 ),
549 AssertKind::OverflowNeg(op) => {
550 crate::mir::AssertMessage::OverflowNeg(op.stable(tables, cx))
551 }
552 AssertKind::DivisionByZero(op) => {
553 crate::mir::AssertMessage::DivisionByZero(op.stable(tables, cx))
554 }
555 AssertKind::RemainderByZero(op) => {
556 crate::mir::AssertMessage::RemainderByZero(op.stable(tables, cx))
557 }
558 AssertKind::ResumedAfterReturn(coroutine) => {
559 crate::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables, cx))
560 }
561 AssertKind::ResumedAfterPanic(coroutine) => {
562 crate::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables, cx))
563 }
564 AssertKind::ResumedAfterDrop(coroutine) => {
565 crate::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables, cx))
566 }
567 AssertKind::MisalignedPointerDereference { required, found } => {
568 crate::mir::AssertMessage::MisalignedPointerDereference {
569 required: required.stable(tables, cx),
570 found: found.stable(tables, cx),
571 }
572 }
573 AssertKind::NullPointerDereference => crate::mir::AssertMessage::NullPointerDereference,
574 AssertKind::InvalidEnumConstruction(source) => {
575 crate::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables, cx))
576 }
577 }
578 }
579}
580
581impl<'tcx> Stable<'tcx> for mir::BinOp {
582 type T = crate::mir::BinOp;
583 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
584 use rustc_middle::mir::BinOp;
585 match self {
586 BinOp::Add => crate::mir::BinOp::Add,
587 BinOp::AddUnchecked => crate::mir::BinOp::AddUnchecked,
588 BinOp::AddWithOverflow => bug!("AddWithOverflow should have been translated already"),
589 BinOp::Sub => crate::mir::BinOp::Sub,
590 BinOp::SubUnchecked => crate::mir::BinOp::SubUnchecked,
591 BinOp::SubWithOverflow => bug!("AddWithOverflow should have been translated already"),
592 BinOp::Mul => crate::mir::BinOp::Mul,
593 BinOp::MulUnchecked => crate::mir::BinOp::MulUnchecked,
594 BinOp::MulWithOverflow => bug!("AddWithOverflow should have been translated already"),
595 BinOp::Div => crate::mir::BinOp::Div,
596 BinOp::Rem => crate::mir::BinOp::Rem,
597 BinOp::BitXor => crate::mir::BinOp::BitXor,
598 BinOp::BitAnd => crate::mir::BinOp::BitAnd,
599 BinOp::BitOr => crate::mir::BinOp::BitOr,
600 BinOp::Shl => crate::mir::BinOp::Shl,
601 BinOp::ShlUnchecked => crate::mir::BinOp::ShlUnchecked,
602 BinOp::Shr => crate::mir::BinOp::Shr,
603 BinOp::ShrUnchecked => crate::mir::BinOp::ShrUnchecked,
604 BinOp::Eq => crate::mir::BinOp::Eq,
605 BinOp::Lt => crate::mir::BinOp::Lt,
606 BinOp::Le => crate::mir::BinOp::Le,
607 BinOp::Ne => crate::mir::BinOp::Ne,
608 BinOp::Ge => crate::mir::BinOp::Ge,
609 BinOp::Gt => crate::mir::BinOp::Gt,
610 BinOp::Cmp => crate::mir::BinOp::Cmp,
611 BinOp::Offset => crate::mir::BinOp::Offset,
612 }
613 }
614}
615
616impl<'tcx> Stable<'tcx> for mir::UnOp {
617 type T = crate::mir::UnOp;
618 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
619 use rustc_middle::mir::UnOp;
620 match self {
621 UnOp::Not => crate::mir::UnOp::Not,
622 UnOp::Neg => crate::mir::UnOp::Neg,
623 UnOp::PtrMetadata => crate::mir::UnOp::PtrMetadata,
624 }
625 }
626}
627
628impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
629 type T = crate::mir::AggregateKind;
630 fn stable<'cx>(
631 &self,
632 tables: &mut Tables<'cx, BridgeTys>,
633 cx: &SmirCtxt<'cx, BridgeTys>,
634 ) -> Self::T {
635 match self {
636 mir::AggregateKind::Array(ty) => {
637 crate::mir::AggregateKind::Array(ty.stable(tables, cx))
638 }
639 mir::AggregateKind::Tuple => crate::mir::AggregateKind::Tuple,
640 mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
641 crate::mir::AggregateKind::Adt(
642 tables.adt_def(*def_id),
643 var_idx.stable(tables, cx),
644 generic_arg.stable(tables, cx),
645 user_ty_index.map(|idx| idx.index()),
646 field_idx.map(|idx| idx.index()),
647 )
648 }
649 mir::AggregateKind::Closure(def_id, generic_arg) => crate::mir::AggregateKind::Closure(
650 tables.closure_def(*def_id),
651 generic_arg.stable(tables, cx),
652 ),
653 mir::AggregateKind::Coroutine(def_id, generic_arg) => {
654 crate::mir::AggregateKind::Coroutine(
655 tables.coroutine_def(*def_id),
656 generic_arg.stable(tables, cx),
657 cx.coroutine_movability(*def_id).stable(tables, cx),
658 )
659 }
660 mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
661 crate::mir::AggregateKind::CoroutineClosure(
662 tables.coroutine_closure_def(*def_id),
663 generic_args.stable(tables, cx),
664 )
665 }
666 mir::AggregateKind::RawPtr(ty, mutability) => crate::mir::AggregateKind::RawPtr(
667 ty.stable(tables, cx),
668 mutability.stable(tables, cx),
669 ),
670 }
671 }
672}
673
674impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> {
675 type T = crate::mir::InlineAsmOperand;
676 fn stable<'cx>(
677 &self,
678 tables: &mut Tables<'cx, BridgeTys>,
679 cx: &SmirCtxt<'cx, BridgeTys>,
680 ) -> Self::T {
681 use rustc_middle::mir::InlineAsmOperand;
682
683 let (in_value, out_place) = match self {
684 InlineAsmOperand::In { value, .. } => (Some(value.stable(tables, cx)), None),
685 InlineAsmOperand::Out { place, .. } => {
686 (None, place.map(|place| place.stable(tables, cx)))
687 }
688 InlineAsmOperand::InOut { in_value, out_place, .. } => {
689 (Some(in_value.stable(tables, cx)), out_place.map(|place| place.stable(tables, cx)))
690 }
691 InlineAsmOperand::Const { .. }
692 | InlineAsmOperand::SymFn { .. }
693 | InlineAsmOperand::SymStatic { .. }
694 | InlineAsmOperand::Label { .. } => (None, None),
695 };
696
697 crate::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") }
698 }
699}
700
701impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> {
702 type T = crate::mir::Terminator;
703 fn stable<'cx>(
704 &self,
705 tables: &mut Tables<'cx, BridgeTys>,
706 cx: &SmirCtxt<'cx, BridgeTys>,
707 ) -> Self::T {
708 use crate::mir::Terminator;
709 Terminator {
710 kind: self.kind.stable(tables, cx),
711 span: self.source_info.span.stable(tables, cx),
712 }
713 }
714}
715
716impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
717 type T = crate::mir::TerminatorKind;
718 fn stable<'cx>(
719 &self,
720 tables: &mut Tables<'cx, BridgeTys>,
721 cx: &SmirCtxt<'cx, BridgeTys>,
722 ) -> Self::T {
723 use crate::mir::TerminatorKind;
724 match self {
725 mir::TerminatorKind::Goto { target } => {
726 TerminatorKind::Goto { target: target.as_usize() }
727 }
728 mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt {
729 discr: discr.stable(tables, cx),
730 targets: {
731 let branches = targets.iter().map(|(val, target)| (val, target.as_usize()));
732 crate::mir::SwitchTargets::new(
733 branches.collect(),
734 targets.otherwise().as_usize(),
735 )
736 },
737 },
738 mir::TerminatorKind::UnwindResume => TerminatorKind::Resume,
739 mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort,
740 mir::TerminatorKind::Return => TerminatorKind::Return,
741 mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable,
742 mir::TerminatorKind::Drop {
743 place,
744 target,
745 unwind,
746 replace: _,
747 drop: _,
748 async_fut: _,
749 } => TerminatorKind::Drop {
750 place: place.stable(tables, cx),
751 target: target.as_usize(),
752 unwind: unwind.stable(tables, cx),
753 },
754 mir::TerminatorKind::Call {
755 func,
756 args,
757 destination,
758 target,
759 unwind,
760 call_source: _,
761 fn_span: _,
762 } => TerminatorKind::Call {
763 func: func.stable(tables, cx),
764 args: args.iter().map(|arg| arg.node.stable(tables, cx)).collect(),
765 destination: destination.stable(tables, cx),
766 target: target.map(|t| t.as_usize()),
767 unwind: unwind.stable(tables, cx),
768 },
769 mir::TerminatorKind::TailCall { func: _, args: _, fn_span: _ } => todo!(),
770 mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => {
771 TerminatorKind::Assert {
772 cond: cond.stable(tables, cx),
773 expected: *expected,
774 msg: msg.stable(tables, cx),
775 target: target.as_usize(),
776 unwind: unwind.stable(tables, cx),
777 }
778 }
779 mir::TerminatorKind::InlineAsm {
780 asm_macro: _,
781 template,
782 operands,
783 options,
784 line_spans,
785 targets,
786 unwind,
787 } => TerminatorKind::InlineAsm {
788 template: format!("{template:?}"),
789 operands: operands.iter().map(|operand| operand.stable(tables, cx)).collect(),
790 options: format!("{options:?}"),
791 line_spans: format!("{line_spans:?}"),
792 destination: targets.first().map(|d| d.as_usize()),
794 unwind: unwind.stable(tables, cx),
795 },
796 mir::TerminatorKind::Yield { .. }
797 | mir::TerminatorKind::CoroutineDrop
798 | mir::TerminatorKind::FalseEdge { .. }
799 | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(),
800 }
801 }
802}
803
804impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> {
805 type T = Allocation;
806
807 fn stable<'cx>(
808 &self,
809 tables: &mut Tables<'cx, BridgeTys>,
810 cx: &SmirCtxt<'cx, BridgeTys>,
811 ) -> Self::T {
812 self.inner().stable(tables, cx)
813 }
814}
815
816impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
817 type T = crate::ty::Allocation;
818
819 fn stable<'cx>(
820 &self,
821 tables: &mut Tables<'cx, BridgeTys>,
822 cx: &SmirCtxt<'cx, BridgeTys>,
823 ) -> Self::T {
824 use rustc_smir::context::SmirAllocRange;
825 alloc::allocation_filter(
826 self,
827 cx.alloc_range(rustc_abi::Size::ZERO, self.size()),
828 tables,
829 cx,
830 )
831 }
832}
833
834impl<'tcx> Stable<'tcx> for mir::interpret::AllocId {
835 type T = crate::mir::alloc::AllocId;
836 fn stable<'cx>(
837 &self,
838 tables: &mut Tables<'cx, BridgeTys>,
839 _: &SmirCtxt<'cx, BridgeTys>,
840 ) -> Self::T {
841 tables.create_alloc_id(*self)
842 }
843}
844
845impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> {
846 type T = GlobalAlloc;
847
848 fn stable<'cx>(
849 &self,
850 tables: &mut Tables<'cx, BridgeTys>,
851 cx: &SmirCtxt<'cx, BridgeTys>,
852 ) -> Self::T {
853 match self {
854 mir::interpret::GlobalAlloc::Function { instance, .. } => {
855 GlobalAlloc::Function(instance.stable(tables, cx))
856 }
857 mir::interpret::GlobalAlloc::VTable(ty, dyn_ty) => {
858 GlobalAlloc::VTable(ty.stable(tables, cx), dyn_ty.principal().stable(tables, cx))
860 }
861 mir::interpret::GlobalAlloc::Static(def) => {
862 GlobalAlloc::Static(tables.static_def(*def))
863 }
864 mir::interpret::GlobalAlloc::Memory(alloc) => {
865 GlobalAlloc::Memory(alloc.stable(tables, cx))
866 }
867 }
868 }
869}
870
871impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> {
872 type T = crate::ty::MirConst;
873
874 fn stable<'cx>(
875 &self,
876 tables: &mut Tables<'cx, BridgeTys>,
877 cx: &SmirCtxt<'cx, BridgeTys>,
878 ) -> Self::T {
879 let id = tables.intern_mir_const(cx.lift(*self).unwrap());
880 match *self {
881 mir::Const::Ty(ty, c) => MirConst::new(
882 crate::ty::ConstantKind::Ty(c.stable(tables, cx)),
883 ty.stable(tables, cx),
884 id,
885 ),
886 mir::Const::Unevaluated(unev_const, ty) => {
887 let kind = crate::ty::ConstantKind::Unevaluated(crate::ty::UnevaluatedConst {
888 def: tables.const_def(unev_const.def),
889 args: unev_const.args.stable(tables, cx),
890 promoted: unev_const.promoted.map(|u| u.as_u32()),
891 });
892 let ty = ty.stable(tables, cx);
893 MirConst::new(kind, ty, id)
894 }
895 mir::Const::Val(mir::ConstValue::ZeroSized, ty) => {
896 let ty = ty.stable(tables, cx);
897 MirConst::new(ConstantKind::ZeroSized, ty, id)
898 }
899 mir::Const::Val(val, ty) => {
900 let ty = cx.lift(ty).unwrap();
901 let val = cx.lift(val).unwrap();
902 let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables, cx));
903 let ty = ty.stable(tables, cx);
904 MirConst::new(kind, ty, id)
905 }
906 }
907 }
908}
909
910impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled {
911 type T = Error;
912
913 fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T {
914 Error::new(format!("{self:?}"))
915 }
916}
917
918impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
919 type T = crate::mir::mono::MonoItem;
920
921 fn stable<'cx>(
922 &self,
923 tables: &mut Tables<'cx, BridgeTys>,
924 cx: &SmirCtxt<'cx, BridgeTys>,
925 ) -> Self::T {
926 use crate::mir::mono::MonoItem as StableMonoItem;
927 match self {
928 MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables, cx)),
929 MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
930 MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
931 }
932 }
933}