stable_mir/
ty.rs

1use std::fmt::{self, Debug, Display, Formatter};
2use std::ops::Range;
3
4use serde::Serialize;
5
6use super::mir::{Body, Mutability, Safety};
7use super::{DefId, Error, Symbol, with};
8use crate::abi::{FnAbi, Layout};
9use crate::crate_def::{CrateDef, CrateDefType};
10use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
11use crate::mir::mono::StaticDef;
12use crate::target::MachineInfo;
13use crate::{Filename, Opaque};
14
15#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
16pub struct Ty(usize);
17
18impl Debug for Ty {
19    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20        f.debug_struct("Ty").field("id", &self.0).field("kind", &self.kind()).finish()
21    }
22}
23
24/// Constructors for `Ty`.
25impl Ty {
26    /// Create a new type from a given kind.
27    pub fn from_rigid_kind(kind: RigidTy) -> Ty {
28        with(|cx| cx.new_rigid_ty(kind))
29    }
30
31    /// Create a new array type.
32    pub fn try_new_array(elem_ty: Ty, size: u64) -> Result<Ty, Error> {
33        Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?)))
34    }
35
36    /// Create a new array type from Const length.
37    pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty {
38        Ty::from_rigid_kind(RigidTy::Array(elem_ty, len))
39    }
40
41    /// Create a new pointer type.
42    pub fn new_ptr(pointee_ty: Ty, mutability: Mutability) -> Ty {
43        Ty::from_rigid_kind(RigidTy::RawPtr(pointee_ty, mutability))
44    }
45
46    /// Create a new reference type.
47    pub fn new_ref(reg: Region, pointee_ty: Ty, mutability: Mutability) -> Ty {
48        Ty::from_rigid_kind(RigidTy::Ref(reg, pointee_ty, mutability))
49    }
50
51    /// Create a new pointer type.
52    pub fn new_tuple(tys: &[Ty]) -> Ty {
53        Ty::from_rigid_kind(RigidTy::Tuple(Vec::from(tys)))
54    }
55
56    /// Create a new closure type.
57    pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
58        Ty::from_rigid_kind(RigidTy::Closure(def, args))
59    }
60
61    /// Create a new coroutine type.
62    pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
63        Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
64    }
65
66    /// Create a new closure type.
67    pub fn new_coroutine_closure(def: CoroutineClosureDef, args: GenericArgs) -> Ty {
68        Ty::from_rigid_kind(RigidTy::CoroutineClosure(def, args))
69    }
70
71    /// Create a new box type that represents `Box<T>`, for the given inner type `T`.
72    pub fn new_box(inner_ty: Ty) -> Ty {
73        with(|cx| cx.new_box_ty(inner_ty))
74    }
75
76    /// Create a type representing `usize`.
77    pub fn usize_ty() -> Ty {
78        Ty::from_rigid_kind(RigidTy::Uint(UintTy::Usize))
79    }
80
81    /// Create a type representing `bool`.
82    pub fn bool_ty() -> Ty {
83        Ty::from_rigid_kind(RigidTy::Bool)
84    }
85
86    /// Create a type representing a signed integer.
87    pub fn signed_ty(inner: IntTy) -> Ty {
88        Ty::from_rigid_kind(RigidTy::Int(inner))
89    }
90
91    /// Create a type representing an unsigned integer.
92    pub fn unsigned_ty(inner: UintTy) -> Ty {
93        Ty::from_rigid_kind(RigidTy::Uint(inner))
94    }
95
96    /// Get a type layout.
97    pub fn layout(self) -> Result<Layout, Error> {
98        with(|cx| cx.ty_layout(self))
99    }
100}
101
102impl Ty {
103    pub fn kind(&self) -> TyKind {
104        with(|context| context.ty_kind(*self))
105    }
106}
107
108/// Represents a pattern in the type system
109#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
110pub enum Pattern {
111    Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
112}
113
114/// Represents a constant in the type system
115#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
116pub struct TyConst {
117    pub(crate) kind: TyConstKind,
118    pub id: TyConstId,
119}
120
121impl TyConst {
122    pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst {
123        Self { kind, id }
124    }
125
126    /// Retrieve the constant kind.
127    pub fn kind(&self) -> &TyConstKind {
128        &self.kind
129    }
130
131    /// Creates an interned usize constant.
132    pub fn try_from_target_usize(val: u64) -> Result<Self, Error> {
133        with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
134    }
135
136    /// Try to evaluate to a target `usize`.
137    pub fn eval_target_usize(&self) -> Result<u64, Error> {
138        with(|cx| cx.eval_target_usize_ty(self))
139    }
140}
141
142#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
143pub enum TyConstKind {
144    Param(ParamConst),
145    Bound(DebruijnIndex, BoundVar),
146    Unevaluated(ConstDef, GenericArgs),
147
148    // FIXME: These should be a valtree
149    Value(Ty, Allocation),
150    ZSTValue(Ty),
151}
152
153#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
154pub struct TyConstId(usize);
155
156/// Represents a constant in MIR
157#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
158pub struct MirConst {
159    /// The constant kind.
160    pub(crate) kind: ConstantKind,
161    /// The constant type.
162    pub(crate) ty: Ty,
163    /// Used for internal tracking of the internal constant.
164    pub id: MirConstId,
165}
166
167impl MirConst {
168    /// Build a constant. Note that this should only be used by the compiler.
169    pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst {
170        MirConst { kind, ty, id }
171    }
172
173    /// Retrieve the constant kind.
174    pub fn kind(&self) -> &ConstantKind {
175        &self.kind
176    }
177
178    /// Get the constant type.
179    pub fn ty(&self) -> Ty {
180        self.ty
181    }
182
183    /// Try to evaluate to a target `usize`.
184    pub fn eval_target_usize(&self) -> Result<u64, Error> {
185        with(|cx| cx.eval_target_usize(self))
186    }
187
188    /// Create a constant that represents a new zero-sized constant of type T.
189    /// Fails if the type is not a ZST or if it doesn't have a known size.
190    pub fn try_new_zero_sized(ty: Ty) -> Result<MirConst, Error> {
191        with(|cx| cx.try_new_const_zst(ty))
192    }
193
194    /// Build a new constant that represents the given string.
195    ///
196    /// Note that there is no guarantee today about duplication of the same constant.
197    /// I.e.: Calling this function multiple times with the same argument may or may not return
198    /// the same allocation.
199    pub fn from_str(value: &str) -> MirConst {
200        with(|cx| cx.new_const_str(value))
201    }
202
203    /// Build a new constant that represents the given boolean value.
204    pub fn from_bool(value: bool) -> MirConst {
205        with(|cx| cx.new_const_bool(value))
206    }
207
208    /// Build a new constant that represents the given unsigned integer.
209    pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
210        with(|cx| cx.try_new_const_uint(value, uint_ty))
211    }
212}
213
214#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
215pub struct MirConstId(usize);
216
217type Ident = Opaque;
218
219#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
220pub struct Region {
221    pub kind: RegionKind,
222}
223
224#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
225pub enum RegionKind {
226    ReEarlyParam(EarlyParamRegion),
227    ReBound(DebruijnIndex, BoundRegion),
228    ReStatic,
229    RePlaceholder(Placeholder<BoundRegion>),
230    ReErased,
231}
232
233pub(crate) type DebruijnIndex = u32;
234
235#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
236pub struct EarlyParamRegion {
237    pub index: u32,
238    pub name: Symbol,
239}
240
241pub(crate) type BoundVar = u32;
242
243#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
244pub struct BoundRegion {
245    pub var: BoundVar,
246    pub kind: BoundRegionKind,
247}
248
249pub(crate) type UniverseIndex = u32;
250
251#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
252pub struct Placeholder<T> {
253    pub universe: UniverseIndex,
254    pub bound: T,
255}
256
257#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
258pub struct Span(usize);
259
260impl Debug for Span {
261    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
262        f.debug_struct("Span")
263            .field("id", &self.0)
264            .field("repr", &with(|cx| cx.span_to_string(*self)))
265            .finish()
266    }
267}
268
269impl Span {
270    /// Return filename for diagnostic purposes
271    pub fn get_filename(&self) -> Filename {
272        with(|c| c.get_filename(self))
273    }
274
275    /// Return lines that correspond to this `Span`
276    pub fn get_lines(&self) -> LineInfo {
277        with(|c| c.get_lines(self))
278    }
279
280    /// Return the span location to be printed in diagnostic messages.
281    ///
282    /// This may leak local file paths and should not be used to build artifacts that may be
283    /// distributed.
284    pub fn diagnostic(&self) -> String {
285        with(|c| c.span_to_string(*self))
286    }
287}
288
289#[derive(Clone, Copy, Debug, Serialize)]
290/// Information you get from `Span` in a struct form.
291/// Line and col start from 1.
292pub struct LineInfo {
293    pub start_line: usize,
294    pub start_col: usize,
295    pub end_line: usize,
296    pub end_col: usize,
297}
298
299#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
300pub enum TyKind {
301    RigidTy(RigidTy),
302    Alias(AliasKind, AliasTy),
303    Param(ParamTy),
304    Bound(usize, BoundTy),
305}
306
307impl TyKind {
308    pub fn rigid(&self) -> Option<&RigidTy> {
309        if let TyKind::RigidTy(inner) = self { Some(inner) } else { None }
310    }
311
312    #[inline]
313    pub fn is_unit(&self) -> bool {
314        matches!(self, TyKind::RigidTy(RigidTy::Tuple(data)) if data.is_empty())
315    }
316
317    #[inline]
318    pub fn is_bool(&self) -> bool {
319        matches!(self, TyKind::RigidTy(RigidTy::Bool))
320    }
321
322    #[inline]
323    pub fn is_char(&self) -> bool {
324        matches!(self, TyKind::RigidTy(RigidTy::Char))
325    }
326
327    #[inline]
328    pub fn is_trait(&self) -> bool {
329        matches!(self, TyKind::RigidTy(RigidTy::Dynamic(_, _, DynKind::Dyn)))
330    }
331
332    #[inline]
333    pub fn is_enum(&self) -> bool {
334        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Enum)
335    }
336
337    #[inline]
338    pub fn is_struct(&self) -> bool {
339        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Struct)
340    }
341
342    #[inline]
343    pub fn is_union(&self) -> bool {
344        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.kind() == AdtKind::Union)
345    }
346
347    #[inline]
348    pub fn is_adt(&self) -> bool {
349        matches!(self, TyKind::RigidTy(RigidTy::Adt(..)))
350    }
351
352    #[inline]
353    pub fn is_ref(&self) -> bool {
354        matches!(self, TyKind::RigidTy(RigidTy::Ref(..)))
355    }
356
357    #[inline]
358    pub fn is_fn(&self) -> bool {
359        matches!(self, TyKind::RigidTy(RigidTy::FnDef(..)))
360    }
361
362    #[inline]
363    pub fn is_fn_ptr(&self) -> bool {
364        matches!(self, TyKind::RigidTy(RigidTy::FnPtr(..)))
365    }
366
367    #[inline]
368    pub fn is_primitive(&self) -> bool {
369        matches!(
370            self,
371            TyKind::RigidTy(
372                RigidTy::Bool
373                    | RigidTy::Char
374                    | RigidTy::Int(_)
375                    | RigidTy::Uint(_)
376                    | RigidTy::Float(_)
377            )
378        )
379    }
380
381    #[inline]
382    pub fn is_float(&self) -> bool {
383        matches!(self, TyKind::RigidTy(RigidTy::Float(_)))
384    }
385
386    #[inline]
387    pub fn is_integral(&self) -> bool {
388        matches!(self, TyKind::RigidTy(RigidTy::Int(_) | RigidTy::Uint(_)))
389    }
390
391    #[inline]
392    pub fn is_numeric(&self) -> bool {
393        self.is_integral() || self.is_float()
394    }
395
396    #[inline]
397    pub fn is_signed(&self) -> bool {
398        matches!(self, TyKind::RigidTy(RigidTy::Int(_)))
399    }
400
401    #[inline]
402    pub fn is_str(&self) -> bool {
403        *self == TyKind::RigidTy(RigidTy::Str)
404    }
405
406    #[inline]
407    pub fn is_cstr(&self) -> bool {
408        let TyKind::RigidTy(RigidTy::Adt(def, _)) = self else {
409            return false;
410        };
411        with(|cx| cx.adt_is_cstr(*def))
412    }
413
414    #[inline]
415    pub fn is_slice(&self) -> bool {
416        matches!(self, TyKind::RigidTy(RigidTy::Slice(_)))
417    }
418
419    #[inline]
420    pub fn is_array(&self) -> bool {
421        matches!(self, TyKind::RigidTy(RigidTy::Array(..)))
422    }
423
424    #[inline]
425    pub fn is_mutable_ptr(&self) -> bool {
426        matches!(
427            self,
428            TyKind::RigidTy(RigidTy::RawPtr(_, Mutability::Mut))
429                | TyKind::RigidTy(RigidTy::Ref(_, _, Mutability::Mut))
430        )
431    }
432
433    #[inline]
434    pub fn is_raw_ptr(&self) -> bool {
435        matches!(self, TyKind::RigidTy(RigidTy::RawPtr(..)))
436    }
437
438    /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer).
439    #[inline]
440    pub fn is_any_ptr(&self) -> bool {
441        self.is_ref() || self.is_raw_ptr() || self.is_fn_ptr()
442    }
443
444    #[inline]
445    pub fn is_coroutine(&self) -> bool {
446        matches!(self, TyKind::RigidTy(RigidTy::Coroutine(..)))
447    }
448
449    #[inline]
450    pub fn is_closure(&self) -> bool {
451        matches!(self, TyKind::RigidTy(RigidTy::Closure(..)))
452    }
453
454    #[inline]
455    pub fn is_box(&self) -> bool {
456        match self {
457            TyKind::RigidTy(RigidTy::Adt(def, _)) => def.is_box(),
458            _ => false,
459        }
460    }
461
462    #[inline]
463    pub fn is_simd(&self) -> bool {
464        matches!(self, TyKind::RigidTy(RigidTy::Adt(def, _)) if def.is_simd())
465    }
466
467    pub fn trait_principal(&self) -> Option<Binder<ExistentialTraitRef>> {
468        if let TyKind::RigidTy(RigidTy::Dynamic(predicates, _, _)) = self {
469            if let Some(Binder { value: ExistentialPredicate::Trait(trait_ref), bound_vars }) =
470                predicates.first()
471            {
472                Some(Binder { value: trait_ref.clone(), bound_vars: bound_vars.clone() })
473            } else {
474                None
475            }
476        } else {
477            None
478        }
479    }
480
481    /// Returns the type of `ty[i]` for builtin types.
482    pub fn builtin_index(&self) -> Option<Ty> {
483        match self.rigid()? {
484            RigidTy::Array(ty, _) | RigidTy::Slice(ty) => Some(*ty),
485            _ => None,
486        }
487    }
488
489    /// Returns the type and mutability of `*ty` for builtin types.
490    ///
491    /// The parameter `explicit` indicates if this is an *explicit* dereference.
492    /// Some types -- notably raw ptrs -- can only be dereferenced explicitly.
493    pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut> {
494        match self.rigid()? {
495            RigidTy::Adt(def, args) if def.is_box() => {
496                Some(TypeAndMut { ty: *args.0.first()?.ty()?, mutability: Mutability::Not })
497            }
498            RigidTy::Ref(_, ty, mutability) => {
499                Some(TypeAndMut { ty: *ty, mutability: *mutability })
500            }
501            RigidTy::RawPtr(ty, mutability) if explicit => {
502                Some(TypeAndMut { ty: *ty, mutability: *mutability })
503            }
504            _ => None,
505        }
506    }
507
508    /// Get the function signature for function like types (Fn, FnPtr, and Closure)
509    pub fn fn_sig(&self) -> Option<PolyFnSig> {
510        match self {
511            TyKind::RigidTy(RigidTy::FnDef(def, args)) => Some(with(|cx| cx.fn_sig(*def, args))),
512            TyKind::RigidTy(RigidTy::FnPtr(sig)) => Some(sig.clone()),
513            TyKind::RigidTy(RigidTy::Closure(_def, args)) => Some(with(|cx| cx.closure_sig(args))),
514            _ => None,
515        }
516    }
517
518    /// Get the discriminant type for this type.
519    pub fn discriminant_ty(&self) -> Option<Ty> {
520        self.rigid().map(|ty| with(|cx| cx.rigid_ty_discriminant_ty(ty)))
521    }
522
523    /// Deconstruct a function type if this is one.
524    pub fn fn_def(&self) -> Option<(FnDef, &GenericArgs)> {
525        if let TyKind::RigidTy(RigidTy::FnDef(def, args)) = self {
526            Some((*def, args))
527        } else {
528            None
529        }
530    }
531}
532
533pub struct TypeAndMut {
534    pub ty: Ty,
535    pub mutability: Mutability,
536}
537
538#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
539pub enum RigidTy {
540    Bool,
541    Char,
542    Int(IntTy),
543    Uint(UintTy),
544    Float(FloatTy),
545    Adt(AdtDef, GenericArgs),
546    Foreign(ForeignDef),
547    Str,
548    Array(Ty, TyConst),
549    Pat(Ty, Pattern),
550    Slice(Ty),
551    RawPtr(Ty, Mutability),
552    Ref(Region, Ty, Mutability),
553    FnDef(FnDef, GenericArgs),
554    FnPtr(PolyFnSig),
555    Closure(ClosureDef, GenericArgs),
556    // FIXME(stable_mir): Movability here is redundant
557    Coroutine(CoroutineDef, GenericArgs, Movability),
558    CoroutineClosure(CoroutineClosureDef, GenericArgs),
559    Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
560    Never,
561    Tuple(Vec<Ty>),
562    CoroutineWitness(CoroutineWitnessDef, GenericArgs),
563}
564
565impl RigidTy {
566    /// Get the discriminant type for this type.
567    pub fn discriminant_ty(&self) -> Ty {
568        with(|cx| cx.rigid_ty_discriminant_ty(self))
569    }
570}
571
572impl From<RigidTy> for TyKind {
573    fn from(value: RigidTy) -> Self {
574        TyKind::RigidTy(value)
575    }
576}
577
578#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
579pub enum IntTy {
580    Isize,
581    I8,
582    I16,
583    I32,
584    I64,
585    I128,
586}
587
588impl IntTy {
589    pub fn num_bytes(self) -> usize {
590        match self {
591            IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(),
592            IntTy::I8 => 1,
593            IntTy::I16 => 2,
594            IntTy::I32 => 4,
595            IntTy::I64 => 8,
596            IntTy::I128 => 16,
597        }
598    }
599}
600
601#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
602pub enum UintTy {
603    Usize,
604    U8,
605    U16,
606    U32,
607    U64,
608    U128,
609}
610
611impl UintTy {
612    pub fn num_bytes(self) -> usize {
613        match self {
614            UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(),
615            UintTy::U8 => 1,
616            UintTy::U16 => 2,
617            UintTy::U32 => 4,
618            UintTy::U64 => 8,
619            UintTy::U128 => 16,
620        }
621    }
622}
623
624#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
625pub enum FloatTy {
626    F16,
627    F32,
628    F64,
629    F128,
630}
631
632#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
633pub enum Movability {
634    Static,
635    Movable,
636}
637
638crate_def! {
639    #[derive(Serialize)]
640    pub ForeignModuleDef;
641}
642
643impl ForeignModuleDef {
644    pub fn module(&self) -> ForeignModule {
645        with(|cx| cx.foreign_module(*self))
646    }
647}
648
649pub struct ForeignModule {
650    pub def_id: ForeignModuleDef,
651    pub abi: Abi,
652}
653
654impl ForeignModule {
655    pub fn items(&self) -> Vec<ForeignDef> {
656        with(|cx| cx.foreign_items(self.def_id))
657    }
658}
659
660crate_def_with_ty! {
661    /// Hold information about a ForeignItem in a crate.
662    #[derive(Serialize)]
663    pub ForeignDef;
664}
665
666impl ForeignDef {
667    pub fn kind(&self) -> ForeignItemKind {
668        with(|cx| cx.foreign_item_kind(*self))
669    }
670}
671
672#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
673pub enum ForeignItemKind {
674    Fn(FnDef),
675    Static(StaticDef),
676    Type(Ty),
677}
678
679crate_def_with_ty! {
680    /// Hold information about a function definition in a crate.
681    #[derive(Serialize)]
682    pub FnDef;
683}
684
685impl FnDef {
686    // Get the function body if available.
687    pub fn body(&self) -> Option<Body> {
688        with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
689    }
690
691    // Check if the function body is available.
692    pub fn has_body(&self) -> bool {
693        with(|ctx| ctx.has_body(self.0))
694    }
695
696    /// Get the information of the intrinsic if this function is a definition of one.
697    pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
698        with(|cx| cx.intrinsic(self.def_id()))
699    }
700
701    /// Check if the function is an intrinsic.
702    #[inline]
703    pub fn is_intrinsic(&self) -> bool {
704        self.as_intrinsic().is_some()
705    }
706
707    /// Get the function signature for this function definition.
708    pub fn fn_sig(&self) -> PolyFnSig {
709        let kind = self.ty().kind();
710        kind.fn_sig().unwrap()
711    }
712}
713
714crate_def_with_ty! {
715    #[derive(Serialize)]
716    pub IntrinsicDef;
717}
718
719impl IntrinsicDef {
720    /// Returns the plain name of the intrinsic.
721    /// e.g., `transmute` for `core::intrinsics::transmute`.
722    pub fn fn_name(&self) -> Symbol {
723        with(|cx| cx.intrinsic_name(*self))
724    }
725
726    /// Returns whether the intrinsic has no meaningful body and all backends
727    /// need to shim all calls to it.
728    pub fn must_be_overridden(&self) -> bool {
729        with(|cx| !cx.has_body(self.0))
730    }
731}
732
733impl From<IntrinsicDef> for FnDef {
734    fn from(def: IntrinsicDef) -> Self {
735        FnDef(def.0)
736    }
737}
738
739crate_def! {
740    #[derive(Serialize)]
741    pub ClosureDef;
742}
743
744crate_def! {
745    #[derive(Serialize)]
746    pub CoroutineDef;
747}
748
749crate_def! {
750    #[derive(Serialize)]
751    pub CoroutineClosureDef;
752}
753
754crate_def! {
755    #[derive(Serialize)]
756    pub ParamDef;
757}
758
759crate_def! {
760    #[derive(Serialize)]
761    pub BrNamedDef;
762}
763
764crate_def! {
765    #[derive(Serialize)]
766    pub AdtDef;
767}
768
769#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
770pub enum AdtKind {
771    Enum,
772    Union,
773    Struct,
774}
775
776impl AdtDef {
777    pub fn kind(&self) -> AdtKind {
778        with(|cx| cx.adt_kind(*self))
779    }
780
781    /// Retrieve the type of this Adt.
782    pub fn ty(&self) -> Ty {
783        with(|cx| cx.def_ty(self.0))
784    }
785
786    /// Retrieve the type of this Adt by instantiating and normalizing it with the given arguments.
787    ///
788    /// This will assume the type can be instantiated with these arguments.
789    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
790        with(|cx| cx.def_ty_with_args(self.0, args))
791    }
792
793    pub fn is_box(&self) -> bool {
794        with(|cx| cx.adt_is_box(*self))
795    }
796
797    pub fn is_simd(&self) -> bool {
798        with(|cx| cx.adt_is_simd(*self))
799    }
800
801    /// The number of variants in this ADT.
802    pub fn num_variants(&self) -> usize {
803        with(|cx| cx.adt_variants_len(*self))
804    }
805
806    /// Retrieve the variants in this ADT.
807    pub fn variants(&self) -> Vec<VariantDef> {
808        self.variants_iter().collect()
809    }
810
811    /// Iterate over the variants in this ADT.
812    pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> + '_ {
813        (0..self.num_variants())
814            .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
815    }
816
817    pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
818        (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
819    }
820}
821
822/// Definition of a variant, which can be either a struct / union field or an enum variant.
823#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
824pub struct VariantDef {
825    /// The variant index.
826    ///
827    /// ## Warning
828    /// Do not access this field directly!
829    pub idx: VariantIdx,
830    /// The data type where this variant comes from.
831    /// For now, we use this to retrieve information about the variant itself so we don't need to
832    /// cache more information.
833    ///
834    /// ## Warning
835    /// Do not access this field directly!
836    pub adt_def: AdtDef,
837}
838
839impl VariantDef {
840    pub fn name(&self) -> Symbol {
841        with(|cx| cx.variant_name(*self))
842    }
843
844    /// Retrieve all the fields in this variant.
845    // We expect user to cache this and use it directly since today it is expensive to generate all
846    // fields name.
847    pub fn fields(&self) -> Vec<FieldDef> {
848        with(|cx| cx.variant_fields(*self))
849    }
850}
851
852#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
853pub struct FieldDef {
854    /// The field definition.
855    ///
856    /// ## Warning
857    /// Do not access this field directly! This is public for the compiler to have access to it.
858    pub def: DefId,
859
860    /// The field name.
861    pub name: Symbol,
862}
863
864impl FieldDef {
865    /// Retrieve the type of this field instantiating and normalizing it with the given arguments.
866    ///
867    /// This will assume the type can be instantiated with these arguments.
868    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
869        with(|cx| cx.def_ty_with_args(self.def, args))
870    }
871
872    /// Retrieve the type of this field.
873    pub fn ty(&self) -> Ty {
874        with(|cx| cx.def_ty(self.def))
875    }
876}
877
878impl Display for AdtKind {
879    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
880        f.write_str(match self {
881            AdtKind::Enum => "enum",
882            AdtKind::Union => "union",
883            AdtKind::Struct => "struct",
884        })
885    }
886}
887
888impl AdtKind {
889    pub fn is_enum(&self) -> bool {
890        matches!(self, AdtKind::Enum)
891    }
892
893    pub fn is_struct(&self) -> bool {
894        matches!(self, AdtKind::Struct)
895    }
896
897    pub fn is_union(&self) -> bool {
898        matches!(self, AdtKind::Union)
899    }
900}
901
902crate_def! {
903    #[derive(Serialize)]
904    pub AliasDef;
905}
906
907crate_def! {
908    /// A trait's definition.
909    #[derive(Serialize)]
910    pub TraitDef;
911}
912
913impl TraitDef {
914    pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
915        with(|cx| cx.trait_decl(trait_def))
916    }
917}
918
919crate_def! {
920    #[derive(Serialize)]
921    pub GenericDef;
922}
923
924crate_def_with_ty! {
925    #[derive(Serialize)]
926    pub ConstDef;
927}
928
929crate_def! {
930    /// A trait impl definition.
931    #[derive(Serialize)]
932    pub ImplDef;
933}
934
935impl ImplDef {
936    /// Retrieve information about this implementation.
937    pub fn trait_impl(&self) -> ImplTrait {
938        with(|cx| cx.trait_impl(self))
939    }
940}
941
942crate_def! {
943    #[derive(Serialize)]
944    pub RegionDef;
945}
946
947crate_def! {
948    #[derive(Serialize)]
949    pub CoroutineWitnessDef;
950}
951
952/// A list of generic arguments.
953#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
954pub struct GenericArgs(pub Vec<GenericArgKind>);
955
956impl std::ops::Index<ParamTy> for GenericArgs {
957    type Output = Ty;
958
959    fn index(&self, index: ParamTy) -> &Self::Output {
960        self.0[index.index as usize].expect_ty()
961    }
962}
963
964impl std::ops::Index<ParamConst> for GenericArgs {
965    type Output = TyConst;
966
967    fn index(&self, index: ParamConst) -> &Self::Output {
968        self.0[index.index as usize].expect_const()
969    }
970}
971
972#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
973pub enum GenericArgKind {
974    Lifetime(Region),
975    Type(Ty),
976    Const(TyConst),
977}
978
979impl GenericArgKind {
980    /// Panic if this generic argument is not a type, otherwise
981    /// return the type.
982    #[track_caller]
983    pub fn expect_ty(&self) -> &Ty {
984        match self {
985            GenericArgKind::Type(ty) => ty,
986            _ => panic!("{self:?}"),
987        }
988    }
989
990    /// Panic if this generic argument is not a const, otherwise
991    /// return the const.
992    #[track_caller]
993    pub fn expect_const(&self) -> &TyConst {
994        match self {
995            GenericArgKind::Const(c) => c,
996            _ => panic!("{self:?}"),
997        }
998    }
999
1000    /// Return the generic argument type if applicable, otherwise return `None`.
1001    pub fn ty(&self) -> Option<&Ty> {
1002        match self {
1003            GenericArgKind::Type(ty) => Some(ty),
1004            _ => None,
1005        }
1006    }
1007}
1008
1009#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1010pub enum TermKind {
1011    Type(Ty),
1012    Const(TyConst),
1013}
1014
1015#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1016pub enum AliasKind {
1017    Projection,
1018    Inherent,
1019    Opaque,
1020    Weak,
1021}
1022
1023#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1024pub struct AliasTy {
1025    pub def_id: AliasDef,
1026    pub args: GenericArgs,
1027}
1028
1029#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1030pub struct AliasTerm {
1031    pub def_id: AliasDef,
1032    pub args: GenericArgs,
1033}
1034
1035pub type PolyFnSig = Binder<FnSig>;
1036
1037impl PolyFnSig {
1038    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
1039    ///
1040    /// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
1041    /// instead, where the instance is an `InstanceKind::Virtual`.
1042    pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1043        with(|cx| cx.fn_ptr_abi(self))
1044    }
1045}
1046
1047#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1048pub struct FnSig {
1049    pub inputs_and_output: Vec<Ty>,
1050    pub c_variadic: bool,
1051    pub safety: Safety,
1052    pub abi: Abi,
1053}
1054
1055impl FnSig {
1056    pub fn output(&self) -> Ty {
1057        self.inputs_and_output[self.inputs_and_output.len() - 1]
1058    }
1059
1060    pub fn inputs(&self) -> &[Ty] {
1061        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1062    }
1063}
1064
1065#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1066pub enum Abi {
1067    Rust,
1068    C { unwind: bool },
1069    Cdecl { unwind: bool },
1070    Stdcall { unwind: bool },
1071    Fastcall { unwind: bool },
1072    Vectorcall { unwind: bool },
1073    Thiscall { unwind: bool },
1074    Aapcs { unwind: bool },
1075    Win64 { unwind: bool },
1076    SysV64 { unwind: bool },
1077    PtxKernel,
1078    Msp430Interrupt,
1079    X86Interrupt,
1080    GpuKernel,
1081    EfiApi,
1082    AvrInterrupt,
1083    AvrNonBlockingInterrupt,
1084    CCmseNonSecureCall,
1085    CCmseNonSecureEntry,
1086    System { unwind: bool },
1087    RustIntrinsic,
1088    RustCall,
1089    Unadjusted,
1090    RustCold,
1091    RiscvInterruptM,
1092    RiscvInterruptS,
1093}
1094
1095/// A binder represents a possibly generic type and its bound vars.
1096#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1097pub struct Binder<T> {
1098    pub value: T,
1099    pub bound_vars: Vec<BoundVariableKind>,
1100}
1101
1102impl<T> Binder<T> {
1103    /// Create a new binder with the given bound vars.
1104    pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1105        Binder { value, bound_vars }
1106    }
1107
1108    /// Create a new binder with no bounded variable.
1109    pub fn dummy(value: T) -> Self {
1110        Binder { value, bound_vars: vec![] }
1111    }
1112
1113    pub fn skip_binder(self) -> T {
1114        self.value
1115    }
1116
1117    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1118    where
1119        F: FnOnce(&T) -> U,
1120    {
1121        let Binder { value, bound_vars } = self;
1122        let new_value = f(value);
1123        Binder { value: new_value, bound_vars: bound_vars.clone() }
1124    }
1125
1126    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1127    where
1128        F: FnOnce(T) -> U,
1129    {
1130        let Binder { value, bound_vars } = self;
1131        let new_value = f(value);
1132        Binder { value: new_value, bound_vars }
1133    }
1134}
1135
1136#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1137pub struct EarlyBinder<T> {
1138    pub value: T,
1139}
1140
1141#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1142pub enum BoundVariableKind {
1143    Ty(BoundTyKind),
1144    Region(BoundRegionKind),
1145    Const,
1146}
1147
1148#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1149pub enum BoundTyKind {
1150    Anon,
1151    Param(ParamDef, String),
1152}
1153
1154#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1155pub enum BoundRegionKind {
1156    BrAnon,
1157    BrNamed(BrNamedDef, String),
1158    BrEnv,
1159}
1160
1161#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1162pub enum DynKind {
1163    Dyn,
1164    DynStar,
1165}
1166
1167#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1168pub enum ExistentialPredicate {
1169    Trait(ExistentialTraitRef),
1170    Projection(ExistentialProjection),
1171    AutoTrait(TraitDef),
1172}
1173
1174/// An existential reference to a trait where `Self` is not included.
1175///
1176/// The `generic_args` will include any other known argument.
1177#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1178pub struct ExistentialTraitRef {
1179    pub def_id: TraitDef,
1180    pub generic_args: GenericArgs,
1181}
1182
1183impl Binder<ExistentialTraitRef> {
1184    pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1185        self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1186    }
1187}
1188
1189impl ExistentialTraitRef {
1190    pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1191        TraitRef::new(self.def_id, self_ty, &self.generic_args)
1192    }
1193}
1194
1195#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1196pub struct ExistentialProjection {
1197    pub def_id: TraitDef,
1198    pub generic_args: GenericArgs,
1199    pub term: TermKind,
1200}
1201
1202#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1203pub struct ParamTy {
1204    pub index: u32,
1205    pub name: String,
1206}
1207
1208#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1209pub struct BoundTy {
1210    pub var: usize,
1211    pub kind: BoundTyKind,
1212}
1213
1214pub type Bytes = Vec<Option<u8>>;
1215
1216/// Size in bytes.
1217pub type Size = usize;
1218
1219#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1220pub struct Prov(pub AllocId);
1221
1222pub type Align = u64;
1223pub type Promoted = u32;
1224pub type InitMaskMaterialized = Vec<u64>;
1225
1226/// Stores the provenance information of pointers stored in memory.
1227#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1228pub struct ProvenanceMap {
1229    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
1230    /// bytes. Two entries in this map are always at least a pointer size apart.
1231    pub ptrs: Vec<(Size, Prov)>,
1232}
1233
1234#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1235pub struct Allocation {
1236    pub bytes: Bytes,
1237    pub provenance: ProvenanceMap,
1238    pub align: Align,
1239    pub mutability: Mutability,
1240}
1241
1242impl Allocation {
1243    /// Get a vector of bytes for an Allocation that has been fully initialized
1244    pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1245        self.bytes
1246            .iter()
1247            .copied()
1248            .collect::<Option<Vec<_>>>()
1249            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1250    }
1251
1252    /// Read a uint value from the specified range.
1253    pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1254        if range.end - range.start > 16 {
1255            return Err(error!("Allocation is bigger than largest integer"));
1256        }
1257        if range.end > self.bytes.len() {
1258            return Err(error!(
1259                "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1260                self.bytes.len(),
1261                range
1262            ));
1263        }
1264        let raw = self.bytes[range]
1265            .iter()
1266            .copied()
1267            .collect::<Option<Vec<_>>>()
1268            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1269        read_target_uint(&raw)
1270    }
1271
1272    /// Read this allocation and try to convert it to an unassigned integer.
1273    pub fn read_uint(&self) -> Result<u128, Error> {
1274        if self.bytes.len() > 16 {
1275            return Err(error!("Allocation is bigger than largest integer"));
1276        }
1277        let raw = self.raw_bytes()?;
1278        read_target_uint(&raw)
1279    }
1280
1281    /// Read this allocation and try to convert it to a signed integer.
1282    pub fn read_int(&self) -> Result<i128, Error> {
1283        if self.bytes.len() > 16 {
1284            return Err(error!("Allocation is bigger than largest integer"));
1285        }
1286        let raw = self.raw_bytes()?;
1287        read_target_int(&raw)
1288    }
1289
1290    /// Read this allocation and try to convert it to a boolean.
1291    pub fn read_bool(&self) -> Result<bool, Error> {
1292        match self.read_int()? {
1293            0 => Ok(false),
1294            1 => Ok(true),
1295            val => Err(error!("Unexpected value for bool: `{val}`")),
1296        }
1297    }
1298
1299    /// Read this allocation as a pointer and return whether it represents a `null` pointer.
1300    pub fn is_null(&self) -> Result<bool, Error> {
1301        let len = self.bytes.len();
1302        let ptr_len = MachineInfo::target_pointer_width().bytes();
1303        if len != ptr_len {
1304            return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1305        }
1306        Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1307    }
1308}
1309
1310#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1311pub enum ConstantKind {
1312    Ty(TyConst),
1313    Allocated(Allocation),
1314    Unevaluated(UnevaluatedConst),
1315    Param(ParamConst),
1316    /// Store ZST constants.
1317    /// We have to special handle these constants since its type might be generic.
1318    ZeroSized,
1319}
1320
1321#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1322pub struct ParamConst {
1323    pub index: u32,
1324    pub name: String,
1325}
1326
1327#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1328pub struct UnevaluatedConst {
1329    pub def: ConstDef,
1330    pub args: GenericArgs,
1331    pub promoted: Option<Promoted>,
1332}
1333
1334#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1335pub enum TraitSpecializationKind {
1336    None,
1337    Marker,
1338    AlwaysApplicable,
1339}
1340
1341#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1342pub struct TraitDecl {
1343    pub def_id: TraitDef,
1344    pub safety: Safety,
1345    pub paren_sugar: bool,
1346    pub has_auto_impl: bool,
1347    pub is_marker: bool,
1348    pub is_coinductive: bool,
1349    pub skip_array_during_method_dispatch: bool,
1350    pub skip_boxed_slice_during_method_dispatch: bool,
1351    pub specialization_kind: TraitSpecializationKind,
1352    pub must_implement_one_of: Option<Vec<Ident>>,
1353    pub implement_via_object: bool,
1354    pub deny_explicit_impl: bool,
1355}
1356
1357impl TraitDecl {
1358    pub fn generics_of(&self) -> Generics {
1359        with(|cx| cx.generics_of(self.def_id.0))
1360    }
1361
1362    pub fn predicates_of(&self) -> GenericPredicates {
1363        with(|cx| cx.predicates_of(self.def_id.0))
1364    }
1365
1366    pub fn explicit_predicates_of(&self) -> GenericPredicates {
1367        with(|cx| cx.explicit_predicates_of(self.def_id.0))
1368    }
1369}
1370
1371pub type ImplTrait = EarlyBinder<TraitRef>;
1372
1373/// A complete reference to a trait, i.e., one where `Self` is known.
1374#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1375pub struct TraitRef {
1376    pub def_id: TraitDef,
1377    /// The generic arguments for this definition.
1378    /// The first element must always be type, and it represents `Self`.
1379    args: GenericArgs,
1380}
1381
1382impl TraitRef {
1383    pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1384        let mut args = vec![GenericArgKind::Type(self_ty)];
1385        args.extend_from_slice(&gen_args.0);
1386        TraitRef { def_id, args: GenericArgs(args) }
1387    }
1388
1389    pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1390        match &args.0[..] {
1391            [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1392            _ => Err(()),
1393        }
1394    }
1395
1396    pub fn args(&self) -> &GenericArgs {
1397        &self.args
1398    }
1399
1400    pub fn self_ty(&self) -> Ty {
1401        let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1402            panic!("Self must be a type, but found: {:?}", self.args.0[0])
1403        };
1404        self_ty
1405    }
1406}
1407
1408#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1409pub struct Generics {
1410    pub parent: Option<GenericDef>,
1411    pub parent_count: usize,
1412    pub params: Vec<GenericParamDef>,
1413    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1414    pub has_self: bool,
1415    pub has_late_bound_regions: Option<Span>,
1416}
1417
1418#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1419pub enum GenericParamDefKind {
1420    Lifetime,
1421    Type { has_default: bool, synthetic: bool },
1422    Const { has_default: bool },
1423}
1424
1425#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1426pub struct GenericParamDef {
1427    pub name: super::Symbol,
1428    pub def_id: GenericDef,
1429    pub index: u32,
1430    pub pure_wrt_drop: bool,
1431    pub kind: GenericParamDefKind,
1432}
1433
1434pub struct GenericPredicates {
1435    pub parent: Option<TraitDef>,
1436    pub predicates: Vec<(PredicateKind, Span)>,
1437}
1438
1439#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1440pub enum PredicateKind {
1441    Clause(ClauseKind),
1442    DynCompatible(TraitDef),
1443    SubType(SubtypePredicate),
1444    Coerce(CoercePredicate),
1445    ConstEquate(TyConst, TyConst),
1446    Ambiguous,
1447    AliasRelate(TermKind, TermKind, AliasRelationDirection),
1448}
1449
1450#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1451pub enum ClauseKind {
1452    Trait(TraitPredicate),
1453    RegionOutlives(RegionOutlivesPredicate),
1454    TypeOutlives(TypeOutlivesPredicate),
1455    Projection(ProjectionPredicate),
1456    ConstArgHasType(TyConst, Ty),
1457    WellFormed(GenericArgKind),
1458    ConstEvaluatable(TyConst),
1459}
1460
1461#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1462pub enum ClosureKind {
1463    Fn,
1464    FnMut,
1465    FnOnce,
1466}
1467
1468#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1469pub struct SubtypePredicate {
1470    pub a: Ty,
1471    pub b: Ty,
1472}
1473
1474#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1475pub struct CoercePredicate {
1476    pub a: Ty,
1477    pub b: Ty,
1478}
1479
1480#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1481pub enum AliasRelationDirection {
1482    Equate,
1483    Subtype,
1484}
1485
1486#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1487pub struct TraitPredicate {
1488    pub trait_ref: TraitRef,
1489    pub polarity: PredicatePolarity,
1490}
1491
1492#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1493pub struct OutlivesPredicate<A, B>(pub A, pub B);
1494
1495pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1496pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1497
1498#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1499pub struct ProjectionPredicate {
1500    pub projection_term: AliasTerm,
1501    pub term: TermKind,
1502}
1503
1504#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1505pub enum ImplPolarity {
1506    Positive,
1507    Negative,
1508    Reservation,
1509}
1510
1511#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1512pub enum PredicatePolarity {
1513    Positive,
1514    Negative,
1515}
1516
1517pub trait IndexedVal {
1518    fn to_val(index: usize) -> Self;
1519
1520    fn to_index(&self) -> usize;
1521}
1522
1523macro_rules! index_impl {
1524    ($name:ident) => {
1525        impl IndexedVal for $name {
1526            fn to_val(index: usize) -> Self {
1527                $name(index)
1528            }
1529            fn to_index(&self) -> usize {
1530                self.0
1531            }
1532        }
1533    };
1534}
1535
1536index_impl!(TyConstId);
1537index_impl!(MirConstId);
1538index_impl!(Ty);
1539index_impl!(Span);
1540
1541/// The source-order index of a variant in a type.
1542///
1543/// For example, in the following types,
1544/// ```ignore(illustrative)
1545/// enum Demo1 {
1546///    Variant0 { a: bool, b: i32 },
1547///    Variant1 { c: u8, d: u64 },
1548/// }
1549/// struct Demo2 { e: u8, f: u16, g: u8 }
1550/// ```
1551/// `a` is in the variant with the `VariantIdx` of `0`,
1552/// `c` is in the variant with the `VariantIdx` of `1`, and
1553/// `g` is in the variant with the `VariantIdx` of `0`.
1554#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1555pub struct VariantIdx(usize);
1556
1557index_impl!(VariantIdx);