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