rustc_smir/rustc_smir/convert/
ty.rs

1//! Conversion of internal Rust compiler `ty` items to stable ones.
2
3use rustc_middle::ty::Ty;
4use rustc_middle::{mir, ty};
5use stable_mir::ty::{
6    AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy,
7};
8
9use crate::rustc_smir::{Stable, Tables, alloc};
10use crate::stable_mir;
11
12impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
13    type T = stable_mir::ty::AliasKind;
14    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
15        match self {
16            ty::Projection => stable_mir::ty::AliasKind::Projection,
17            ty::Inherent => stable_mir::ty::AliasKind::Inherent,
18            ty::Opaque => stable_mir::ty::AliasKind::Opaque,
19            ty::Free => stable_mir::ty::AliasKind::Free,
20        }
21    }
22}
23
24impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> {
25    type T = stable_mir::ty::AliasTy;
26    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
27        let ty::AliasTy { args, def_id, .. } = self;
28        stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) }
29    }
30}
31
32impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> {
33    type T = stable_mir::ty::AliasTerm;
34    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
35        let ty::AliasTerm { args, def_id, .. } = self;
36        stable_mir::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables) }
37    }
38}
39
40impl<'tcx> Stable<'tcx> for ty::DynKind {
41    type T = stable_mir::ty::DynKind;
42
43    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
44        match self {
45            ty::Dyn => stable_mir::ty::DynKind::Dyn,
46            ty::DynStar => stable_mir::ty::DynKind::DynStar,
47        }
48    }
49}
50
51impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> {
52    type T = stable_mir::ty::ExistentialPredicate;
53
54    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
55        use stable_mir::ty::ExistentialPredicate::*;
56        match self {
57            ty::ExistentialPredicate::Trait(existential_trait_ref) => {
58                Trait(existential_trait_ref.stable(tables))
59            }
60            ty::ExistentialPredicate::Projection(existential_projection) => {
61                Projection(existential_projection.stable(tables))
62            }
63            ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)),
64        }
65    }
66}
67
68impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> {
69    type T = stable_mir::ty::ExistentialTraitRef;
70
71    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
72        let ty::ExistentialTraitRef { def_id, args, .. } = self;
73        stable_mir::ty::ExistentialTraitRef {
74            def_id: tables.trait_def(*def_id),
75            generic_args: args.stable(tables),
76        }
77    }
78}
79
80impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> {
81    type T = stable_mir::ty::TermKind;
82
83    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
84        use stable_mir::ty::TermKind;
85        match self {
86            ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)),
87            ty::TermKind::Const(cnst) => {
88                let cnst = cnst.stable(tables);
89                TermKind::Const(cnst)
90            }
91        }
92    }
93}
94
95impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> {
96    type T = stable_mir::ty::ExistentialProjection;
97
98    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
99        let ty::ExistentialProjection { def_id, args, term, .. } = self;
100        stable_mir::ty::ExistentialProjection {
101            def_id: tables.trait_def(*def_id),
102            generic_args: args.stable(tables),
103            term: term.kind().stable(tables),
104        }
105    }
106}
107
108impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion {
109    type T = stable_mir::mir::PointerCoercion;
110    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
111        use rustc_middle::ty::adjustment::PointerCoercion;
112        match self {
113            PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer,
114            PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer,
115            PointerCoercion::ClosureFnPointer(safety) => {
116                stable_mir::mir::PointerCoercion::ClosureFnPointer(safety.stable(tables))
117            }
118            PointerCoercion::MutToConstPointer => {
119                stable_mir::mir::PointerCoercion::MutToConstPointer
120            }
121            PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
122            PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
123            PointerCoercion::DynStar => unreachable!("represented as `CastKind::DynStar` in smir"),
124        }
125    }
126}
127
128impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex {
129    type T = usize;
130    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
131        self.as_usize()
132    }
133}
134
135impl<'tcx> Stable<'tcx> for ty::AdtKind {
136    type T = AdtKind;
137
138    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
139        match self {
140            ty::AdtKind::Struct => AdtKind::Struct,
141            ty::AdtKind::Union => AdtKind::Union,
142            ty::AdtKind::Enum => AdtKind::Enum,
143        }
144    }
145}
146
147impl<'tcx> Stable<'tcx> for ty::FieldDef {
148    type T = stable_mir::ty::FieldDef;
149
150    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
151        stable_mir::ty::FieldDef {
152            def: tables.create_def_id(self.did),
153            name: self.name.stable(tables),
154        }
155    }
156}
157
158impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
159    type T = stable_mir::ty::GenericArgs;
160    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
161        GenericArgs(self.iter().map(|arg| arg.kind().stable(tables)).collect())
162    }
163}
164
165impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> {
166    type T = stable_mir::ty::GenericArgKind;
167
168    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
169        use stable_mir::ty::GenericArgKind;
170        match self {
171            ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)),
172            ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)),
173            ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)),
174        }
175    }
176}
177
178impl<'tcx, S, V> Stable<'tcx> for ty::Binder<'tcx, S>
179where
180    S: Stable<'tcx, T = V>,
181{
182    type T = stable_mir::ty::Binder<V>;
183
184    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
185        use stable_mir::ty::Binder;
186
187        Binder {
188            value: self.as_ref().skip_binder().stable(tables),
189            bound_vars: self
190                .bound_vars()
191                .iter()
192                .map(|bound_var| bound_var.stable(tables))
193                .collect(),
194        }
195    }
196}
197
198impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder<'tcx, S>
199where
200    S: Stable<'tcx, T = V>,
201{
202    type T = stable_mir::ty::EarlyBinder<V>;
203
204    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
205        use stable_mir::ty::EarlyBinder;
206
207        EarlyBinder { value: self.as_ref().skip_binder().stable(tables) }
208    }
209}
210
211impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
212    type T = stable_mir::ty::FnSig;
213    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
214        use stable_mir::ty::FnSig;
215
216        FnSig {
217            inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(),
218            c_variadic: self.c_variadic,
219            safety: self.safety.stable(tables),
220            abi: self.abi.stable(tables),
221        }
222    }
223}
224
225impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
226    type T = stable_mir::ty::BoundTyKind;
227
228    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
229        use stable_mir::ty::BoundTyKind;
230
231        match self {
232            ty::BoundTyKind::Anon => BoundTyKind::Anon,
233            ty::BoundTyKind::Param(def_id, symbol) => {
234                BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
235            }
236        }
237    }
238}
239
240impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
241    type T = stable_mir::ty::BoundRegionKind;
242
243    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
244        use stable_mir::ty::BoundRegionKind;
245
246        match self {
247            ty::BoundRegionKind::Anon => BoundRegionKind::BrAnon,
248            ty::BoundRegionKind::Named(def_id, symbol) => {
249                BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
250            }
251            ty::BoundRegionKind::ClosureEnv => BoundRegionKind::BrEnv,
252        }
253    }
254}
255
256impl<'tcx> Stable<'tcx> for ty::BoundVariableKind {
257    type T = stable_mir::ty::BoundVariableKind;
258
259    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
260        use stable_mir::ty::BoundVariableKind;
261
262        match self {
263            ty::BoundVariableKind::Ty(bound_ty_kind) => {
264                BoundVariableKind::Ty(bound_ty_kind.stable(tables))
265            }
266            ty::BoundVariableKind::Region(bound_region_kind) => {
267                BoundVariableKind::Region(bound_region_kind.stable(tables))
268            }
269            ty::BoundVariableKind::Const => BoundVariableKind::Const,
270        }
271    }
272}
273
274impl<'tcx> Stable<'tcx> for ty::IntTy {
275    type T = IntTy;
276
277    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
278        match self {
279            ty::IntTy::Isize => IntTy::Isize,
280            ty::IntTy::I8 => IntTy::I8,
281            ty::IntTy::I16 => IntTy::I16,
282            ty::IntTy::I32 => IntTy::I32,
283            ty::IntTy::I64 => IntTy::I64,
284            ty::IntTy::I128 => IntTy::I128,
285        }
286    }
287}
288
289impl<'tcx> Stable<'tcx> for ty::UintTy {
290    type T = UintTy;
291
292    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
293        match self {
294            ty::UintTy::Usize => UintTy::Usize,
295            ty::UintTy::U8 => UintTy::U8,
296            ty::UintTy::U16 => UintTy::U16,
297            ty::UintTy::U32 => UintTy::U32,
298            ty::UintTy::U64 => UintTy::U64,
299            ty::UintTy::U128 => UintTy::U128,
300        }
301    }
302}
303
304impl<'tcx> Stable<'tcx> for ty::FloatTy {
305    type T = FloatTy;
306
307    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
308        match self {
309            ty::FloatTy::F16 => FloatTy::F16,
310            ty::FloatTy::F32 => FloatTy::F32,
311            ty::FloatTy::F64 => FloatTy::F64,
312            ty::FloatTy::F128 => FloatTy::F128,
313        }
314    }
315}
316
317impl<'tcx> Stable<'tcx> for Ty<'tcx> {
318    type T = stable_mir::ty::Ty;
319    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
320        tables.intern_ty(tables.tcx.lift(*self).unwrap())
321    }
322}
323
324impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
325    type T = stable_mir::ty::TyKind;
326    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
327        match self {
328            ty::Bool => TyKind::RigidTy(RigidTy::Bool),
329            ty::Char => TyKind::RigidTy(RigidTy::Char),
330            ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))),
331            ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))),
332            ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))),
333            ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt(
334                tables.adt_def(adt_def.did()),
335                generic_args.stable(tables),
336            )),
337            ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
338            ty::Str => TyKind::RigidTy(RigidTy::Str),
339            ty::Array(ty, constant) => {
340                TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables)))
341            }
342            ty::Pat(ty, pat) => {
343                TyKind::RigidTy(RigidTy::Pat(ty.stable(tables), pat.stable(tables)))
344            }
345            ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))),
346            ty::RawPtr(ty, mutbl) => {
347                TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables)))
348            }
349            ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref(
350                region.stable(tables),
351                ty.stable(tables),
352                mutbl.stable(tables),
353            )),
354            ty::FnDef(def_id, generic_args) => {
355                TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
356            }
357            ty::FnPtr(sig_tys, hdr) => {
358                TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables)))
359            }
360            // FIXME(unsafe_binders):
361            ty::UnsafeBinder(_) => todo!(),
362            ty::Dynamic(existential_predicates, region, dyn_kind) => {
363                TyKind::RigidTy(RigidTy::Dynamic(
364                    existential_predicates
365                        .iter()
366                        .map(|existential_predicate| existential_predicate.stable(tables))
367                        .collect(),
368                    region.stable(tables),
369                    dyn_kind.stable(tables),
370                ))
371            }
372            ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
373                tables.closure_def(*def_id),
374                generic_args.stable(tables),
375            )),
376            ty::CoroutineClosure(..) => todo!("FIXME(async_closures): Lower these to SMIR"),
377            ty::Coroutine(def_id, generic_args) => TyKind::RigidTy(RigidTy::Coroutine(
378                tables.coroutine_def(*def_id),
379                generic_args.stable(tables),
380                tables.tcx.coroutine_movability(*def_id).stable(tables),
381            )),
382            ty::Never => TyKind::RigidTy(RigidTy::Never),
383            ty::Tuple(fields) => {
384                TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect()))
385            }
386            ty::Alias(alias_kind, alias_ty) => {
387                TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables))
388            }
389            ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)),
390            ty::Bound(debruijn_idx, bound_ty) => {
391                TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
392            }
393            ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness(
394                tables.coroutine_witness_def(*def_id),
395                args.stable(tables),
396            )),
397            ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => {
398                unreachable!();
399            }
400        }
401    }
402}
403
404impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
405    type T = stable_mir::ty::Pattern;
406
407    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
408        match **self {
409            ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range {
410                // FIXME(SMIR): update data structures to not have an Option here anymore
411                start: Some(start.stable(tables)),
412                end: Some(end.stable(tables)),
413                include_end: true,
414            },
415            ty::PatternKind::Or(_) => todo!(),
416        }
417    }
418}
419
420impl<'tcx> Stable<'tcx> for ty::Const<'tcx> {
421    type T = stable_mir::ty::TyConst;
422
423    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
424        let ct = tables.tcx.lift(*self).unwrap();
425        let kind = match ct.kind() {
426            ty::ConstKind::Value(cv) => {
427                let const_val = tables.tcx.valtree_to_const_val(cv);
428                if matches!(const_val, mir::ConstValue::ZeroSized) {
429                    stable_mir::ty::TyConstKind::ZSTValue(cv.ty.stable(tables))
430                } else {
431                    stable_mir::ty::TyConstKind::Value(
432                        cv.ty.stable(tables),
433                        alloc::new_allocation(cv.ty, const_val, tables),
434                    )
435                }
436            }
437            ty::ConstKind::Param(param) => stable_mir::ty::TyConstKind::Param(param.stable(tables)),
438            ty::ConstKind::Unevaluated(uv) => stable_mir::ty::TyConstKind::Unevaluated(
439                tables.const_def(uv.def),
440                uv.args.stable(tables),
441            ),
442            ty::ConstKind::Error(_) => unreachable!(),
443            ty::ConstKind::Infer(_) => unreachable!(),
444            ty::ConstKind::Bound(_, _) => unimplemented!(),
445            ty::ConstKind::Placeholder(_) => unimplemented!(),
446            ty::ConstKind::Expr(_) => unimplemented!(),
447        };
448        let id = tables.intern_ty_const(ct);
449        stable_mir::ty::TyConst::new(kind, id)
450    }
451}
452
453impl<'tcx> Stable<'tcx> for ty::ParamConst {
454    type T = stable_mir::ty::ParamConst;
455    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
456        use stable_mir::ty::ParamConst;
457        ParamConst { index: self.index, name: self.name.to_string() }
458    }
459}
460
461impl<'tcx> Stable<'tcx> for ty::ParamTy {
462    type T = stable_mir::ty::ParamTy;
463    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
464        use stable_mir::ty::ParamTy;
465        ParamTy { index: self.index, name: self.name.to_string() }
466    }
467}
468
469impl<'tcx> Stable<'tcx> for ty::BoundTy {
470    type T = stable_mir::ty::BoundTy;
471    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
472        use stable_mir::ty::BoundTy;
473        BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
474    }
475}
476
477impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind {
478    type T = stable_mir::ty::TraitSpecializationKind;
479    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
480        use stable_mir::ty::TraitSpecializationKind;
481
482        match self {
483            ty::trait_def::TraitSpecializationKind::None => TraitSpecializationKind::None,
484            ty::trait_def::TraitSpecializationKind::Marker => TraitSpecializationKind::Marker,
485            ty::trait_def::TraitSpecializationKind::AlwaysApplicable => {
486                TraitSpecializationKind::AlwaysApplicable
487            }
488        }
489    }
490}
491
492impl<'tcx> Stable<'tcx> for ty::TraitDef {
493    type T = stable_mir::ty::TraitDecl;
494    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
495        use stable_mir::opaque;
496        use stable_mir::ty::TraitDecl;
497
498        TraitDecl {
499            def_id: tables.trait_def(self.def_id),
500            safety: self.safety.stable(tables),
501            paren_sugar: self.paren_sugar,
502            has_auto_impl: self.has_auto_impl,
503            is_marker: self.is_marker,
504            is_coinductive: self.is_coinductive,
505            skip_array_during_method_dispatch: self.skip_array_during_method_dispatch,
506            skip_boxed_slice_during_method_dispatch: self.skip_boxed_slice_during_method_dispatch,
507            specialization_kind: self.specialization_kind.stable(tables),
508            must_implement_one_of: self
509                .must_implement_one_of
510                .as_ref()
511                .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()),
512            implement_via_object: self.implement_via_object,
513            deny_explicit_impl: self.deny_explicit_impl,
514        }
515    }
516}
517
518impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
519    type T = stable_mir::ty::TraitRef;
520    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
521        use stable_mir::ty::TraitRef;
522
523        TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap()
524    }
525}
526
527impl<'tcx> Stable<'tcx> for ty::Generics {
528    type T = stable_mir::ty::Generics;
529
530    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
531        use stable_mir::ty::Generics;
532
533        let params: Vec<_> = self.own_params.iter().map(|param| param.stable(tables)).collect();
534        let param_def_id_to_index =
535            params.iter().map(|param| (param.def_id, param.index)).collect();
536
537        Generics {
538            parent: self.parent.map(|did| tables.generic_def(did)),
539            parent_count: self.parent_count,
540            params,
541            param_def_id_to_index,
542            has_self: self.has_self,
543            has_late_bound_regions: self
544                .has_late_bound_regions
545                .as_ref()
546                .map(|late_bound_regions| late_bound_regions.stable(tables)),
547        }
548    }
549}
550
551impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind {
552    type T = stable_mir::ty::GenericParamDefKind;
553
554    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
555        use stable_mir::ty::GenericParamDefKind;
556        match self {
557            ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime,
558            ty::GenericParamDefKind::Type { has_default, synthetic } => {
559                GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic }
560            }
561            ty::GenericParamDefKind::Const { has_default, synthetic: _ } => {
562                GenericParamDefKind::Const { has_default: *has_default }
563            }
564        }
565    }
566}
567
568impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef {
569    type T = stable_mir::ty::GenericParamDef;
570
571    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
572        GenericParamDef {
573            name: self.name.to_string(),
574            def_id: tables.generic_def(self.def_id),
575            index: self.index,
576            pure_wrt_drop: self.pure_wrt_drop,
577            kind: self.kind.stable(tables),
578        }
579    }
580}
581
582impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> {
583    type T = stable_mir::ty::PredicateKind;
584
585    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
586        use rustc_middle::ty::PredicateKind;
587        match self {
588            PredicateKind::Clause(clause_kind) => {
589                stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables))
590            }
591            PredicateKind::DynCompatible(did) => {
592                stable_mir::ty::PredicateKind::DynCompatible(tables.trait_def(*did))
593            }
594            PredicateKind::Subtype(subtype_predicate) => {
595                stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables))
596            }
597            PredicateKind::Coerce(coerce_predicate) => {
598                stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables))
599            }
600            PredicateKind::ConstEquate(a, b) => {
601                stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables))
602            }
603            PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous,
604            PredicateKind::NormalizesTo(_pred) => unimplemented!(),
605            PredicateKind::AliasRelate(a, b, alias_relation_direction) => {
606                stable_mir::ty::PredicateKind::AliasRelate(
607                    a.kind().stable(tables),
608                    b.kind().stable(tables),
609                    alias_relation_direction.stable(tables),
610                )
611            }
612        }
613    }
614}
615
616impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
617    type T = stable_mir::ty::ClauseKind;
618
619    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
620        use rustc_middle::ty::ClauseKind;
621        match *self {
622            ClauseKind::Trait(trait_object) => {
623                stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables))
624            }
625            ClauseKind::RegionOutlives(region_outlives) => {
626                stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables))
627            }
628            ClauseKind::TypeOutlives(type_outlives) => {
629                let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives;
630                stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate(
631                    a.stable(tables),
632                    b.stable(tables),
633                ))
634            }
635            ClauseKind::Projection(projection_predicate) => {
636                stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables))
637            }
638            ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType(
639                const_.stable(tables),
640                ty.stable(tables),
641            ),
642            ClauseKind::WellFormed(term) => {
643                stable_mir::ty::ClauseKind::WellFormed(term.kind().stable(tables))
644            }
645            ClauseKind::ConstEvaluatable(const_) => {
646                stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
647            }
648            ClauseKind::HostEffect(..) => {
649                todo!()
650            }
651        }
652    }
653}
654
655impl<'tcx> Stable<'tcx> for ty::ClosureKind {
656    type T = stable_mir::ty::ClosureKind;
657
658    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
659        use rustc_middle::ty::ClosureKind::*;
660        match self {
661            Fn => stable_mir::ty::ClosureKind::Fn,
662            FnMut => stable_mir::ty::ClosureKind::FnMut,
663            FnOnce => stable_mir::ty::ClosureKind::FnOnce,
664        }
665    }
666}
667
668impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> {
669    type T = stable_mir::ty::SubtypePredicate;
670
671    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
672        let ty::SubtypePredicate { a, b, a_is_expected: _ } = self;
673        stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) }
674    }
675}
676
677impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> {
678    type T = stable_mir::ty::CoercePredicate;
679
680    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
681        let ty::CoercePredicate { a, b } = self;
682        stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) }
683    }
684}
685
686impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection {
687    type T = stable_mir::ty::AliasRelationDirection;
688
689    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
690        use rustc_middle::ty::AliasRelationDirection::*;
691        match self {
692            Equate => stable_mir::ty::AliasRelationDirection::Equate,
693            Subtype => stable_mir::ty::AliasRelationDirection::Subtype,
694        }
695    }
696}
697
698impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> {
699    type T = stable_mir::ty::TraitPredicate;
700
701    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
702        let ty::TraitPredicate { trait_ref, polarity } = self;
703        stable_mir::ty::TraitPredicate {
704            trait_ref: trait_ref.stable(tables),
705            polarity: polarity.stable(tables),
706        }
707    }
708}
709
710impl<'tcx, T> Stable<'tcx> for ty::OutlivesPredicate<'tcx, T>
711where
712    T: Stable<'tcx>,
713{
714    type T = stable_mir::ty::OutlivesPredicate<T::T, Region>;
715
716    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
717        let ty::OutlivesPredicate(a, b) = self;
718        stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables))
719    }
720}
721
722impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> {
723    type T = stable_mir::ty::ProjectionPredicate;
724
725    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
726        let ty::ProjectionPredicate { projection_term, term } = self;
727        stable_mir::ty::ProjectionPredicate {
728            projection_term: projection_term.stable(tables),
729            term: term.kind().stable(tables),
730        }
731    }
732}
733
734impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
735    type T = stable_mir::ty::ImplPolarity;
736
737    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
738        use rustc_middle::ty::ImplPolarity::*;
739        match self {
740            Positive => stable_mir::ty::ImplPolarity::Positive,
741            Negative => stable_mir::ty::ImplPolarity::Negative,
742            Reservation => stable_mir::ty::ImplPolarity::Reservation,
743        }
744    }
745}
746
747impl<'tcx> Stable<'tcx> for ty::PredicatePolarity {
748    type T = stable_mir::ty::PredicatePolarity;
749
750    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
751        use rustc_middle::ty::PredicatePolarity::*;
752        match self {
753            Positive => stable_mir::ty::PredicatePolarity::Positive,
754            Negative => stable_mir::ty::PredicatePolarity::Negative,
755        }
756    }
757}
758
759impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
760    type T = stable_mir::ty::Region;
761
762    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
763        Region { kind: self.kind().stable(tables) }
764    }
765}
766
767impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
768    type T = stable_mir::ty::RegionKind;
769
770    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
771        use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind};
772        match self {
773            ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion {
774                index: early_reg.index,
775                name: early_reg.name.to_string(),
776            }),
777            ty::ReBound(db_index, bound_reg) => RegionKind::ReBound(
778                db_index.as_u32(),
779                BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
780            ),
781            ty::ReStatic => RegionKind::ReStatic,
782            ty::RePlaceholder(place_holder) => {
783                RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
784                    universe: place_holder.universe.as_u32(),
785                    bound: BoundRegion {
786                        var: place_holder.bound.var.as_u32(),
787                        kind: place_holder.bound.kind.stable(tables),
788                    },
789                })
790            }
791            ty::ReErased => RegionKind::ReErased,
792            _ => unreachable!("{self:?}"),
793        }
794    }
795}
796
797impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
798    type T = stable_mir::mir::mono::Instance;
799
800    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
801        let def = tables.instance_def(tables.tcx.lift(*self).unwrap());
802        let kind = match self.def {
803            ty::InstanceKind::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
804            ty::InstanceKind::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
805            ty::InstanceKind::Virtual(_def_id, idx) => {
806                stable_mir::mir::mono::InstanceKind::Virtual { idx }
807            }
808            ty::InstanceKind::VTableShim(..)
809            | ty::InstanceKind::ReifyShim(..)
810            | ty::InstanceKind::FnPtrAddrShim(..)
811            | ty::InstanceKind::ClosureOnceShim { .. }
812            | ty::InstanceKind::ConstructCoroutineInClosureShim { .. }
813            | ty::InstanceKind::ThreadLocalShim(..)
814            | ty::InstanceKind::DropGlue(..)
815            | ty::InstanceKind::CloneShim(..)
816            | ty::InstanceKind::FnPtrShim(..)
817            | ty::InstanceKind::FutureDropPollShim(..)
818            | ty::InstanceKind::AsyncDropGlue(..)
819            | ty::InstanceKind::AsyncDropGlueCtorShim(..) => {
820                stable_mir::mir::mono::InstanceKind::Shim
821            }
822        };
823        stable_mir::mir::mono::Instance { def, kind }
824    }
825}
826
827impl<'tcx> Stable<'tcx> for ty::Variance {
828    type T = stable_mir::mir::Variance;
829    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
830        match self {
831            ty::Bivariant => stable_mir::mir::Variance::Bivariant,
832            ty::Contravariant => stable_mir::mir::Variance::Contravariant,
833            ty::Covariant => stable_mir::mir::Variance::Covariant,
834            ty::Invariant => stable_mir::mir::Variance::Invariant,
835        }
836    }
837}
838
839impl<'tcx> Stable<'tcx> for ty::Movability {
840    type T = stable_mir::ty::Movability;
841
842    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
843        match self {
844            ty::Movability::Static => stable_mir::ty::Movability::Static,
845            ty::Movability::Movable => stable_mir::ty::Movability::Movable,
846        }
847    }
848}
849
850impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
851    type T = stable_mir::ty::Abi;
852
853    fn stable(&self, _: &mut Tables<'_>) -> Self::T {
854        use rustc_abi::ExternAbi;
855        use stable_mir::ty::Abi;
856        match *self {
857            ExternAbi::Rust => Abi::Rust,
858            ExternAbi::C { unwind } => Abi::C { unwind },
859            ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
860            ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
861            ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
862            ExternAbi::Vectorcall { unwind } => Abi::Vectorcall { unwind },
863            ExternAbi::Thiscall { unwind } => Abi::Thiscall { unwind },
864            ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
865            ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
866            ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
867            ExternAbi::PtxKernel => Abi::PtxKernel,
868            ExternAbi::GpuKernel => Abi::GpuKernel,
869            ExternAbi::Msp430Interrupt => Abi::Msp430Interrupt,
870            ExternAbi::X86Interrupt => Abi::X86Interrupt,
871            ExternAbi::EfiApi => Abi::EfiApi,
872            ExternAbi::AvrInterrupt => Abi::AvrInterrupt,
873            ExternAbi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt,
874            ExternAbi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
875            ExternAbi::CCmseNonSecureEntry => Abi::CCmseNonSecureEntry,
876            ExternAbi::System { unwind } => Abi::System { unwind },
877            ExternAbi::RustCall => Abi::RustCall,
878            ExternAbi::Unadjusted => Abi::Unadjusted,
879            ExternAbi::RustCold => Abi::RustCold,
880            ExternAbi::RiscvInterruptM => Abi::RiscvInterruptM,
881            ExternAbi::RiscvInterruptS => Abi::RiscvInterruptS,
882        }
883    }
884}
885
886impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
887    type T = stable_mir::ty::ForeignModule;
888
889    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
890        stable_mir::ty::ForeignModule {
891            def_id: tables.foreign_module_def(self.def_id),
892            abi: self.abi.stable(tables),
893        }
894    }
895}
896
897impl<'tcx> Stable<'tcx> for ty::AssocKind {
898    type T = stable_mir::ty::AssocKind;
899
900    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
901        use stable_mir::ty::{AssocKind, AssocTypeData};
902        match *self {
903            ty::AssocKind::Const { name } => AssocKind::Const { name: name.to_string() },
904            ty::AssocKind::Fn { name, has_self } => {
905                AssocKind::Fn { name: name.to_string(), has_self }
906            }
907            ty::AssocKind::Type { data } => AssocKind::Type {
908                data: match data {
909                    ty::AssocTypeData::Normal(name) => AssocTypeData::Normal(name.to_string()),
910                    ty::AssocTypeData::Rpitit(rpitit) => {
911                        AssocTypeData::Rpitit(rpitit.stable(tables))
912                    }
913                },
914            },
915        }
916    }
917}
918
919impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
920    type T = stable_mir::ty::AssocItemContainer;
921
922    fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
923        use stable_mir::ty::AssocItemContainer;
924        match self {
925            ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
926            ty::AssocItemContainer::Impl => AssocItemContainer::Impl,
927        }
928    }
929}
930
931impl<'tcx> Stable<'tcx> for ty::AssocItem {
932    type T = stable_mir::ty::AssocItem;
933
934    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
935        stable_mir::ty::AssocItem {
936            def_id: tables.assoc_def(self.def_id),
937            kind: self.kind.stable(tables),
938            container: self.container.stable(tables),
939            trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
940        }
941    }
942}
943
944impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
945    type T = stable_mir::ty::ImplTraitInTraitData;
946
947    fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
948        use stable_mir::ty::ImplTraitInTraitData;
949        match self {
950            ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
951                ImplTraitInTraitData::Trait {
952                    fn_def_id: tables.fn_def(*fn_def_id),
953                    opaque_def_id: tables.opaque_def(*opaque_def_id),
954                }
955            }
956            ty::ImplTraitInTraitData::Impl { fn_def_id } => {
957                ImplTraitInTraitData::Impl { fn_def_id: tables.fn_def(*fn_def_id) }
958            }
959        }
960    }
961}