rustc_smir/stable_mir/
ty.rs

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