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, ThreadLocalIndex};
15
16#[derive(Copy, Clone, Eq, PartialEq, Hash)]
17pub struct Ty(usize, ThreadLocalIndex);
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)]
155pub struct TyConstId(usize, ThreadLocalIndex);
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)]
216pub struct MirConstId(usize, ThreadLocalIndex);
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)]
259pub struct Span(usize, ThreadLocalIndex);
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    /// The name of the variant, struct or union.
880    ///
881    /// This will not include the name of the enum or qualified path.
882    pub fn name(&self) -> Symbol {
883        with(|cx| cx.variant_name(*self))
884    }
885
886    /// Retrieve all the fields in this variant.
887    // We expect user to cache this and use it directly since today it is expensive to generate all
888    // fields name.
889    pub fn fields(&self) -> Vec<FieldDef> {
890        with(|cx| cx.variant_fields(*self))
891    }
892}
893
894#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
895pub struct FieldDef {
896    /// The field definition.
897    ///
898    /// ## Warning
899    /// Do not access this field directly! This is public for the compiler to have access to it.
900    pub def: DefId,
901
902    /// The field name.
903    pub name: Symbol,
904}
905
906impl FieldDef {
907    /// Retrieve the type of this field instantiating and normalizing it with the given arguments.
908    ///
909    /// This will assume the type can be instantiated with these arguments.
910    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
911        with(|cx| cx.def_ty_with_args(self.def, args))
912    }
913
914    /// Retrieve the type of this field.
915    pub fn ty(&self) -> Ty {
916        with(|cx| cx.def_ty(self.def))
917    }
918}
919
920impl Display for AdtKind {
921    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
922        f.write_str(match self {
923            AdtKind::Enum => "enum",
924            AdtKind::Union => "union",
925            AdtKind::Struct => "struct",
926        })
927    }
928}
929
930impl AdtKind {
931    pub fn is_enum(&self) -> bool {
932        matches!(self, AdtKind::Enum)
933    }
934
935    pub fn is_struct(&self) -> bool {
936        matches!(self, AdtKind::Struct)
937    }
938
939    pub fn is_union(&self) -> bool {
940        matches!(self, AdtKind::Union)
941    }
942}
943
944crate_def! {
945    #[derive(Serialize)]
946    pub AliasDef;
947}
948
949crate_def! {
950    /// A trait's definition.
951    #[derive(Serialize)]
952    pub TraitDef;
953}
954
955impl_crate_def_items! {
956    TraitDef;
957}
958
959impl TraitDef {
960    pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
961        with(|cx| cx.trait_decl(trait_def))
962    }
963}
964
965crate_def! {
966    #[derive(Serialize)]
967    pub GenericDef;
968}
969
970crate_def_with_ty! {
971    #[derive(Serialize)]
972    pub ConstDef;
973}
974
975crate_def! {
976    /// A trait impl definition.
977    #[derive(Serialize)]
978    pub ImplDef;
979}
980
981impl_crate_def_items! {
982    ImplDef;
983}
984
985impl ImplDef {
986    /// Retrieve information about this implementation.
987    pub fn trait_impl(&self) -> ImplTrait {
988        with(|cx| cx.trait_impl(self))
989    }
990}
991
992crate_def! {
993    #[derive(Serialize)]
994    pub RegionDef;
995}
996
997crate_def! {
998    #[derive(Serialize)]
999    pub CoroutineWitnessDef;
1000}
1001
1002/// A list of generic arguments.
1003#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1004pub struct GenericArgs(pub Vec<GenericArgKind>);
1005
1006impl std::ops::Index<ParamTy> for GenericArgs {
1007    type Output = Ty;
1008
1009    fn index(&self, index: ParamTy) -> &Self::Output {
1010        self.0[index.index as usize].expect_ty()
1011    }
1012}
1013
1014impl std::ops::Index<ParamConst> for GenericArgs {
1015    type Output = TyConst;
1016
1017    fn index(&self, index: ParamConst) -> &Self::Output {
1018        self.0[index.index as usize].expect_const()
1019    }
1020}
1021
1022#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1023pub enum GenericArgKind {
1024    Lifetime(Region),
1025    Type(Ty),
1026    Const(TyConst),
1027}
1028
1029impl GenericArgKind {
1030    /// Panic if this generic argument is not a type, otherwise
1031    /// return the type.
1032    #[track_caller]
1033    pub fn expect_ty(&self) -> &Ty {
1034        match self {
1035            GenericArgKind::Type(ty) => ty,
1036            _ => panic!("{self:?}"),
1037        }
1038    }
1039
1040    /// Panic if this generic argument is not a const, otherwise
1041    /// return the const.
1042    #[track_caller]
1043    pub fn expect_const(&self) -> &TyConst {
1044        match self {
1045            GenericArgKind::Const(c) => c,
1046            _ => panic!("{self:?}"),
1047        }
1048    }
1049
1050    /// Return the generic argument type if applicable, otherwise return `None`.
1051    pub fn ty(&self) -> Option<&Ty> {
1052        match self {
1053            GenericArgKind::Type(ty) => Some(ty),
1054            _ => None,
1055        }
1056    }
1057}
1058
1059#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1060pub enum TermKind {
1061    Type(Ty),
1062    Const(TyConst),
1063}
1064
1065#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1066pub enum AliasKind {
1067    Projection,
1068    Inherent,
1069    Opaque,
1070    Free,
1071}
1072
1073#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1074pub struct AliasTy {
1075    pub def_id: AliasDef,
1076    pub args: GenericArgs,
1077}
1078
1079#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1080pub struct AliasTerm {
1081    pub def_id: AliasDef,
1082    pub args: GenericArgs,
1083}
1084
1085pub type PolyFnSig = Binder<FnSig>;
1086
1087impl PolyFnSig {
1088    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
1089    ///
1090    /// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
1091    /// instead, where the instance is an `InstanceKind::Virtual`.
1092    pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1093        with(|cx| cx.fn_ptr_abi(self))
1094    }
1095}
1096
1097#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1098pub struct FnSig {
1099    pub inputs_and_output: Vec<Ty>,
1100    pub c_variadic: bool,
1101    pub safety: Safety,
1102    pub abi: Abi,
1103}
1104
1105impl FnSig {
1106    pub fn output(&self) -> Ty {
1107        self.inputs_and_output[self.inputs_and_output.len() - 1]
1108    }
1109
1110    pub fn inputs(&self) -> &[Ty] {
1111        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1112    }
1113}
1114
1115#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1116pub enum Abi {
1117    Rust,
1118    C { unwind: bool },
1119    Cdecl { unwind: bool },
1120    Stdcall { unwind: bool },
1121    Fastcall { unwind: bool },
1122    Vectorcall { unwind: bool },
1123    Thiscall { unwind: bool },
1124    Aapcs { unwind: bool },
1125    Win64 { unwind: bool },
1126    SysV64 { unwind: bool },
1127    PtxKernel,
1128    Msp430Interrupt,
1129    X86Interrupt,
1130    GpuKernel,
1131    EfiApi,
1132    AvrInterrupt,
1133    AvrNonBlockingInterrupt,
1134    CCmseNonSecureCall,
1135    CCmseNonSecureEntry,
1136    System { unwind: bool },
1137    RustCall,
1138    Unadjusted,
1139    RustCold,
1140    RiscvInterruptM,
1141    RiscvInterruptS,
1142    RustInvalid,
1143    Custom,
1144}
1145
1146/// A binder represents a possibly generic type and its bound vars.
1147#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1148pub struct Binder<T> {
1149    pub value: T,
1150    pub bound_vars: Vec<BoundVariableKind>,
1151}
1152
1153impl<T> Binder<T> {
1154    /// Create a new binder with the given bound vars.
1155    pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1156        Binder { value, bound_vars }
1157    }
1158
1159    /// Create a new binder with no bounded variable.
1160    pub fn dummy(value: T) -> Self {
1161        Binder { value, bound_vars: vec![] }
1162    }
1163
1164    pub fn skip_binder(self) -> T {
1165        self.value
1166    }
1167
1168    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1169    where
1170        F: FnOnce(&T) -> U,
1171    {
1172        let Binder { value, bound_vars } = self;
1173        let new_value = f(value);
1174        Binder { value: new_value, bound_vars: bound_vars.clone() }
1175    }
1176
1177    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1178    where
1179        F: FnOnce(T) -> U,
1180    {
1181        let Binder { value, bound_vars } = self;
1182        let new_value = f(value);
1183        Binder { value: new_value, bound_vars }
1184    }
1185}
1186
1187#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1188pub struct EarlyBinder<T> {
1189    pub value: T,
1190}
1191
1192#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1193pub enum BoundVariableKind {
1194    Ty(BoundTyKind),
1195    Region(BoundRegionKind),
1196    Const,
1197}
1198
1199#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1200pub enum BoundTyKind {
1201    Anon,
1202    Param(ParamDef, String),
1203}
1204
1205#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1206pub enum BoundRegionKind {
1207    BrAnon,
1208    BrNamed(BrNamedDef, String),
1209    BrEnv,
1210}
1211
1212#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1213pub enum ExistentialPredicate {
1214    Trait(ExistentialTraitRef),
1215    Projection(ExistentialProjection),
1216    AutoTrait(TraitDef),
1217}
1218
1219/// An existential reference to a trait where `Self` is not included.
1220///
1221/// The `generic_args` will include any other known argument.
1222#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1223pub struct ExistentialTraitRef {
1224    pub def_id: TraitDef,
1225    pub generic_args: GenericArgs,
1226}
1227
1228impl Binder<ExistentialTraitRef> {
1229    pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1230        self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1231    }
1232}
1233
1234impl ExistentialTraitRef {
1235    pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1236        TraitRef::new(self.def_id, self_ty, &self.generic_args)
1237    }
1238}
1239
1240#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1241pub struct ExistentialProjection {
1242    pub def_id: TraitDef,
1243    pub generic_args: GenericArgs,
1244    pub term: TermKind,
1245}
1246
1247#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1248pub struct ParamTy {
1249    pub index: u32,
1250    pub name: String,
1251}
1252
1253#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1254pub struct BoundTy {
1255    pub var: usize,
1256    pub kind: BoundTyKind,
1257}
1258
1259pub type Bytes = Vec<Option<u8>>;
1260
1261/// Size in bytes.
1262pub type Size = usize;
1263
1264#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1265pub struct Prov(pub AllocId);
1266
1267pub type Align = u64;
1268pub type Promoted = u32;
1269pub type InitMaskMaterialized = Vec<u64>;
1270
1271/// Stores the provenance information of pointers stored in memory.
1272#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1273pub struct ProvenanceMap {
1274    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
1275    /// bytes. Two entries in this map are always at least a pointer size apart.
1276    pub ptrs: Vec<(Size, Prov)>,
1277}
1278
1279#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1280pub struct Allocation {
1281    pub bytes: Bytes,
1282    pub provenance: ProvenanceMap,
1283    pub align: Align,
1284    pub mutability: Mutability,
1285}
1286
1287impl Allocation {
1288    /// Get a vector of bytes for an Allocation that has been fully initialized
1289    pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1290        self.bytes
1291            .iter()
1292            .copied()
1293            .collect::<Option<Vec<_>>>()
1294            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1295    }
1296
1297    /// Read a uint value from the specified range.
1298    pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1299        if range.end - range.start > 16 {
1300            return Err(error!("Allocation is bigger than largest integer"));
1301        }
1302        if range.end > self.bytes.len() {
1303            return Err(error!(
1304                "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1305                self.bytes.len(),
1306                range
1307            ));
1308        }
1309        let raw = self.bytes[range]
1310            .iter()
1311            .copied()
1312            .collect::<Option<Vec<_>>>()
1313            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1314        read_target_uint(&raw)
1315    }
1316
1317    /// Read this allocation and try to convert it to an unassigned integer.
1318    pub fn read_uint(&self) -> Result<u128, Error> {
1319        if self.bytes.len() > 16 {
1320            return Err(error!("Allocation is bigger than largest integer"));
1321        }
1322        let raw = self.raw_bytes()?;
1323        read_target_uint(&raw)
1324    }
1325
1326    /// Read this allocation and try to convert it to a signed integer.
1327    pub fn read_int(&self) -> Result<i128, Error> {
1328        if self.bytes.len() > 16 {
1329            return Err(error!("Allocation is bigger than largest integer"));
1330        }
1331        let raw = self.raw_bytes()?;
1332        read_target_int(&raw)
1333    }
1334
1335    /// Read this allocation and try to convert it to a boolean.
1336    pub fn read_bool(&self) -> Result<bool, Error> {
1337        match self.read_int()? {
1338            0 => Ok(false),
1339            1 => Ok(true),
1340            val => Err(error!("Unexpected value for bool: `{val}`")),
1341        }
1342    }
1343
1344    /// Read this allocation as a pointer and return whether it represents a `null` pointer.
1345    pub fn is_null(&self) -> Result<bool, Error> {
1346        let len = self.bytes.len();
1347        let ptr_len = MachineInfo::target_pointer_width().bytes();
1348        if len != ptr_len {
1349            return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1350        }
1351        Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1352    }
1353}
1354
1355#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1356pub enum ConstantKind {
1357    Ty(TyConst),
1358    Allocated(Allocation),
1359    Unevaluated(UnevaluatedConst),
1360    Param(ParamConst),
1361    /// Store ZST constants.
1362    /// We have to special handle these constants since its type might be generic.
1363    ZeroSized,
1364}
1365
1366#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1367pub struct ParamConst {
1368    pub index: u32,
1369    pub name: String,
1370}
1371
1372#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1373pub struct UnevaluatedConst {
1374    pub def: ConstDef,
1375    pub args: GenericArgs,
1376    pub promoted: Option<Promoted>,
1377}
1378
1379#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1380pub enum TraitSpecializationKind {
1381    None,
1382    Marker,
1383    AlwaysApplicable,
1384}
1385
1386#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1387pub struct TraitDecl {
1388    pub def_id: TraitDef,
1389    pub safety: Safety,
1390    pub paren_sugar: bool,
1391    pub has_auto_impl: bool,
1392    pub is_marker: bool,
1393    pub is_coinductive: bool,
1394    pub skip_array_during_method_dispatch: bool,
1395    pub skip_boxed_slice_during_method_dispatch: bool,
1396    pub specialization_kind: TraitSpecializationKind,
1397    pub must_implement_one_of: Option<Vec<Ident>>,
1398    pub implement_via_object: bool,
1399    pub deny_explicit_impl: bool,
1400}
1401
1402impl TraitDecl {
1403    pub fn generics_of(&self) -> Generics {
1404        with(|cx| cx.generics_of(self.def_id.0))
1405    }
1406
1407    pub fn predicates_of(&self) -> GenericPredicates {
1408        with(|cx| cx.predicates_of(self.def_id.0))
1409    }
1410
1411    pub fn explicit_predicates_of(&self) -> GenericPredicates {
1412        with(|cx| cx.explicit_predicates_of(self.def_id.0))
1413    }
1414}
1415
1416pub type ImplTrait = EarlyBinder<TraitRef>;
1417
1418/// A complete reference to a trait, i.e., one where `Self` is known.
1419#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1420pub struct TraitRef {
1421    pub def_id: TraitDef,
1422    /// The generic arguments for this definition.
1423    /// The first element must always be type, and it represents `Self`.
1424    args: GenericArgs,
1425}
1426
1427impl TraitRef {
1428    pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1429        let mut args = vec![GenericArgKind::Type(self_ty)];
1430        args.extend_from_slice(&gen_args.0);
1431        TraitRef { def_id, args: GenericArgs(args) }
1432    }
1433
1434    pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1435        match &args.0[..] {
1436            [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1437            _ => Err(()),
1438        }
1439    }
1440
1441    pub fn args(&self) -> &GenericArgs {
1442        &self.args
1443    }
1444
1445    pub fn self_ty(&self) -> Ty {
1446        let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1447            panic!("Self must be a type, but found: {:?}", self.args.0[0])
1448        };
1449        self_ty
1450    }
1451}
1452
1453#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1454pub struct Generics {
1455    pub parent: Option<GenericDef>,
1456    pub parent_count: usize,
1457    pub params: Vec<GenericParamDef>,
1458    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1459    pub has_self: bool,
1460    pub has_late_bound_regions: Option<Span>,
1461}
1462
1463#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1464pub enum GenericParamDefKind {
1465    Lifetime,
1466    Type { has_default: bool, synthetic: bool },
1467    Const { has_default: bool },
1468}
1469
1470#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1471pub struct GenericParamDef {
1472    pub name: super::Symbol,
1473    pub def_id: GenericDef,
1474    pub index: u32,
1475    pub pure_wrt_drop: bool,
1476    pub kind: GenericParamDefKind,
1477}
1478
1479pub struct GenericPredicates {
1480    pub parent: Option<TraitDef>,
1481    pub predicates: Vec<(PredicateKind, Span)>,
1482}
1483
1484#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1485pub enum PredicateKind {
1486    Clause(ClauseKind),
1487    DynCompatible(TraitDef),
1488    SubType(SubtypePredicate),
1489    Coerce(CoercePredicate),
1490    ConstEquate(TyConst, TyConst),
1491    Ambiguous,
1492    AliasRelate(TermKind, TermKind, AliasRelationDirection),
1493}
1494
1495#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1496pub enum ClauseKind {
1497    Trait(TraitPredicate),
1498    RegionOutlives(RegionOutlivesPredicate),
1499    TypeOutlives(TypeOutlivesPredicate),
1500    Projection(ProjectionPredicate),
1501    ConstArgHasType(TyConst, Ty),
1502    WellFormed(TermKind),
1503    ConstEvaluatable(TyConst),
1504}
1505
1506#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1507pub enum ClosureKind {
1508    Fn,
1509    FnMut,
1510    FnOnce,
1511}
1512
1513#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1514pub struct SubtypePredicate {
1515    pub a: Ty,
1516    pub b: Ty,
1517}
1518
1519#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1520pub struct CoercePredicate {
1521    pub a: Ty,
1522    pub b: Ty,
1523}
1524
1525#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1526pub enum AliasRelationDirection {
1527    Equate,
1528    Subtype,
1529}
1530
1531#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1532pub struct TraitPredicate {
1533    pub trait_ref: TraitRef,
1534    pub polarity: PredicatePolarity,
1535}
1536
1537#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1538pub struct OutlivesPredicate<A, B>(pub A, pub B);
1539
1540pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1541pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1542
1543#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1544pub struct ProjectionPredicate {
1545    pub projection_term: AliasTerm,
1546    pub term: TermKind,
1547}
1548
1549#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1550pub enum ImplPolarity {
1551    Positive,
1552    Negative,
1553    Reservation,
1554}
1555
1556#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1557pub enum PredicatePolarity {
1558    Positive,
1559    Negative,
1560}
1561
1562macro_rules! index_impl {
1563    ($name:ident) => {
1564        impl crate::IndexedVal for $name {
1565            fn to_val(index: usize) -> Self {
1566                $name(index, $crate::ThreadLocalIndex)
1567            }
1568            fn to_index(&self) -> usize {
1569                self.0
1570            }
1571        }
1572        $crate::ty::serialize_index_impl!($name);
1573    };
1574}
1575macro_rules! serialize_index_impl {
1576    ($name:ident) => {
1577        impl ::serde::Serialize for $name {
1578            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1579            where
1580                S: ::serde::Serializer,
1581            {
1582                let n: usize = self.0; // Make sure we're serializing an int.
1583                ::serde::Serialize::serialize(&n, serializer)
1584            }
1585        }
1586    };
1587}
1588pub(crate) use {index_impl, serialize_index_impl};
1589
1590index_impl!(TyConstId);
1591index_impl!(MirConstId);
1592index_impl!(Ty);
1593index_impl!(Span);
1594
1595/// The source-order index of a variant in a type.
1596///
1597/// For example, in the following types,
1598/// ```ignore(illustrative)
1599/// enum Demo1 {
1600///    Variant0 { a: bool, b: i32 },
1601///    Variant1 { c: u8, d: u64 },
1602/// }
1603/// struct Demo2 { e: u8, f: u16, g: u8 }
1604/// ```
1605/// `a` is in the variant with the `VariantIdx` of `0`,
1606/// `c` is in the variant with the `VariantIdx` of `1`, and
1607/// `g` is in the variant with the `VariantIdx` of `0`.
1608#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1609pub struct VariantIdx(usize, ThreadLocalIndex);
1610
1611index_impl!(VariantIdx);
1612
1613crate_def! {
1614    /// Hold information about an Opaque definition, particularly useful in `RPITIT`.
1615    #[derive(Serialize)]
1616    pub OpaqueDef;
1617}
1618
1619crate_def! {
1620    #[derive(Serialize)]
1621    pub AssocDef;
1622}
1623
1624#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1625pub struct AssocItem {
1626    pub def_id: AssocDef,
1627    pub kind: AssocKind,
1628    pub container: AssocContainer,
1629}
1630
1631#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1632pub enum AssocTypeData {
1633    Normal(Symbol),
1634    /// The associated type comes from an RPITIT. It has no name, and the
1635    /// `ImplTraitInTraitData` provides additional information about its
1636    /// source.
1637    Rpitit(ImplTraitInTraitData),
1638}
1639
1640#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1641pub enum AssocKind {
1642    Const { name: Symbol },
1643    Fn { name: Symbol, has_self: bool },
1644    Type { data: AssocTypeData },
1645}
1646
1647#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1648pub enum AssocContainer {
1649    InherentImpl,
1650    /// The `AssocDef` points to the trait item being implemented.
1651    TraitImpl(AssocDef),
1652    Trait,
1653}
1654
1655#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1656pub enum ImplTraitInTraitData {
1657    Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1658    Impl { fn_def_id: FnDef },
1659}
1660
1661impl AssocItem {
1662    pub fn is_impl_trait_in_trait(&self) -> bool {
1663        matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1664    }
1665}