rustc_smir/stable_mir/
ty.rs

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