Skip to main content

rustc_public/unstable/convert/stable/
mir.rs

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