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