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