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