rustc_public/unstable/convert/stable/
ty.rs

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