stable_mir/
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, mov: Movability) -> Ty {
64        Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
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, 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, 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, Serialize)]
155pub struct TyConstId(usize);
156
157/// Represents a constant in MIR
158#[derive(Clone, Debug, Eq, PartialEq, 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, Serialize)]
216pub struct MirConstId(usize);
217
218type Ident = Opaque;
219
220#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
221pub struct Region {
222    pub kind: RegionKind,
223}
224
225#[derive(Clone, Debug, Eq, PartialEq, 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, 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, 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, Serialize)]
253pub struct Placeholder<T> {
254    pub universe: UniverseIndex,
255    pub bound: T,
256}
257
258#[derive(Clone, Copy, PartialEq, Eq, 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    // FIXME(stable_mir): Movability here is redundant
564    Coroutine(CoroutineDef, GenericArgs, Movability),
565    CoroutineClosure(CoroutineClosureDef, GenericArgs),
566    Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
567    Never,
568    Tuple(Vec<Ty>),
569    CoroutineWitness(CoroutineWitnessDef, GenericArgs),
570}
571
572impl RigidTy {
573    /// Get the discriminant type for this type.
574    pub fn discriminant_ty(&self) -> Ty {
575        with(|cx| cx.rigid_ty_discriminant_ty(self))
576    }
577}
578
579impl From<RigidTy> for TyKind {
580    fn from(value: RigidTy) -> Self {
581        TyKind::RigidTy(value)
582    }
583}
584
585#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
586pub enum IntTy {
587    Isize,
588    I8,
589    I16,
590    I32,
591    I64,
592    I128,
593}
594
595impl IntTy {
596    pub fn num_bytes(self) -> usize {
597        match self {
598            IntTy::Isize => MachineInfo::target_pointer_width().bytes(),
599            IntTy::I8 => 1,
600            IntTy::I16 => 2,
601            IntTy::I32 => 4,
602            IntTy::I64 => 8,
603            IntTy::I128 => 16,
604        }
605    }
606}
607
608#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
609pub enum UintTy {
610    Usize,
611    U8,
612    U16,
613    U32,
614    U64,
615    U128,
616}
617
618impl UintTy {
619    pub fn num_bytes(self) -> usize {
620        match self {
621            UintTy::Usize => MachineInfo::target_pointer_width().bytes(),
622            UintTy::U8 => 1,
623            UintTy::U16 => 2,
624            UintTy::U32 => 4,
625            UintTy::U64 => 8,
626            UintTy::U128 => 16,
627        }
628    }
629}
630
631#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
632pub enum FloatTy {
633    F16,
634    F32,
635    F64,
636    F128,
637}
638
639#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
640pub enum Movability {
641    Static,
642    Movable,
643}
644
645crate_def! {
646    #[derive(Serialize)]
647    pub ForeignModuleDef;
648}
649
650impl ForeignModuleDef {
651    pub fn module(&self) -> ForeignModule {
652        with(|cx| cx.foreign_module(*self))
653    }
654}
655
656pub struct ForeignModule {
657    pub def_id: ForeignModuleDef,
658    pub abi: Abi,
659}
660
661impl ForeignModule {
662    pub fn items(&self) -> Vec<ForeignDef> {
663        with(|cx| cx.foreign_items(self.def_id))
664    }
665}
666
667crate_def_with_ty! {
668    /// Hold information about a ForeignItem in a crate.
669    #[derive(Serialize)]
670    pub ForeignDef;
671}
672
673impl ForeignDef {
674    pub fn kind(&self) -> ForeignItemKind {
675        with(|cx| cx.foreign_item_kind(*self))
676    }
677}
678
679#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
680pub enum ForeignItemKind {
681    Fn(FnDef),
682    Static(StaticDef),
683    Type(Ty),
684}
685
686crate_def_with_ty! {
687    /// Hold information about a function definition in a crate.
688    #[derive(Serialize)]
689    pub FnDef;
690}
691
692impl FnDef {
693    // Get the function body if available.
694    pub fn body(&self) -> Option<Body> {
695        with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
696    }
697
698    // Check if the function body is available.
699    pub fn has_body(&self) -> bool {
700        with(|ctx| ctx.has_body(self.0))
701    }
702
703    /// Get the information of the intrinsic if this function is a definition of one.
704    pub fn as_intrinsic(&self) -> Option<IntrinsicDef> {
705        with(|cx| cx.intrinsic(self.def_id()))
706    }
707
708    /// Check if the function is an intrinsic.
709    #[inline]
710    pub fn is_intrinsic(&self) -> bool {
711        self.as_intrinsic().is_some()
712    }
713
714    /// Get the function signature for this function definition.
715    pub fn fn_sig(&self) -> PolyFnSig {
716        let kind = self.ty().kind();
717        kind.fn_sig().unwrap()
718    }
719}
720
721crate_def_with_ty! {
722    #[derive(Serialize)]
723    pub IntrinsicDef;
724}
725
726impl IntrinsicDef {
727    /// Returns the plain name of the intrinsic.
728    /// e.g., `transmute` for `core::intrinsics::transmute`.
729    pub fn fn_name(&self) -> Symbol {
730        with(|cx| cx.intrinsic_name(*self))
731    }
732
733    /// Returns whether the intrinsic has no meaningful body and all backends
734    /// need to shim all calls to it.
735    pub fn must_be_overridden(&self) -> bool {
736        with(|cx| !cx.has_body(self.0))
737    }
738}
739
740impl From<IntrinsicDef> for FnDef {
741    fn from(def: IntrinsicDef) -> Self {
742        FnDef(def.0)
743    }
744}
745
746crate_def! {
747    #[derive(Serialize)]
748    pub ClosureDef;
749}
750
751impl ClosureDef {
752    /// Retrieves the body of the closure definition. Returns None if the body
753    /// isn't available.
754    pub fn body(&self) -> Option<Body> {
755        with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
756    }
757}
758
759crate_def! {
760    #[derive(Serialize)]
761    pub CoroutineDef;
762}
763
764impl CoroutineDef {
765    /// Retrieves the body of the coroutine definition. Returns None if the body
766    /// isn't available.
767    pub fn body(&self) -> Option<Body> {
768        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
769    }
770
771    pub fn discriminant_for_variant(&self, args: &GenericArgs, idx: VariantIdx) -> Discr {
772        with(|cx| cx.coroutine_discr_for_variant(*self, args, idx))
773    }
774}
775
776crate_def! {
777    #[derive(Serialize)]
778    pub CoroutineClosureDef;
779}
780
781crate_def! {
782    #[derive(Serialize)]
783    pub ParamDef;
784}
785
786crate_def! {
787    #[derive(Serialize)]
788    pub BrNamedDef;
789}
790
791crate_def! {
792    #[derive(Serialize)]
793    pub AdtDef;
794}
795
796#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
797pub enum AdtKind {
798    Enum,
799    Union,
800    Struct,
801}
802
803impl AdtDef {
804    pub fn kind(&self) -> AdtKind {
805        with(|cx| cx.adt_kind(*self))
806    }
807
808    /// Retrieve the type of this Adt.
809    pub fn ty(&self) -> Ty {
810        with(|cx| cx.def_ty(self.0))
811    }
812
813    /// Retrieve the type of this Adt by instantiating and normalizing it with the given arguments.
814    ///
815    /// This will assume the type can be instantiated with these arguments.
816    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
817        with(|cx| cx.def_ty_with_args(self.0, args))
818    }
819
820    pub fn is_box(&self) -> bool {
821        with(|cx| cx.adt_is_box(*self))
822    }
823
824    pub fn is_simd(&self) -> bool {
825        with(|cx| cx.adt_is_simd(*self))
826    }
827
828    /// The number of variants in this ADT.
829    pub fn num_variants(&self) -> usize {
830        with(|cx| cx.adt_variants_len(*self))
831    }
832
833    /// Retrieve the variants in this ADT.
834    pub fn variants(&self) -> Vec<VariantDef> {
835        self.variants_iter().collect()
836    }
837
838    /// Iterate over the variants in this ADT.
839    pub fn variants_iter(&self) -> impl Iterator<Item = VariantDef> {
840        (0..self.num_variants())
841            .map(|idx| VariantDef { idx: VariantIdx::to_val(idx), adt_def: *self })
842    }
843
844    pub fn variant(&self, idx: VariantIdx) -> Option<VariantDef> {
845        (idx.to_index() < self.num_variants()).then_some(VariantDef { idx, adt_def: *self })
846    }
847
848    pub fn repr(&self) -> ReprOptions {
849        with(|cx| cx.adt_repr(*self))
850    }
851
852    pub fn discriminant_for_variant(&self, idx: VariantIdx) -> Discr {
853        with(|cx| cx.adt_discr_for_variant(*self, idx))
854    }
855}
856
857pub struct Discr {
858    pub val: u128,
859    pub ty: Ty,
860}
861
862/// Definition of a variant, which can be either a struct / union field or an enum variant.
863#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
864pub struct VariantDef {
865    /// The variant index.
866    ///
867    /// ## Warning
868    /// Do not access this field directly!
869    pub idx: VariantIdx,
870    /// The data type where this variant comes from.
871    /// For now, we use this to retrieve information about the variant itself so we don't need to
872    /// cache more information.
873    ///
874    /// ## Warning
875    /// Do not access this field directly!
876    pub adt_def: AdtDef,
877}
878
879impl VariantDef {
880    pub fn name(&self) -> Symbol {
881        with(|cx| cx.variant_name(*self))
882    }
883
884    /// Retrieve all the fields in this variant.
885    // We expect user to cache this and use it directly since today it is expensive to generate all
886    // fields name.
887    pub fn fields(&self) -> Vec<FieldDef> {
888        with(|cx| cx.variant_fields(*self))
889    }
890}
891
892#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
893pub struct FieldDef {
894    /// The field definition.
895    ///
896    /// ## Warning
897    /// Do not access this field directly! This is public for the compiler to have access to it.
898    pub def: DefId,
899
900    /// The field name.
901    pub name: Symbol,
902}
903
904impl FieldDef {
905    /// Retrieve the type of this field instantiating and normalizing it with the given arguments.
906    ///
907    /// This will assume the type can be instantiated with these arguments.
908    pub fn ty_with_args(&self, args: &GenericArgs) -> Ty {
909        with(|cx| cx.def_ty_with_args(self.def, args))
910    }
911
912    /// Retrieve the type of this field.
913    pub fn ty(&self) -> Ty {
914        with(|cx| cx.def_ty(self.def))
915    }
916}
917
918impl Display for AdtKind {
919    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
920        f.write_str(match self {
921            AdtKind::Enum => "enum",
922            AdtKind::Union => "union",
923            AdtKind::Struct => "struct",
924        })
925    }
926}
927
928impl AdtKind {
929    pub fn is_enum(&self) -> bool {
930        matches!(self, AdtKind::Enum)
931    }
932
933    pub fn is_struct(&self) -> bool {
934        matches!(self, AdtKind::Struct)
935    }
936
937    pub fn is_union(&self) -> bool {
938        matches!(self, AdtKind::Union)
939    }
940}
941
942crate_def! {
943    #[derive(Serialize)]
944    pub AliasDef;
945}
946
947crate_def! {
948    /// A trait's definition.
949    #[derive(Serialize)]
950    pub TraitDef;
951}
952
953impl_crate_def_items! {
954    TraitDef;
955}
956
957impl TraitDef {
958    pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
959        with(|cx| cx.trait_decl(trait_def))
960    }
961}
962
963crate_def! {
964    #[derive(Serialize)]
965    pub GenericDef;
966}
967
968crate_def_with_ty! {
969    #[derive(Serialize)]
970    pub ConstDef;
971}
972
973crate_def! {
974    /// A trait impl definition.
975    #[derive(Serialize)]
976    pub ImplDef;
977}
978
979impl_crate_def_items! {
980    ImplDef;
981}
982
983impl ImplDef {
984    /// Retrieve information about this implementation.
985    pub fn trait_impl(&self) -> ImplTrait {
986        with(|cx| cx.trait_impl(self))
987    }
988}
989
990crate_def! {
991    #[derive(Serialize)]
992    pub RegionDef;
993}
994
995crate_def! {
996    #[derive(Serialize)]
997    pub CoroutineWitnessDef;
998}
999
1000/// A list of generic arguments.
1001#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1002pub struct GenericArgs(pub Vec<GenericArgKind>);
1003
1004impl std::ops::Index<ParamTy> for GenericArgs {
1005    type Output = Ty;
1006
1007    fn index(&self, index: ParamTy) -> &Self::Output {
1008        self.0[index.index as usize].expect_ty()
1009    }
1010}
1011
1012impl std::ops::Index<ParamConst> for GenericArgs {
1013    type Output = TyConst;
1014
1015    fn index(&self, index: ParamConst) -> &Self::Output {
1016        self.0[index.index as usize].expect_const()
1017    }
1018}
1019
1020#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1021pub enum GenericArgKind {
1022    Lifetime(Region),
1023    Type(Ty),
1024    Const(TyConst),
1025}
1026
1027impl GenericArgKind {
1028    /// Panic if this generic argument is not a type, otherwise
1029    /// return the type.
1030    #[track_caller]
1031    pub fn expect_ty(&self) -> &Ty {
1032        match self {
1033            GenericArgKind::Type(ty) => ty,
1034            _ => panic!("{self:?}"),
1035        }
1036    }
1037
1038    /// Panic if this generic argument is not a const, otherwise
1039    /// return the const.
1040    #[track_caller]
1041    pub fn expect_const(&self) -> &TyConst {
1042        match self {
1043            GenericArgKind::Const(c) => c,
1044            _ => panic!("{self:?}"),
1045        }
1046    }
1047
1048    /// Return the generic argument type if applicable, otherwise return `None`.
1049    pub fn ty(&self) -> Option<&Ty> {
1050        match self {
1051            GenericArgKind::Type(ty) => Some(ty),
1052            _ => None,
1053        }
1054    }
1055}
1056
1057#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1058pub enum TermKind {
1059    Type(Ty),
1060    Const(TyConst),
1061}
1062
1063#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1064pub enum AliasKind {
1065    Projection,
1066    Inherent,
1067    Opaque,
1068    Free,
1069}
1070
1071#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1072pub struct AliasTy {
1073    pub def_id: AliasDef,
1074    pub args: GenericArgs,
1075}
1076
1077#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1078pub struct AliasTerm {
1079    pub def_id: AliasDef,
1080    pub args: GenericArgs,
1081}
1082
1083pub type PolyFnSig = Binder<FnSig>;
1084
1085impl PolyFnSig {
1086    /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers.
1087    ///
1088    /// NB: this doesn't handle virtual calls - those should use `Instance::fn_abi`
1089    /// instead, where the instance is an `InstanceKind::Virtual`.
1090    pub fn fn_ptr_abi(self) -> Result<FnAbi, Error> {
1091        with(|cx| cx.fn_ptr_abi(self))
1092    }
1093}
1094
1095#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1096pub struct FnSig {
1097    pub inputs_and_output: Vec<Ty>,
1098    pub c_variadic: bool,
1099    pub safety: Safety,
1100    pub abi: Abi,
1101}
1102
1103impl FnSig {
1104    pub fn output(&self) -> Ty {
1105        self.inputs_and_output[self.inputs_and_output.len() - 1]
1106    }
1107
1108    pub fn inputs(&self) -> &[Ty] {
1109        &self.inputs_and_output[..self.inputs_and_output.len() - 1]
1110    }
1111}
1112
1113#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1114pub enum Abi {
1115    Rust,
1116    C { unwind: bool },
1117    Cdecl { unwind: bool },
1118    Stdcall { unwind: bool },
1119    Fastcall { unwind: bool },
1120    Vectorcall { unwind: bool },
1121    Thiscall { unwind: bool },
1122    Aapcs { unwind: bool },
1123    Win64 { unwind: bool },
1124    SysV64 { unwind: bool },
1125    PtxKernel,
1126    Msp430Interrupt,
1127    X86Interrupt,
1128    GpuKernel,
1129    EfiApi,
1130    AvrInterrupt,
1131    AvrNonBlockingInterrupt,
1132    CCmseNonSecureCall,
1133    CCmseNonSecureEntry,
1134    System { unwind: bool },
1135    RustCall,
1136    Unadjusted,
1137    RustCold,
1138    RiscvInterruptM,
1139    RiscvInterruptS,
1140    RustInvalid,
1141    Custom,
1142}
1143
1144/// A binder represents a possibly generic type and its bound vars.
1145#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1146pub struct Binder<T> {
1147    pub value: T,
1148    pub bound_vars: Vec<BoundVariableKind>,
1149}
1150
1151impl<T> Binder<T> {
1152    /// Create a new binder with the given bound vars.
1153    pub fn bind_with_vars(value: T, bound_vars: Vec<BoundVariableKind>) -> Self {
1154        Binder { value, bound_vars }
1155    }
1156
1157    /// Create a new binder with no bounded variable.
1158    pub fn dummy(value: T) -> Self {
1159        Binder { value, bound_vars: vec![] }
1160    }
1161
1162    pub fn skip_binder(self) -> T {
1163        self.value
1164    }
1165
1166    pub fn map_bound_ref<F, U>(&self, f: F) -> Binder<U>
1167    where
1168        F: FnOnce(&T) -> U,
1169    {
1170        let Binder { value, bound_vars } = self;
1171        let new_value = f(value);
1172        Binder { value: new_value, bound_vars: bound_vars.clone() }
1173    }
1174
1175    pub fn map_bound<F, U>(self, f: F) -> Binder<U>
1176    where
1177        F: FnOnce(T) -> U,
1178    {
1179        let Binder { value, bound_vars } = self;
1180        let new_value = f(value);
1181        Binder { value: new_value, bound_vars }
1182    }
1183}
1184
1185#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1186pub struct EarlyBinder<T> {
1187    pub value: T,
1188}
1189
1190#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1191pub enum BoundVariableKind {
1192    Ty(BoundTyKind),
1193    Region(BoundRegionKind),
1194    Const,
1195}
1196
1197#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
1198pub enum BoundTyKind {
1199    Anon,
1200    Param(ParamDef, String),
1201}
1202
1203#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1204pub enum BoundRegionKind {
1205    BrAnon,
1206    BrNamed(BrNamedDef, String),
1207    BrEnv,
1208}
1209
1210#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1211pub enum DynKind {
1212    Dyn,
1213}
1214
1215#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1216pub enum ExistentialPredicate {
1217    Trait(ExistentialTraitRef),
1218    Projection(ExistentialProjection),
1219    AutoTrait(TraitDef),
1220}
1221
1222/// An existential reference to a trait where `Self` is not included.
1223///
1224/// The `generic_args` will include any other known argument.
1225#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1226pub struct ExistentialTraitRef {
1227    pub def_id: TraitDef,
1228    pub generic_args: GenericArgs,
1229}
1230
1231impl Binder<ExistentialTraitRef> {
1232    pub fn with_self_ty(&self, self_ty: Ty) -> Binder<TraitRef> {
1233        self.map_bound_ref(|trait_ref| trait_ref.with_self_ty(self_ty))
1234    }
1235}
1236
1237impl ExistentialTraitRef {
1238    pub fn with_self_ty(&self, self_ty: Ty) -> TraitRef {
1239        TraitRef::new(self.def_id, self_ty, &self.generic_args)
1240    }
1241}
1242
1243#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1244pub struct ExistentialProjection {
1245    pub def_id: TraitDef,
1246    pub generic_args: GenericArgs,
1247    pub term: TermKind,
1248}
1249
1250#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1251pub struct ParamTy {
1252    pub index: u32,
1253    pub name: String,
1254}
1255
1256#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1257pub struct BoundTy {
1258    pub var: usize,
1259    pub kind: BoundTyKind,
1260}
1261
1262pub type Bytes = Vec<Option<u8>>;
1263
1264/// Size in bytes.
1265pub type Size = usize;
1266
1267#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1268pub struct Prov(pub AllocId);
1269
1270pub type Align = u64;
1271pub type Promoted = u32;
1272pub type InitMaskMaterialized = Vec<u64>;
1273
1274/// Stores the provenance information of pointers stored in memory.
1275#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1276pub struct ProvenanceMap {
1277    /// Provenance in this map applies from the given offset for an entire pointer-size worth of
1278    /// bytes. Two entries in this map are always at least a pointer size apart.
1279    pub ptrs: Vec<(Size, Prov)>,
1280}
1281
1282#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
1283pub struct Allocation {
1284    pub bytes: Bytes,
1285    pub provenance: ProvenanceMap,
1286    pub align: Align,
1287    pub mutability: Mutability,
1288}
1289
1290impl Allocation {
1291    /// Get a vector of bytes for an Allocation that has been fully initialized
1292    pub fn raw_bytes(&self) -> Result<Vec<u8>, Error> {
1293        self.bytes
1294            .iter()
1295            .copied()
1296            .collect::<Option<Vec<_>>>()
1297            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))
1298    }
1299
1300    /// Read a uint value from the specified range.
1301    pub fn read_partial_uint(&self, range: Range<usize>) -> Result<u128, Error> {
1302        if range.end - range.start > 16 {
1303            return Err(error!("Allocation is bigger than largest integer"));
1304        }
1305        if range.end > self.bytes.len() {
1306            return Err(error!(
1307                "Range is out of bounds. Allocation length is `{}`, but requested range `{:?}`",
1308                self.bytes.len(),
1309                range
1310            ));
1311        }
1312        let raw = self.bytes[range]
1313            .iter()
1314            .copied()
1315            .collect::<Option<Vec<_>>>()
1316            .ok_or_else(|| error!("Found uninitialized bytes: `{:?}`", self.bytes))?;
1317        read_target_uint(&raw)
1318    }
1319
1320    /// Read this allocation and try to convert it to an unassigned integer.
1321    pub fn read_uint(&self) -> Result<u128, Error> {
1322        if self.bytes.len() > 16 {
1323            return Err(error!("Allocation is bigger than largest integer"));
1324        }
1325        let raw = self.raw_bytes()?;
1326        read_target_uint(&raw)
1327    }
1328
1329    /// Read this allocation and try to convert it to a signed integer.
1330    pub fn read_int(&self) -> Result<i128, Error> {
1331        if self.bytes.len() > 16 {
1332            return Err(error!("Allocation is bigger than largest integer"));
1333        }
1334        let raw = self.raw_bytes()?;
1335        read_target_int(&raw)
1336    }
1337
1338    /// Read this allocation and try to convert it to a boolean.
1339    pub fn read_bool(&self) -> Result<bool, Error> {
1340        match self.read_int()? {
1341            0 => Ok(false),
1342            1 => Ok(true),
1343            val => Err(error!("Unexpected value for bool: `{val}`")),
1344        }
1345    }
1346
1347    /// Read this allocation as a pointer and return whether it represents a `null` pointer.
1348    pub fn is_null(&self) -> Result<bool, Error> {
1349        let len = self.bytes.len();
1350        let ptr_len = MachineInfo::target_pointer_width().bytes();
1351        if len != ptr_len {
1352            return Err(error!("Expected width of pointer (`{ptr_len}`), but found: `{len}`"));
1353        }
1354        Ok(self.read_uint()? == 0 && self.provenance.ptrs.is_empty())
1355    }
1356}
1357
1358#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1359pub enum ConstantKind {
1360    Ty(TyConst),
1361    Allocated(Allocation),
1362    Unevaluated(UnevaluatedConst),
1363    Param(ParamConst),
1364    /// Store ZST constants.
1365    /// We have to special handle these constants since its type might be generic.
1366    ZeroSized,
1367}
1368
1369#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1370pub struct ParamConst {
1371    pub index: u32,
1372    pub name: String,
1373}
1374
1375#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1376pub struct UnevaluatedConst {
1377    pub def: ConstDef,
1378    pub args: GenericArgs,
1379    pub promoted: Option<Promoted>,
1380}
1381
1382#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
1383pub enum TraitSpecializationKind {
1384    None,
1385    Marker,
1386    AlwaysApplicable,
1387}
1388
1389#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1390pub struct TraitDecl {
1391    pub def_id: TraitDef,
1392    pub safety: Safety,
1393    pub paren_sugar: bool,
1394    pub has_auto_impl: bool,
1395    pub is_marker: bool,
1396    pub is_coinductive: bool,
1397    pub skip_array_during_method_dispatch: bool,
1398    pub skip_boxed_slice_during_method_dispatch: bool,
1399    pub specialization_kind: TraitSpecializationKind,
1400    pub must_implement_one_of: Option<Vec<Ident>>,
1401    pub implement_via_object: bool,
1402    pub deny_explicit_impl: bool,
1403}
1404
1405impl TraitDecl {
1406    pub fn generics_of(&self) -> Generics {
1407        with(|cx| cx.generics_of(self.def_id.0))
1408    }
1409
1410    pub fn predicates_of(&self) -> GenericPredicates {
1411        with(|cx| cx.predicates_of(self.def_id.0))
1412    }
1413
1414    pub fn explicit_predicates_of(&self) -> GenericPredicates {
1415        with(|cx| cx.explicit_predicates_of(self.def_id.0))
1416    }
1417}
1418
1419pub type ImplTrait = EarlyBinder<TraitRef>;
1420
1421/// A complete reference to a trait, i.e., one where `Self` is known.
1422#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1423pub struct TraitRef {
1424    pub def_id: TraitDef,
1425    /// The generic arguments for this definition.
1426    /// The first element must always be type, and it represents `Self`.
1427    args: GenericArgs,
1428}
1429
1430impl TraitRef {
1431    pub fn new(def_id: TraitDef, self_ty: Ty, gen_args: &GenericArgs) -> TraitRef {
1432        let mut args = vec![GenericArgKind::Type(self_ty)];
1433        args.extend_from_slice(&gen_args.0);
1434        TraitRef { def_id, args: GenericArgs(args) }
1435    }
1436
1437    pub fn try_new(def_id: TraitDef, args: GenericArgs) -> Result<TraitRef, ()> {
1438        match &args.0[..] {
1439            [GenericArgKind::Type(_), ..] => Ok(TraitRef { def_id, args }),
1440            _ => Err(()),
1441        }
1442    }
1443
1444    pub fn args(&self) -> &GenericArgs {
1445        &self.args
1446    }
1447
1448    pub fn self_ty(&self) -> Ty {
1449        let GenericArgKind::Type(self_ty) = self.args.0[0] else {
1450            panic!("Self must be a type, but found: {:?}", self.args.0[0])
1451        };
1452        self_ty
1453    }
1454}
1455
1456#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1457pub struct Generics {
1458    pub parent: Option<GenericDef>,
1459    pub parent_count: usize,
1460    pub params: Vec<GenericParamDef>,
1461    pub param_def_id_to_index: Vec<(GenericDef, u32)>,
1462    pub has_self: bool,
1463    pub has_late_bound_regions: Option<Span>,
1464}
1465
1466#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1467pub enum GenericParamDefKind {
1468    Lifetime,
1469    Type { has_default: bool, synthetic: bool },
1470    Const { has_default: bool },
1471}
1472
1473#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1474pub struct GenericParamDef {
1475    pub name: super::Symbol,
1476    pub def_id: GenericDef,
1477    pub index: u32,
1478    pub pure_wrt_drop: bool,
1479    pub kind: GenericParamDefKind,
1480}
1481
1482pub struct GenericPredicates {
1483    pub parent: Option<TraitDef>,
1484    pub predicates: Vec<(PredicateKind, Span)>,
1485}
1486
1487#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1488pub enum PredicateKind {
1489    Clause(ClauseKind),
1490    DynCompatible(TraitDef),
1491    SubType(SubtypePredicate),
1492    Coerce(CoercePredicate),
1493    ConstEquate(TyConst, TyConst),
1494    Ambiguous,
1495    AliasRelate(TermKind, TermKind, AliasRelationDirection),
1496}
1497
1498#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1499pub enum ClauseKind {
1500    Trait(TraitPredicate),
1501    RegionOutlives(RegionOutlivesPredicate),
1502    TypeOutlives(TypeOutlivesPredicate),
1503    Projection(ProjectionPredicate),
1504    ConstArgHasType(TyConst, Ty),
1505    WellFormed(TermKind),
1506    ConstEvaluatable(TyConst),
1507}
1508
1509#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1510pub enum ClosureKind {
1511    Fn,
1512    FnMut,
1513    FnOnce,
1514}
1515
1516#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1517pub struct SubtypePredicate {
1518    pub a: Ty,
1519    pub b: Ty,
1520}
1521
1522#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1523pub struct CoercePredicate {
1524    pub a: Ty,
1525    pub b: Ty,
1526}
1527
1528#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1529pub enum AliasRelationDirection {
1530    Equate,
1531    Subtype,
1532}
1533
1534#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1535pub struct TraitPredicate {
1536    pub trait_ref: TraitRef,
1537    pub polarity: PredicatePolarity,
1538}
1539
1540#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1541pub struct OutlivesPredicate<A, B>(pub A, pub B);
1542
1543pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
1544pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
1545
1546#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1547pub struct ProjectionPredicate {
1548    pub projection_term: AliasTerm,
1549    pub term: TermKind,
1550}
1551
1552#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1553pub enum ImplPolarity {
1554    Positive,
1555    Negative,
1556    Reservation,
1557}
1558
1559#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1560pub enum PredicatePolarity {
1561    Positive,
1562    Negative,
1563}
1564
1565macro_rules! index_impl {
1566    ($name:ident) => {
1567        impl crate::IndexedVal for $name {
1568            fn to_val(index: usize) -> Self {
1569                $name(index)
1570            }
1571            fn to_index(&self) -> usize {
1572                self.0
1573            }
1574        }
1575    };
1576}
1577
1578index_impl!(TyConstId);
1579index_impl!(MirConstId);
1580index_impl!(Ty);
1581index_impl!(Span);
1582
1583/// The source-order index of a variant in a type.
1584///
1585/// For example, in the following types,
1586/// ```ignore(illustrative)
1587/// enum Demo1 {
1588///    Variant0 { a: bool, b: i32 },
1589///    Variant1 { c: u8, d: u64 },
1590/// }
1591/// struct Demo2 { e: u8, f: u16, g: u8 }
1592/// ```
1593/// `a` is in the variant with the `VariantIdx` of `0`,
1594/// `c` is in the variant with the `VariantIdx` of `1`, and
1595/// `g` is in the variant with the `VariantIdx` of `0`.
1596#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
1597pub struct VariantIdx(usize);
1598
1599index_impl!(VariantIdx);
1600
1601crate_def! {
1602    /// Hold information about an Opaque definition, particularly useful in `RPITIT`.
1603    #[derive(Serialize)]
1604    pub OpaqueDef;
1605}
1606
1607crate_def! {
1608    #[derive(Serialize)]
1609    pub AssocDef;
1610}
1611
1612#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1613pub struct AssocItem {
1614    pub def_id: AssocDef,
1615    pub kind: AssocKind,
1616    pub container: AssocItemContainer,
1617
1618    /// If this is an item in an impl of a trait then this is the `DefId` of
1619    /// the associated item on the trait that this implements.
1620    pub trait_item_def_id: Option<AssocDef>,
1621}
1622
1623#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
1624pub enum AssocTypeData {
1625    Normal(Symbol),
1626    /// The associated type comes from an RPITIT. It has no name, and the
1627    /// `ImplTraitInTraitData` provides additional information about its
1628    /// source.
1629    Rpitit(ImplTraitInTraitData),
1630}
1631
1632#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1633pub enum AssocKind {
1634    Const { name: Symbol },
1635    Fn { name: Symbol, has_self: bool },
1636    Type { data: AssocTypeData },
1637}
1638
1639#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
1640pub enum AssocItemContainer {
1641    Trait,
1642    Impl,
1643}
1644
1645#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
1646pub enum ImplTraitInTraitData {
1647    Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
1648    Impl { fn_def_id: FnDef },
1649}
1650
1651impl AssocItem {
1652    pub fn is_impl_trait_in_trait(&self) -> bool {
1653        matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
1654    }
1655}