rustc_public/
ty.rs

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