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(_, _, DynKind::Dyn)))
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, DynKind),
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 DynKind {
1211    Dyn,
1212}
1213
1214#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1215pub enum ExistentialPredicate {
1216    Trait(ExistentialTraitRef),
1217    Projection(ExistentialProjection),
1218    AutoTrait(TraitDef),
1219}
1220
1221/// An existential reference to a trait where `Self` is not included.
1222///
1223/// The `generic_args` will include any other known argument.
1224#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1225pub struct ExistentialTraitRef {
1226    pub def_id: TraitDef,
1227    pub generic_args: GenericArgs,
1228}
1229
1230impl Binder<ExistentialTraitRef> {
1231    pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1232        self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1233    }
1234}
1235
1236impl ExistentialTraitRef {
1237    pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1238        TraitRef::new(self.def_id, self_ty, &self.generic_args)
1239    }
1240}
1241
1242#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1243pub struct ExistentialProjection {
1244    pub def_id: TraitDef,
1245    pub generic_args: GenericArgs,
1246    pub term: TermKind,
1247}
1248
1249#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1250pub struct ParamTy {
1251    pub index: u32,
1252    pub name: String,
1253}
1254
1255#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1256pub struct BoundTy {
1257    pub var: usize,
1258    pub kind: BoundTyKind,
1259}
1260
1261pub type Bytes = Vec<Option<u8>>;
1262
1263/// Size in bytes.
1264pub type Size = usize;
1265
1266#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1267pub struct Prov(pub AllocId);
1268
1269pub type Align = u64;
1270pub type Promoted = u32;
1271pub type InitMaskMaterialized = Vec<u64>;
1272
1273/// Stores the provenance information of pointers stored in memory.
1274#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1275pub struct ProvenanceMap {
1276    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
1277    /// bytes. Two entries in this map are always at least a pointer size apart.
1278    pub ptrs: Vec<(Size, Prov)>,
1279}
1280
1281#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1282pub struct Allocation {
1283    pub bytes: Bytes,
1284    pub provenance: ProvenanceMap,
1285    pub align: Align,
1286    pub mutability: Mutability,
1287}
1288
1289impl Allocation {
1290    /// Get a vector of bytes for an Allocation that has been fully initialized
1291    pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1292        self.bytes
1293            .iter()
1294            .copied()
1295            .collect::<Option<Vec<_>>>()
1296            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1297    }
1298
1299    /// Read a uint value from the specified range.
1300    pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1301        if range.end - range.start > 16 {
1302            return Err(error!("Allocation is bigger than largest integer"));
1303        }
1304        if range.end > self.bytes.len() {
1305            return Err(error!(
1306                "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1307                self.bytes.len(),
1308                range
1309            ));
1310        }
1311        let raw = self.bytes[range]
1312            .iter()
1313            .copied()
1314            .collect::<Option<Vec<_>>>()
1315            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1316        read_target_uint(&raw)
1317    }
1318
1319    /// Read this allocation and try to convert it to an unassigned integer.
1320    pub fn read_uint(&self) -> Result<u128, Error> {
1321        if self.bytes.len() > 16 {
1322            return Err(error!("Allocation is bigger than largest integer"));
1323        }
1324        let raw = self.raw_bytes()?;
1325        read_target_uint(&raw)
1326    }
1327
1328    /// Read this allocation and try to convert it to a signed integer.
1329    pub fn read_int(&self) -> Result<i128, Error> {
1330        if self.bytes.len() > 16 {
1331            return Err(error!("Allocation is bigger than largest integer"));
1332        }
1333        let raw = self.raw_bytes()?;
1334        read_target_int(&raw)
1335    }
1336
1337    /// Read this allocation and try to convert it to a boolean.
1338    pub fn read_bool(&self) -> Result<bool, Error> {
1339        match self.read_int()? {
1340            0 => Ok(false),
1341            1 => Ok(true),
1342            val => Err(error!("Unexpected value for bool: `{val}`")),
1343        }
1344    }
1345
1346    /// Read this allocation as a pointer and return whether it represents a `null` pointer.
1347    pub fn is_null(&self) -> Result<bool, Error> {
1348        let len = self.bytes.len();
1349        let ptr_len = MachineInfo::target_pointer_width().bytes();
1350        if len != ptr_len {
1351            return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1352        }
1353        Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1354    }
1355}
1356
1357#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1358pub enum ConstantKind {
1359    Ty(TyConst),
1360    Allocated(Allocation),
1361    Unevaluated(UnevaluatedConst),
1362    Param(ParamConst),
1363    /// Store ZST constants.
1364    /// We have to special handle these constants since its type might be generic.
1365    ZeroSized,
1366}
1367
1368#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1369pub struct ParamConst {
1370    pub index: u32,
1371    pub name: String,
1372}
1373
1374#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1375pub struct UnevaluatedConst {
1376    pub def: ConstDef,
1377    pub args: GenericArgs,
1378    pub promoted: Option<Promoted>,
1379}
1380
1381#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1382pub enum TraitSpecializationKind {
1383    None,
1384    Marker,
1385    AlwaysApplicable,
1386}
1387
1388#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1389pub struct TraitDecl {
1390    pub def_id: TraitDef,
1391    pub safety: Safety,
1392    pub paren_sugar: bool,
1393    pub has_auto_impl: bool,
1394    pub is_marker: bool,
1395    pub is_coinductive: bool,
1396    pub skip_array_during_method_dispatch: bool,
1397    pub skip_boxed_slice_during_method_dispatch: bool,
1398    pub specialization_kind: TraitSpecializationKind,
1399    pub must_implement_one_of: Option<Vec<Ident>>,
1400    pub implement_via_object: bool,
1401    pub deny_explicit_impl: bool,
1402}
1403
1404impl TraitDecl {
1405    pub fn generics_of(&self) -> Generics {
1406        with(|cx| cx.generics_of(self.def_id.0))
1407    }
1408
1409    pub fn predicates_of(&self) -> GenericPredicates {
1410        with(|cx| cx.predicates_of(self.def_id.0))
1411    }
1412
1413    pub fn explicit_predicates_of(&self) -> GenericPredicates {
1414        with(|cx| cx.explicit_predicates_of(self.def_id.0))
1415    }
1416}
1417
1418pub type ImplTrait = EarlyBinder<TraitRef>;
1419
1420/// A complete reference to a trait, i.e., one where `Self` is known.
1421#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1422pub struct TraitRef {
1423    pub def_id: TraitDef,
1424    /// The generic arguments for this definition.
1425    /// The first element must always be type, and it represents `Self`.
1426    args: GenericArgs,
1427}
1428
1429impl TraitRef {
1430    pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1431        let mut args = vec![GenericArgKind::Type(self_ty)];
1432        args.extend_from_slice(&gen_args.0);
1433        TraitRef { def_id, args: GenericArgs(args) }
1434    }
1435
1436    pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1437        match &args.0[..] {
1438            [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1439            _ => Err(()),
1440        }
1441    }
1442
1443    pub fn args(&self) -> &GenericArgs {
1444        &self.args
1445    }
1446
1447    pub fn self_ty(&self) -> Ty {
1448        let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1449            panic!("Self must be a type, but found: {:?}", self.args.0[0])
1450        };
1451        self_ty
1452    }
1453}
1454
1455#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1456pub struct Generics {
1457    pub parent: Option<GenericDef>,
1458    pub parent_count: usize,
1459    pub params: Vec<GenericParamDef>,
1460    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1461    pub has_self: bool,
1462    pub has_late_bound_regions: Option<Span>,
1463}
1464
1465#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1466pub enum GenericParamDefKind {
1467    Lifetime,
1468    Type { has_default: bool, synthetic: bool },
1469    Const { has_default: bool },
1470}
1471
1472#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1473pub struct GenericParamDef {
1474    pub name: super::Symbol,
1475    pub def_id: GenericDef,
1476    pub index: u32,
1477    pub pure_wrt_drop: bool,
1478    pub kind: GenericParamDefKind,
1479}
1480
1481pub struct GenericPredicates {
1482    pub parent: Option<TraitDef>,
1483    pub predicates: Vec<(PredicateKind, Span)>,
1484}
1485
1486#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1487pub enum PredicateKind {
1488    Clause(ClauseKind),
1489    DynCompatible(TraitDef),
1490    SubType(SubtypePredicate),
1491    Coerce(CoercePredicate),
1492    ConstEquate(TyConst, TyConst),
1493    Ambiguous,
1494    AliasRelate(TermKind, TermKind, AliasRelationDirection),
1495}
1496
1497#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1498pub enum ClauseKind {
1499    Trait(TraitPredicate),
1500    RegionOutlives(RegionOutlivesPredicate),
1501    TypeOutlives(TypeOutlivesPredicate),
1502    Projection(ProjectionPredicate),
1503    ConstArgHasType(TyConst, Ty),
1504    WellFormed(TermKind),
1505    ConstEvaluatable(TyConst),
1506}
1507
1508#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1509pub enum ClosureKind {
1510    Fn,
1511    FnMut,
1512    FnOnce,
1513}
1514
1515#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1516pub struct SubtypePredicate {
1517    pub a: Ty,
1518    pub b: Ty,
1519}
1520
1521#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1522pub struct CoercePredicate {
1523    pub a: Ty,
1524    pub b: Ty,
1525}
1526
1527#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1528pub enum AliasRelationDirection {
1529    Equate,
1530    Subtype,
1531}
1532
1533#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1534pub struct TraitPredicate {
1535    pub trait_ref: TraitRef,
1536    pub polarity: PredicatePolarity,
1537}
1538
1539#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1540pub struct OutlivesPredicate<A, B>(pub A, pub B);
1541
1542pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1543pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1544
1545#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1546pub struct ProjectionPredicate {
1547    pub projection_term: AliasTerm,
1548    pub term: TermKind,
1549}
1550
1551#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1552pub enum ImplPolarity {
1553    Positive,
1554    Negative,
1555    Reservation,
1556}
1557
1558#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1559pub enum PredicatePolarity {
1560    Positive,
1561    Negative,
1562}
1563
1564macro_rules! index_impl {
1565    ($name:ident) => {
1566        impl crate::IndexedVal for $name {
1567            fn to_val(index: usize) -> Self {
1568                $name(index)
1569            }
1570            fn to_index(&self) -> usize {
1571                self.0
1572            }
1573        }
1574    };
1575}
1576
1577index_impl!(TyConstId);
1578index_impl!(MirConstId);
1579index_impl!(Ty);
1580index_impl!(Span);
1581
1582/// The source-order index of a variant in a type.
1583///
1584/// For example, in the following types,
1585/// ```ignore(illustrative)
1586/// enum Demo1 {
1587///    Variant0 { a: bool, b: i32 },
1588///    Variant1 { c: u8, d: u64 },
1589/// }
1590/// struct Demo2 { e: u8, f: u16, g: u8 }
1591/// ```
1592/// `a` is in the variant with the `VariantIdx` of `0`,
1593/// `c` is in the variant with the `VariantIdx` of `1`, and
1594/// `g` is in the variant with the `VariantIdx` of `0`.
1595#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1596pub struct VariantIdx(usize);
1597
1598index_impl!(VariantIdx);
1599
1600crate_def! {
1601    /// Hold information about an Opaque definition, particularly useful in `RPITIT`.
1602    #[derive(Serialize)]
1603    pub OpaqueDef;
1604}
1605
1606crate_def! {
1607    #[derive(Serialize)]
1608    pub AssocDef;
1609}
1610
1611#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1612pub struct AssocItem {
1613    pub def_id: AssocDef,
1614    pub kind: AssocKind,
1615    pub container: AssocItemContainer,
1616
1617    /// If this is an item in an impl of a trait then this is the `DefId` of
1618    /// the associated item on the trait that this implements.
1619    pub trait_item_def_id: Option<AssocDef>,
1620}
1621
1622#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1623pub enum AssocTypeData {
1624    Normal(Symbol),
1625    /// The associated type comes from an RPITIT. It has no name, and the
1626    /// `ImplTraitInTraitData` provides additional information about its
1627    /// source.
1628    Rpitit(ImplTraitInTraitData),
1629}
1630
1631#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1632pub enum AssocKind {
1633    Const { name: Symbol },
1634    Fn { name: Symbol, has_self: bool },
1635    Type { data: AssocTypeData },
1636}
1637
1638#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1639pub enum AssocItemContainer {
1640    Trait,
1641    Impl,
1642}
1643
1644#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1645pub enum ImplTraitInTraitData {
1646    Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1647    Impl { fn_def_id: FnDef },
1648}
1649
1650impl AssocItem {
1651    pub fn is_impl_trait_in_trait(&self) -> bool {
1652        matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1653    }
1654}