rustc_smir/rustc_internal/
internal.rs

1//! Module containing the translation from stable mir constructs to the rustc counterpart.
2//!
3//! This module will only include a few constructs to allow users to invoke internal rustc APIs
4//! due to incomplete stable coverage.
5
6// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
7
8use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt};
9use rustc_span::Symbol;
10use stable_mir::abi::Layout;
11use stable_mir::mir::alloc::AllocId;
12use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
13use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp};
14use stable_mir::ty::{
15    Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind,
16    ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
17    GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy,
18    Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
19};
20use stable_mir::{CrateItem, CrateNum, DefId};
21
22use super::RustcInternal;
23use crate::rustc_smir::Tables;
24
25impl RustcInternal for CrateItem {
26    type T<'tcx> = rustc_span::def_id::DefId;
27    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
28        self.0.internal(tables, tcx)
29    }
30}
31
32impl RustcInternal for CrateNum {
33    type T<'tcx> = rustc_span::def_id::CrateNum;
34    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
35        rustc_span::def_id::CrateNum::from_usize(*self)
36    }
37}
38
39impl RustcInternal for DefId {
40    type T<'tcx> = rustc_span::def_id::DefId;
41    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
42        tcx.lift(tables.def_ids[*self]).unwrap()
43    }
44}
45
46impl RustcInternal for GenericArgs {
47    type T<'tcx> = rustc_ty::GenericArgsRef<'tcx>;
48    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
49        tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx)))
50    }
51}
52
53impl RustcInternal for GenericArgKind {
54    type T<'tcx> = rustc_ty::GenericArg<'tcx>;
55    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
56        let arg: rustc_ty::GenericArg<'tcx> = match self {
57            GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(),
58            GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(),
59            GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(),
60        };
61        tcx.lift(arg).unwrap()
62    }
63}
64
65impl RustcInternal for Region {
66    type T<'tcx> = rustc_ty::Region<'tcx>;
67    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
68        // Cannot recover region. Use erased for now.
69        tcx.lifetimes.re_erased
70    }
71}
72
73impl RustcInternal for Ty {
74    type T<'tcx> = InternalTy<'tcx>;
75    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
76        tcx.lift(tables.types[*self]).unwrap()
77    }
78}
79
80impl RustcInternal for TyConst {
81    type T<'tcx> = InternalConst<'tcx>;
82    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
83        tcx.lift(tables.ty_consts[self.id]).unwrap()
84    }
85}
86
87impl RustcInternal for Pattern {
88    type T<'tcx> = rustc_ty::Pattern<'tcx>;
89    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
90        tcx.mk_pat(match self {
91            Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
92                start: start.as_ref().map(|c| c.internal(tables, tcx)),
93                end: end.as_ref().map(|c| c.internal(tables, tcx)),
94                include_end: *include_end,
95            },
96        })
97    }
98}
99
100impl RustcInternal for RigidTy {
101    type T<'tcx> = rustc_ty::TyKind<'tcx>;
102
103    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
104        match self {
105            RigidTy::Bool => rustc_ty::TyKind::Bool,
106            RigidTy::Char => rustc_ty::TyKind::Char,
107            RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)),
108            RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)),
109            RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)),
110            RigidTy::Never => rustc_ty::TyKind::Never,
111            RigidTy::Array(ty, cnst) => {
112                rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx))
113            }
114            RigidTy::Pat(ty, pat) => {
115                rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx))
116            }
117            RigidTy::Adt(def, args) => {
118                rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx))
119            }
120            RigidTy::Str => rustc_ty::TyKind::Str,
121            RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)),
122            RigidTy::RawPtr(ty, mutability) => {
123                rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx))
124            }
125            RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref(
126                region.internal(tables, tcx),
127                ty.internal(tables, tcx),
128                mutability.internal(tables, tcx),
129            ),
130            RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)),
131            RigidTy::FnDef(def, args) => {
132                rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx))
133            }
134            RigidTy::FnPtr(sig) => {
135                let (sig_tys, hdr) = sig.internal(tables, tcx).split();
136                rustc_ty::TyKind::FnPtr(sig_tys, hdr)
137            }
138            RigidTy::Closure(def, args) => {
139                rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx))
140            }
141            RigidTy::Coroutine(def, args, _mov) => {
142                rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
143            }
144            RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure(
145                def.0.internal(tables, tcx),
146                args.internal(tables, tcx),
147            ),
148            RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness(
149                def.0.internal(tables, tcx),
150                args.internal(tables, tcx),
151            ),
152            RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic(
153                tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)),
154                region.internal(tables, tcx),
155                dyn_kind.internal(tables, tcx),
156            ),
157            RigidTy::Tuple(tys) => {
158                rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx)))
159            }
160        }
161    }
162}
163
164impl RustcInternal for IntTy {
165    type T<'tcx> = rustc_ty::IntTy;
166
167    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
168        match self {
169            IntTy::Isize => rustc_ty::IntTy::Isize,
170            IntTy::I8 => rustc_ty::IntTy::I8,
171            IntTy::I16 => rustc_ty::IntTy::I16,
172            IntTy::I32 => rustc_ty::IntTy::I32,
173            IntTy::I64 => rustc_ty::IntTy::I64,
174            IntTy::I128 => rustc_ty::IntTy::I128,
175        }
176    }
177}
178
179impl RustcInternal for UintTy {
180    type T<'tcx> = rustc_ty::UintTy;
181
182    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
183        match self {
184            UintTy::Usize => rustc_ty::UintTy::Usize,
185            UintTy::U8 => rustc_ty::UintTy::U8,
186            UintTy::U16 => rustc_ty::UintTy::U16,
187            UintTy::U32 => rustc_ty::UintTy::U32,
188            UintTy::U64 => rustc_ty::UintTy::U64,
189            UintTy::U128 => rustc_ty::UintTy::U128,
190        }
191    }
192}
193
194impl RustcInternal for FloatTy {
195    type T<'tcx> = rustc_ty::FloatTy;
196
197    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
198        match self {
199            FloatTy::F16 => rustc_ty::FloatTy::F16,
200            FloatTy::F32 => rustc_ty::FloatTy::F32,
201            FloatTy::F64 => rustc_ty::FloatTy::F64,
202            FloatTy::F128 => rustc_ty::FloatTy::F128,
203        }
204    }
205}
206
207impl RustcInternal for Mutability {
208    type T<'tcx> = rustc_ty::Mutability;
209
210    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
211        match self {
212            Mutability::Not => rustc_ty::Mutability::Not,
213            Mutability::Mut => rustc_ty::Mutability::Mut,
214        }
215    }
216}
217
218impl RustcInternal for Movability {
219    type T<'tcx> = rustc_ty::Movability;
220
221    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
222        match self {
223            Movability::Static => rustc_ty::Movability::Static,
224            Movability::Movable => rustc_ty::Movability::Movable,
225        }
226    }
227}
228
229impl RustcInternal for RawPtrKind {
230    type T<'tcx> = rustc_middle::mir::RawPtrKind;
231
232    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
233        match self {
234            RawPtrKind::Mut => rustc_middle::mir::RawPtrKind::Mut,
235            RawPtrKind::Const => rustc_middle::mir::RawPtrKind::Const,
236            RawPtrKind::FakeForPtrMetadata => rustc_middle::mir::RawPtrKind::FakeForPtrMetadata,
237        }
238    }
239}
240
241impl RustcInternal for FnSig {
242    type T<'tcx> = rustc_ty::FnSig<'tcx>;
243
244    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
245        tcx.lift(rustc_ty::FnSig {
246            inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)),
247            c_variadic: self.c_variadic,
248            safety: self.safety.internal(tables, tcx),
249            abi: self.abi.internal(tables, tcx),
250        })
251        .unwrap()
252    }
253}
254
255impl RustcInternal for VariantIdx {
256    type T<'tcx> = rustc_abi::VariantIdx;
257
258    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
259        rustc_abi::VariantIdx::from(self.to_index())
260    }
261}
262
263impl RustcInternal for VariantDef {
264    type T<'tcx> = &'tcx rustc_ty::VariantDef;
265
266    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
267        self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx))
268    }
269}
270
271impl RustcInternal for MirConst {
272    type T<'tcx> = rustc_middle::mir::Const<'tcx>;
273    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
274        let constant = tables.mir_consts[self.id];
275        match constant {
276            rustc_middle::mir::Const::Ty(ty, ct) => {
277                rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap())
278            }
279            rustc_middle::mir::Const::Unevaluated(uneval, ty) => {
280                rustc_middle::mir::Const::Unevaluated(
281                    tcx.lift(uneval).unwrap(),
282                    tcx.lift(ty).unwrap(),
283                )
284            }
285            rustc_middle::mir::Const::Val(const_val, ty) => {
286                rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap())
287            }
288        }
289    }
290}
291
292impl RustcInternal for MonoItem {
293    type T<'tcx> = rustc_middle::mir::mono::MonoItem<'tcx>;
294
295    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
296        use rustc_middle::mir::mono as rustc_mono;
297        match self {
298            MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, tcx)),
299            MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, tcx)),
300            MonoItem::GlobalAsm(_) => {
301                unimplemented!()
302            }
303        }
304    }
305}
306
307impl RustcInternal for Instance {
308    type T<'tcx> = rustc_ty::Instance<'tcx>;
309
310    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
311        tcx.lift(tables.instances[self.def]).unwrap()
312    }
313}
314
315impl RustcInternal for StaticDef {
316    type T<'tcx> = rustc_span::def_id::DefId;
317
318    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
319        self.0.internal(tables, tcx)
320    }
321}
322
323#[allow(rustc::usage_of_qualified_ty)]
324impl<T> RustcInternal for Binder<T>
325where
326    T: RustcInternal,
327    for<'tcx> T::T<'tcx>: rustc_ty::TypeVisitable<rustc_ty::TyCtxt<'tcx>>,
328{
329    type T<'tcx> = rustc_ty::Binder<'tcx, T::T<'tcx>>;
330
331    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
332        rustc_ty::Binder::bind_with_vars(
333            self.value.internal(tables, tcx),
334            tcx.mk_bound_variable_kinds_from_iter(
335                self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)),
336            ),
337        )
338    }
339}
340
341impl RustcInternal for BoundVariableKind {
342    type T<'tcx> = rustc_ty::BoundVariableKind;
343
344    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
345        match self {
346            BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
347                BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
348                BoundTyKind::Param(def, symbol) => rustc_ty::BoundTyKind::Param(
349                    def.0.internal(tables, tcx),
350                    Symbol::intern(symbol),
351                ),
352            }),
353            BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind {
354                BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::Anon,
355                BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::Named(
356                    def.0.internal(tables, tcx),
357                    Symbol::intern(symbol),
358                ),
359                BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::ClosureEnv,
360            }),
361            BoundVariableKind::Const => rustc_ty::BoundVariableKind::Const,
362        }
363    }
364}
365
366impl RustcInternal for DynKind {
367    type T<'tcx> = rustc_ty::DynKind;
368
369    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
370        match self {
371            DynKind::Dyn => rustc_ty::DynKind::Dyn,
372            DynKind::DynStar => rustc_ty::DynKind::DynStar,
373        }
374    }
375}
376
377impl RustcInternal for ExistentialPredicate {
378    type T<'tcx> = rustc_ty::ExistentialPredicate<'tcx>;
379
380    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
381        match self {
382            ExistentialPredicate::Trait(trait_ref) => {
383                rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx))
384            }
385            ExistentialPredicate::Projection(proj) => {
386                rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx))
387            }
388            ExistentialPredicate::AutoTrait(trait_def) => {
389                rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx))
390            }
391        }
392    }
393}
394
395impl RustcInternal for ExistentialProjection {
396    type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>;
397
398    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
399        rustc_ty::ExistentialProjection::new_from_args(
400            tcx,
401            self.def_id.0.internal(tables, tcx),
402            self.generic_args.internal(tables, tcx),
403            self.term.internal(tables, tcx),
404        )
405    }
406}
407
408impl RustcInternal for TermKind {
409    type T<'tcx> = rustc_ty::Term<'tcx>;
410
411    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
412        match self {
413            TermKind::Type(ty) => ty.internal(tables, tcx).into(),
414            TermKind::Const(cnst) => cnst.internal(tables, tcx).into(),
415        }
416    }
417}
418
419impl RustcInternal for ExistentialTraitRef {
420    type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>;
421
422    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
423        rustc_ty::ExistentialTraitRef::new_from_args(
424            tcx,
425            self.def_id.0.internal(tables, tcx),
426            self.generic_args.internal(tables, tcx),
427        )
428    }
429}
430
431impl RustcInternal for TraitRef {
432    type T<'tcx> = rustc_ty::TraitRef<'tcx>;
433
434    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
435        rustc_ty::TraitRef::new_from_args(
436            tcx,
437            self.def_id.0.internal(tables, tcx),
438            self.args().internal(tables, tcx),
439        )
440    }
441}
442
443impl RustcInternal for AllocId {
444    type T<'tcx> = rustc_middle::mir::interpret::AllocId;
445    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
446        tcx.lift(tables.alloc_ids[*self]).unwrap()
447    }
448}
449
450impl RustcInternal for ClosureKind {
451    type T<'tcx> = rustc_ty::ClosureKind;
452
453    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
454        match self {
455            ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
456            ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
457            ClosureKind::FnOnce => rustc_ty::ClosureKind::FnOnce,
458        }
459    }
460}
461
462impl RustcInternal for AdtDef {
463    type T<'tcx> = rustc_ty::AdtDef<'tcx>;
464    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
465        tcx.adt_def(self.0.internal(tables, tcx))
466    }
467}
468
469impl RustcInternal for Abi {
470    type T<'tcx> = rustc_abi::ExternAbi;
471
472    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
473        match *self {
474            Abi::Rust => rustc_abi::ExternAbi::Rust,
475            Abi::C { unwind } => rustc_abi::ExternAbi::C { unwind },
476            Abi::Cdecl { unwind } => rustc_abi::ExternAbi::Cdecl { unwind },
477            Abi::Stdcall { unwind } => rustc_abi::ExternAbi::Stdcall { unwind },
478            Abi::Fastcall { unwind } => rustc_abi::ExternAbi::Fastcall { unwind },
479            Abi::Vectorcall { unwind } => rustc_abi::ExternAbi::Vectorcall { unwind },
480            Abi::Thiscall { unwind } => rustc_abi::ExternAbi::Thiscall { unwind },
481            Abi::Aapcs { unwind } => rustc_abi::ExternAbi::Aapcs { unwind },
482            Abi::Win64 { unwind } => rustc_abi::ExternAbi::Win64 { unwind },
483            Abi::SysV64 { unwind } => rustc_abi::ExternAbi::SysV64 { unwind },
484            Abi::PtxKernel => rustc_abi::ExternAbi::PtxKernel,
485            Abi::Msp430Interrupt => rustc_abi::ExternAbi::Msp430Interrupt,
486            Abi::X86Interrupt => rustc_abi::ExternAbi::X86Interrupt,
487            Abi::GpuKernel => rustc_abi::ExternAbi::GpuKernel,
488            Abi::EfiApi => rustc_abi::ExternAbi::EfiApi,
489            Abi::AvrInterrupt => rustc_abi::ExternAbi::AvrInterrupt,
490            Abi::AvrNonBlockingInterrupt => rustc_abi::ExternAbi::AvrNonBlockingInterrupt,
491            Abi::CCmseNonSecureCall => rustc_abi::ExternAbi::CCmseNonSecureCall,
492            Abi::CCmseNonSecureEntry => rustc_abi::ExternAbi::CCmseNonSecureEntry,
493            Abi::System { unwind } => rustc_abi::ExternAbi::System { unwind },
494            Abi::RustIntrinsic => rustc_abi::ExternAbi::RustIntrinsic,
495            Abi::RustCall => rustc_abi::ExternAbi::RustCall,
496            Abi::Unadjusted => rustc_abi::ExternAbi::Unadjusted,
497            Abi::RustCold => rustc_abi::ExternAbi::RustCold,
498            Abi::RiscvInterruptM => rustc_abi::ExternAbi::RiscvInterruptM,
499            Abi::RiscvInterruptS => rustc_abi::ExternAbi::RiscvInterruptS,
500        }
501    }
502}
503
504impl RustcInternal for Safety {
505    type T<'tcx> = rustc_hir::Safety;
506
507    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
508        match self {
509            Safety::Unsafe => rustc_hir::Safety::Unsafe,
510            Safety::Safe => rustc_hir::Safety::Safe,
511        }
512    }
513}
514impl RustcInternal for Span {
515    type T<'tcx> = rustc_span::Span;
516
517    fn internal<'tcx>(&self, tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
518        tables[*self]
519    }
520}
521
522impl RustcInternal for Layout {
523    type T<'tcx> = rustc_abi::Layout<'tcx>;
524
525    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
526        tcx.lift(tables.layouts[*self]).unwrap()
527    }
528}
529
530impl RustcInternal for Place {
531    type T<'tcx> = rustc_middle::mir::Place<'tcx>;
532
533    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
534        rustc_middle::mir::Place {
535            local: rustc_middle::mir::Local::from_usize(self.local),
536            projection: tcx.mk_place_elems(&self.projection.internal(tables, tcx)),
537        }
538    }
539}
540
541impl RustcInternal for ProjectionElem {
542    type T<'tcx> = rustc_middle::mir::PlaceElem<'tcx>;
543
544    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
545        match self {
546            ProjectionElem::Deref => rustc_middle::mir::PlaceElem::Deref,
547            ProjectionElem::Field(idx, ty) => {
548                rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, tcx))
549            }
550            ProjectionElem::Index(idx) => rustc_middle::mir::PlaceElem::Index((*idx).into()),
551            ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
552                rustc_middle::mir::PlaceElem::ConstantIndex {
553                    offset: *offset,
554                    min_length: *min_length,
555                    from_end: *from_end,
556                }
557            }
558            ProjectionElem::Subslice { from, to, from_end } => {
559                rustc_middle::mir::PlaceElem::Subslice { from: *from, to: *to, from_end: *from_end }
560            }
561            ProjectionElem::Downcast(idx) => {
562                rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, tcx))
563            }
564            ProjectionElem::OpaqueCast(ty) => {
565                rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx))
566            }
567            ProjectionElem::Subtype(ty) => {
568                rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx))
569            }
570        }
571    }
572}
573
574impl RustcInternal for BinOp {
575    type T<'tcx> = rustc_middle::mir::BinOp;
576
577    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
578        match self {
579            BinOp::Add => rustc_middle::mir::BinOp::Add,
580            BinOp::AddUnchecked => rustc_middle::mir::BinOp::AddUnchecked,
581            BinOp::Sub => rustc_middle::mir::BinOp::Sub,
582            BinOp::SubUnchecked => rustc_middle::mir::BinOp::SubUnchecked,
583            BinOp::Mul => rustc_middle::mir::BinOp::Mul,
584            BinOp::MulUnchecked => rustc_middle::mir::BinOp::MulUnchecked,
585            BinOp::Div => rustc_middle::mir::BinOp::Div,
586            BinOp::Rem => rustc_middle::mir::BinOp::Rem,
587            BinOp::BitXor => rustc_middle::mir::BinOp::BitXor,
588            BinOp::BitAnd => rustc_middle::mir::BinOp::BitAnd,
589            BinOp::BitOr => rustc_middle::mir::BinOp::BitOr,
590            BinOp::Shl => rustc_middle::mir::BinOp::Shl,
591            BinOp::ShlUnchecked => rustc_middle::mir::BinOp::ShlUnchecked,
592            BinOp::Shr => rustc_middle::mir::BinOp::Shr,
593            BinOp::ShrUnchecked => rustc_middle::mir::BinOp::ShrUnchecked,
594            BinOp::Eq => rustc_middle::mir::BinOp::Eq,
595            BinOp::Lt => rustc_middle::mir::BinOp::Lt,
596            BinOp::Le => rustc_middle::mir::BinOp::Le,
597            BinOp::Ne => rustc_middle::mir::BinOp::Ne,
598            BinOp::Ge => rustc_middle::mir::BinOp::Ge,
599            BinOp::Gt => rustc_middle::mir::BinOp::Gt,
600            BinOp::Cmp => rustc_middle::mir::BinOp::Cmp,
601            BinOp::Offset => rustc_middle::mir::BinOp::Offset,
602        }
603    }
604}
605
606impl RustcInternal for UnOp {
607    type T<'tcx> = rustc_middle::mir::UnOp;
608
609    fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
610        match self {
611            UnOp::Not => rustc_middle::mir::UnOp::Not,
612            UnOp::Neg => rustc_middle::mir::UnOp::Neg,
613            UnOp::PtrMetadata => rustc_middle::mir::UnOp::PtrMetadata,
614        }
615    }
616}
617
618impl<T> RustcInternal for &T
619where
620    T: RustcInternal,
621{
622    type T<'tcx> = T::T<'tcx>;
623
624    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
625        (*self).internal(tables, tcx)
626    }
627}
628
629impl<T> RustcInternal for Option<T>
630where
631    T: RustcInternal,
632{
633    type T<'tcx> = Option<T::T<'tcx>>;
634
635    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
636        self.as_ref().map(|inner| inner.internal(tables, tcx))
637    }
638}
639
640impl<T> RustcInternal for Vec<T>
641where
642    T: RustcInternal,
643{
644    type T<'tcx> = Vec<T::T<'tcx>>;
645
646    fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
647        self.iter().map(|e| e.internal(tables, tcx)).collect()
648    }
649}