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