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