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