rustc_type_ir/
ty_kind.rs

1use std::fmt;
2use std::ops::Deref;
3
4use derive_where::derive_where;
5use rustc_ast_ir::Mutability;
6#[cfg(feature = "nightly")]
7use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8#[cfg(feature = "nightly")]
9use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue};
10#[cfg(feature = "nightly")]
11use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
12use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
13
14use self::TyKind::*;
15pub use self::closure::*;
16use crate::inherent::*;
17#[cfg(feature = "nightly")]
18use crate::visit::TypeVisitable;
19use crate::{self as ty, DebruijnIndex, Interner};
20
21mod closure;
22
23/// Specifies how a trait object is represented.
24#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
25#[cfg_attr(
26    feature = "nightly",
27    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
28)]
29pub enum DynKind {
30    /// An unsized `dyn Trait` object
31    Dyn,
32    /// A sized `dyn* Trait` object
33    ///
34    /// These objects are represented as a `(data, vtable)` pair where `data` is a value of some
35    /// ptr-sized and ptr-aligned dynamically determined type `T` and `vtable` is a pointer to the
36    /// vtable of `impl T for Trait`. This allows a `dyn*` object to be treated agnostically with
37    /// respect to whether it points to a `Box<T>`, `Rc<T>`, etc.
38    DynStar,
39}
40
41#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
42#[cfg_attr(
43    feature = "nightly",
44    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
45)]
46pub enum AliasTyKind {
47    /// A projection `<Type as Trait>::AssocType`.
48    /// Can get normalized away if monomorphic enough.
49    Projection,
50    /// An associated type in an inherent `impl`
51    Inherent,
52    /// An opaque type (usually from `impl Trait` in type aliases or function return types)
53    /// Can only be normalized away in PostAnalysis mode or its defining scope.
54    Opaque,
55    /// A type alias that actually checks its trait bounds.
56    /// Currently only used if the type alias references opaque types.
57    /// Can always be normalized away.
58    Weak,
59}
60
61impl AliasTyKind {
62    pub fn descr(self) -> &'static str {
63        match self {
64            AliasTyKind::Projection => "associated type",
65            AliasTyKind::Inherent => "inherent associated type",
66            AliasTyKind::Opaque => "opaque type",
67            AliasTyKind::Weak => "type alias",
68        }
69    }
70}
71
72/// Defines the kinds of types used by the type system.
73///
74/// Types written by the user start out as `hir::TyKind` and get
75/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
76#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
77#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
78#[cfg_attr(
79    feature = "nightly",
80    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
81)]
82pub enum TyKind<I: Interner> {
83    /// The primitive boolean type. Written as `bool`.
84    Bool,
85
86    /// The primitive character type; holds a Unicode scalar value
87    /// (a non-surrogate code point). Written as `char`.
88    Char,
89
90    /// A primitive signed integer type. For example, `i32`.
91    Int(IntTy),
92
93    /// A primitive unsigned integer type. For example, `u32`.
94    Uint(UintTy),
95
96    /// A primitive floating-point type. For example, `f64`.
97    Float(FloatTy),
98
99    /// Algebraic data types (ADT). For example: structures, enumerations and unions.
100    ///
101    /// For example, the type `List<i32>` would be represented using the `AdtDef`
102    /// for `struct List<T>` and the args `[i32]`.
103    ///
104    /// Note that generic parameters in fields only get lazily instantiated
105    /// by using something like `adt_def.all_fields().map(|field| field.ty(interner, args))`.
106    Adt(I::AdtDef, I::GenericArgs),
107
108    /// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
109    Foreign(I::DefId),
110
111    /// The pointee of a string slice. Written as `str`.
112    Str,
113
114    /// An array with the given length. Written as `[T; N]`.
115    Array(I::Ty, I::Const),
116
117    /// A pattern newtype. Takes any type and restricts its valid values to its pattern.
118    /// This will also change the layout to take advantage of this restriction.
119    /// Only `Copy` and `Clone` will automatically get implemented for pattern types.
120    /// Auto-traits treat this as if it were an aggregate with a single nested type.
121    /// Only supports integer range patterns for now.
122    Pat(I::Ty, I::Pat),
123
124    /// The pointee of an array slice. Written as `[T]`.
125    Slice(I::Ty),
126
127    /// A raw pointer. Written as `*mut T` or `*const T`
128    RawPtr(I::Ty, Mutability),
129
130    /// A reference; a pointer with an associated lifetime. Written as
131    /// `&'a mut T` or `&'a T`.
132    Ref(I::Region, I::Ty, Mutability),
133
134    /// The anonymous type of a function declaration/definition. Each
135    /// function has a unique type.
136    ///
137    /// For the function `fn foo() -> i32 { 3 }` this type would be
138    /// shown to the user as `fn() -> i32 {foo}`.
139    ///
140    /// For example the type of `bar` here:
141    /// ```rust
142    /// fn foo() -> i32 { 1 }
143    /// let bar = foo; // bar: fn() -> i32 {foo}
144    /// ```
145    FnDef(I::DefId, I::GenericArgs),
146
147    /// A pointer to a function. Written as `fn() -> i32`.
148    ///
149    /// Note that both functions and closures start out as either
150    /// [FnDef] or [Closure] which can be then be coerced to this variant.
151    ///
152    /// For example the type of `bar` here:
153    ///
154    /// ```rust
155    /// fn foo() -> i32 { 1 }
156    /// let bar: fn() -> i32 = foo;
157    /// ```
158    ///
159    /// These two fields are equivalent to a `ty::Binder<I, FnSig<I>>`. But by
160    /// splitting that into two pieces, we get a more compact data layout that
161    /// reduces the size of `TyKind` by 8 bytes. It is a very hot type, so it's
162    /// worth the mild inconvenience.
163    FnPtr(ty::Binder<I, FnSigTys<I>>, FnHeader<I>),
164
165    /// An unsafe binder type.
166    ///
167    /// A higher-ranked type used to represent a type which has had some of its
168    /// lifetimes erased. This can be used to represent types in positions where
169    /// a lifetime is literally inexpressible, such as self-referential types.
170    UnsafeBinder(UnsafeBinderInner<I>),
171
172    /// A trait object. Written as `dyn for<'b> Trait<'b, Assoc = u32> + Send + 'a`.
173    Dynamic(I::BoundExistentialPredicates, I::Region, DynKind),
174
175    /// The anonymous type of a closure. Used to represent the type of `|a| a`.
176    ///
177    /// Closure args contain both the - potentially instantiated - generic parameters
178    /// of its parent and some synthetic parameters. See the documentation for
179    /// `ClosureArgs` for more details.
180    Closure(I::DefId, I::GenericArgs),
181
182    /// The anonymous type of a closure. Used to represent the type of `async |a| a`.
183    ///
184    /// Coroutine-closure args contain both the - potentially instantiated - generic
185    /// parameters of its parent and some synthetic parameters. See the documentation
186    /// for `CoroutineClosureArgs` for more details.
187    CoroutineClosure(I::DefId, I::GenericArgs),
188
189    /// The anonymous type of a coroutine. Used to represent the type of
190    /// `|a| yield a`.
191    ///
192    /// For more info about coroutine args, visit the documentation for
193    /// `CoroutineArgs`.
194    Coroutine(I::DefId, I::GenericArgs),
195
196    /// A type representing the types stored inside a coroutine.
197    /// This should only appear as part of the `CoroutineArgs`.
198    ///
199    /// Unlike upvars, the witness can reference lifetimes from
200    /// inside of the coroutine itself. To deal with them in
201    /// the type of the coroutine, we convert them to higher ranked
202    /// lifetimes bound by the witness itself.
203    ///
204    /// This contains the `DefId` and the `GenericArgsRef` of the coroutine.
205    /// The actual witness types are computed on MIR by the `mir_coroutine_witnesses` query.
206    ///
207    /// Looking at the following example, the witness for this coroutine
208    /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
209    ///
210    /// ```
211    /// #![feature(coroutines)]
212    /// #[coroutine] static |a| {
213    ///     let x = &vec![3];
214    ///     yield a;
215    ///     yield x[0];
216    /// }
217    /// # ;
218    /// ```
219    CoroutineWitness(I::DefId, I::GenericArgs),
220
221    /// The never type `!`.
222    Never,
223
224    /// A tuple type. For example, `(i32, bool)`.
225    Tuple(I::Tys),
226
227    /// A projection, opaque type, weak type alias, or inherent associated type.
228    /// All of these types are represented as pairs of def-id and args, and can
229    /// be normalized, so they are grouped conceptually.
230    Alias(AliasTyKind, AliasTy<I>),
231
232    /// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
233    Param(I::ParamTy),
234
235    /// Bound type variable, used to represent the `'a` in `for<'a> fn(&'a ())`.
236    ///
237    /// For canonical queries, we replace inference variables with bound variables,
238    /// so e.g. when checking whether `&'_ (): Trait<_>` holds, we canonicalize that to
239    /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables
240    /// back to inference variables in a new inference context when inside of the query.
241    ///
242    /// It is conventional to render anonymous bound types like `^N` or `^D_N`,
243    /// where `N` is the bound variable's anonymous index into the binder, and
244    /// `D` is the debruijn index, or totally omitted if the debruijn index is zero.
245    ///
246    /// See the `rustc-dev-guide` for more details about
247    /// [higher-ranked trait bounds][1] and [canonical queries][2].
248    ///
249    /// [1]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
250    /// [2]: https://rustc-dev-guide.rust-lang.org/traits/canonical-queries.html
251    Bound(DebruijnIndex, I::BoundTy),
252
253    /// A placeholder type, used during higher ranked subtyping to instantiate
254    /// bound variables.
255    ///
256    /// It is conventional to render anonymous placeholder types like `!N` or `!U_N`,
257    /// where `N` is the placeholder variable's anonymous index (which corresponds
258    /// to the bound variable's index from the binder from which it was instantiated),
259    /// and `U` is the universe index in which it is instantiated, or totally omitted
260    /// if the universe index is zero.
261    Placeholder(I::PlaceholderTy),
262
263    /// A type variable used during type checking.
264    ///
265    /// Similar to placeholders, inference variables also live in a universe to
266    /// correctly deal with higher ranked types. Though unlike placeholders,
267    /// that universe is stored in the `InferCtxt` instead of directly
268    /// inside of the type.
269    Infer(InferTy),
270
271    /// A placeholder for a type which could not be computed; this is
272    /// propagated to avoid useless error messages.
273    Error(I::ErrorGuaranteed),
274}
275
276// This is manually implemented because a derive would require `I: Debug`
277impl<I: Interner> fmt::Debug for TyKind<I> {
278    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279        match self {
280            Bool => write!(f, "bool"),
281            Char => write!(f, "char"),
282            Int(i) => write!(f, "{i:?}"),
283            Uint(u) => write!(f, "{u:?}"),
284            Float(float) => write!(f, "{float:?}"),
285            Adt(d, s) => {
286                write!(f, "{d:?}")?;
287                let mut s = s.iter();
288                let first = s.next();
289                match first {
290                    Some(first) => write!(f, "<{:?}", first)?,
291                    None => return Ok(()),
292                };
293
294                for arg in s {
295                    write!(f, ", {:?}", arg)?;
296                }
297
298                write!(f, ">")
299            }
300            Foreign(d) => f.debug_tuple("Foreign").field(d).finish(),
301            Str => write!(f, "str"),
302            Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
303            Pat(t, p) => write!(f, "pattern_type!({t:?} is {p:?})"),
304            Slice(t) => write!(f, "[{:?}]", &t),
305            RawPtr(ty, mutbl) => write!(f, "*{} {:?}", mutbl.ptr_str(), ty),
306            Ref(r, t, m) => write!(f, "&{:?} {}{:?}", r, m.prefix_str(), t),
307            FnDef(d, s) => f.debug_tuple("FnDef").field(d).field(&s).finish(),
308            FnPtr(sig_tys, hdr) => write!(f, "{:?}", sig_tys.with(*hdr)),
309            // FIXME(unsafe_binder): print this like `unsafe<'a> T<'a>`.
310            UnsafeBinder(binder) => write!(f, "{:?}", binder),
311            Dynamic(p, r, repr) => match repr {
312                DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
313                DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
314            },
315            Closure(d, s) => f.debug_tuple("Closure").field(d).field(&s).finish(),
316            CoroutineClosure(d, s) => f.debug_tuple("CoroutineClosure").field(d).field(&s).finish(),
317            Coroutine(d, s) => f.debug_tuple("Coroutine").field(d).field(&s).finish(),
318            CoroutineWitness(d, s) => f.debug_tuple("CoroutineWitness").field(d).field(&s).finish(),
319            Never => write!(f, "!"),
320            Tuple(t) => {
321                write!(f, "(")?;
322                let mut count = 0;
323                for ty in t.iter() {
324                    if count > 0 {
325                        write!(f, ", ")?;
326                    }
327                    write!(f, "{ty:?}")?;
328                    count += 1;
329                }
330                // unary tuples need a trailing comma
331                if count == 1 {
332                    write!(f, ",")?;
333                }
334                write!(f, ")")
335            }
336            Alias(i, a) => f.debug_tuple("Alias").field(i).field(&a).finish(),
337            Param(p) => write!(f, "{p:?}"),
338            Bound(d, b) => crate::debug_bound_var(f, *d, b),
339            Placeholder(p) => write!(f, "{p:?}"),
340            Infer(t) => write!(f, "{:?}", t),
341            TyKind::Error(_) => write!(f, "{{type error}}"),
342        }
343    }
344}
345
346/// Represents the projection of an associated, opaque, or lazy-type-alias type.
347///
348/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
349/// * For an inherent projection, this would be `Ty::N<...>`.
350/// * For an opaque type, there is no explicit syntax.
351#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
352#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
353#[cfg_attr(
354    feature = "nightly",
355    derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
356)]
357pub struct AliasTy<I: Interner> {
358    /// The parameters of the associated or opaque type.
359    ///
360    /// For a projection, these are the generic parameters for the trait and the
361    /// GAT parameters, if there are any.
362    ///
363    /// For an inherent projection, they consist of the self type and the GAT parameters,
364    /// if there are any.
365    ///
366    /// For RPIT the generic parameters are for the generics of the function,
367    /// while for TAIT it is used for the generic parameters of the alias.
368    pub args: I::GenericArgs,
369
370    /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
371    /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
372    /// this is an opaque.
373    ///
374    /// During codegen, `interner.type_of(def_id)` can be used to get the type of the
375    /// underlying type if the type is an opaque.
376    ///
377    /// Note that if this is an associated type, this is not the `DefId` of the
378    /// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
379    /// aka. `interner.parent(def_id)`.
380    pub def_id: I::DefId,
381
382    /// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`].
383    #[derive_where(skip(Debug))]
384    pub(crate) _use_alias_ty_new_instead: (),
385}
386
387impl<I: Interner> AliasTy<I> {
388    pub fn new_from_args(interner: I, def_id: I::DefId, args: I::GenericArgs) -> AliasTy<I> {
389        interner.debug_assert_args_compatible(def_id, args);
390        AliasTy { def_id, args, _use_alias_ty_new_instead: () }
391    }
392
393    pub fn new(
394        interner: I,
395        def_id: I::DefId,
396        args: impl IntoIterator<Item: Into<I::GenericArg>>,
397    ) -> AliasTy<I> {
398        let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
399        Self::new_from_args(interner, def_id, args)
400    }
401
402    pub fn kind(self, interner: I) -> AliasTyKind {
403        interner.alias_ty_kind(self)
404    }
405
406    /// Whether this alias type is an opaque.
407    pub fn is_opaque(self, interner: I) -> bool {
408        matches!(self.kind(interner), AliasTyKind::Opaque)
409    }
410
411    pub fn to_ty(self, interner: I) -> I::Ty {
412        Ty::new_alias(interner, self.kind(interner), self)
413    }
414}
415
416/// The following methods work only with (trait) associated type projections.
417impl<I: Interner> AliasTy<I> {
418    pub fn self_ty(self) -> I::Ty {
419        self.args.type_at(0)
420    }
421
422    pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
423        AliasTy::new(
424            interner,
425            self.def_id,
426            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
427        )
428    }
429
430    pub fn trait_def_id(self, interner: I) -> I::DefId {
431        assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
432        interner.parent(self.def_id)
433    }
434
435    /// Extracts the underlying trait reference and own args from this projection.
436    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
437    /// then this function would return a `T: StreamingIterator` trait reference and
438    /// `['a]` as the own args.
439    pub fn trait_ref_and_own_args(self, interner: I) -> (ty::TraitRef<I>, I::GenericArgsSlice) {
440        debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
441        interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
442    }
443
444    /// Extracts the underlying trait reference from this projection.
445    /// For example, if this is a projection of `<T as Iterator>::Item`,
446    /// then this function would return a `T: Iterator` trait reference.
447    ///
448    /// WARNING: This will drop the args for generic associated types
449    /// consider calling [Self::trait_ref_and_own_args] to get those
450    /// as well.
451    pub fn trait_ref(self, interner: I) -> ty::TraitRef<I> {
452        self.trait_ref_and_own_args(interner).0
453    }
454}
455
456/// The following methods work only with inherent associated type projections.
457impl<I: Interner> AliasTy<I> {
458    /// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
459    ///
460    /// Does the following transformation:
461    ///
462    /// ```text
463    /// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
464    ///
465    ///     I_i impl args
466    ///     P_j GAT args
467    /// ```
468    pub fn rebase_inherent_args_onto_impl(
469        self,
470        impl_args: I::GenericArgs,
471        interner: I,
472    ) -> I::GenericArgs {
473        debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
474        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
475    }
476}
477
478#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
479#[cfg_attr(
480    feature = "nightly",
481    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
482)]
483pub enum IntTy {
484    Isize,
485    I8,
486    I16,
487    I32,
488    I64,
489    I128,
490}
491
492impl IntTy {
493    pub fn name_str(&self) -> &'static str {
494        match *self {
495            IntTy::Isize => "isize",
496            IntTy::I8 => "i8",
497            IntTy::I16 => "i16",
498            IntTy::I32 => "i32",
499            IntTy::I64 => "i64",
500            IntTy::I128 => "i128",
501        }
502    }
503
504    pub fn bit_width(&self) -> Option<u64> {
505        Some(match *self {
506            IntTy::Isize => return None,
507            IntTy::I8 => 8,
508            IntTy::I16 => 16,
509            IntTy::I32 => 32,
510            IntTy::I64 => 64,
511            IntTy::I128 => 128,
512        })
513    }
514
515    pub fn normalize(&self, target_width: u32) -> Self {
516        match self {
517            IntTy::Isize => match target_width {
518                16 => IntTy::I16,
519                32 => IntTy::I32,
520                64 => IntTy::I64,
521                _ => unreachable!(),
522            },
523            _ => *self,
524        }
525    }
526
527    pub fn to_unsigned(self) -> UintTy {
528        match self {
529            IntTy::Isize => UintTy::Usize,
530            IntTy::I8 => UintTy::U8,
531            IntTy::I16 => UintTy::U16,
532            IntTy::I32 => UintTy::U32,
533            IntTy::I64 => UintTy::U64,
534            IntTy::I128 => UintTy::U128,
535        }
536    }
537}
538
539#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
540#[cfg_attr(
541    feature = "nightly",
542    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
543)]
544pub enum UintTy {
545    Usize,
546    U8,
547    U16,
548    U32,
549    U64,
550    U128,
551}
552
553impl UintTy {
554    pub fn name_str(&self) -> &'static str {
555        match *self {
556            UintTy::Usize => "usize",
557            UintTy::U8 => "u8",
558            UintTy::U16 => "u16",
559            UintTy::U32 => "u32",
560            UintTy::U64 => "u64",
561            UintTy::U128 => "u128",
562        }
563    }
564
565    pub fn bit_width(&self) -> Option<u64> {
566        Some(match *self {
567            UintTy::Usize => return None,
568            UintTy::U8 => 8,
569            UintTy::U16 => 16,
570            UintTy::U32 => 32,
571            UintTy::U64 => 64,
572            UintTy::U128 => 128,
573        })
574    }
575
576    pub fn normalize(&self, target_width: u32) -> Self {
577        match self {
578            UintTy::Usize => match target_width {
579                16 => UintTy::U16,
580                32 => UintTy::U32,
581                64 => UintTy::U64,
582                _ => unreachable!(),
583            },
584            _ => *self,
585        }
586    }
587
588    pub fn to_signed(self) -> IntTy {
589        match self {
590            UintTy::Usize => IntTy::Isize,
591            UintTy::U8 => IntTy::I8,
592            UintTy::U16 => IntTy::I16,
593            UintTy::U32 => IntTy::I32,
594            UintTy::U64 => IntTy::I64,
595            UintTy::U128 => IntTy::I128,
596        }
597    }
598}
599
600#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
601#[cfg_attr(
602    feature = "nightly",
603    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
604)]
605pub enum FloatTy {
606    F16,
607    F32,
608    F64,
609    F128,
610}
611
612impl FloatTy {
613    pub fn name_str(self) -> &'static str {
614        match self {
615            FloatTy::F16 => "f16",
616            FloatTy::F32 => "f32",
617            FloatTy::F64 => "f64",
618            FloatTy::F128 => "f128",
619        }
620    }
621
622    pub fn bit_width(self) -> u64 {
623        match self {
624            FloatTy::F16 => 16,
625            FloatTy::F32 => 32,
626            FloatTy::F64 => 64,
627            FloatTy::F128 => 128,
628        }
629    }
630}
631
632#[derive(Clone, Copy, PartialEq, Eq, Debug)]
633pub enum IntVarValue {
634    Unknown,
635    IntType(IntTy),
636    UintType(UintTy),
637}
638
639impl IntVarValue {
640    pub fn is_known(self) -> bool {
641        match self {
642            IntVarValue::IntType(_) | IntVarValue::UintType(_) => true,
643            IntVarValue::Unknown => false,
644        }
645    }
646
647    pub fn is_unknown(self) -> bool {
648        !self.is_known()
649    }
650}
651
652#[derive(Clone, Copy, PartialEq, Eq, Debug)]
653pub enum FloatVarValue {
654    Unknown,
655    Known(FloatTy),
656}
657
658impl FloatVarValue {
659    pub fn is_known(self) -> bool {
660        match self {
661            FloatVarValue::Known(_) => true,
662            FloatVarValue::Unknown => false,
663        }
664    }
665
666    pub fn is_unknown(self) -> bool {
667        !self.is_known()
668    }
669}
670
671rustc_index::newtype_index! {
672    /// A **ty**pe **v**ariable **ID**.
673    #[encodable]
674    #[orderable]
675    #[debug_format = "?{}t"]
676    #[gate_rustc_only]
677    pub struct TyVid {}
678}
679
680rustc_index::newtype_index! {
681    /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**.
682    #[encodable]
683    #[orderable]
684    #[debug_format = "?{}i"]
685    #[gate_rustc_only]
686    pub struct IntVid {}
687}
688
689rustc_index::newtype_index! {
690    /// A **float**ing-point (`f32` or `f64`) type **v**ariable **ID**.
691    #[encodable]
692    #[orderable]
693    #[debug_format = "?{}f"]
694    #[gate_rustc_only]
695    pub struct FloatVid {}
696}
697
698/// A placeholder for a type that hasn't been inferred yet.
699///
700/// E.g., if we have an empty array (`[]`), then we create a fresh
701/// type variable for the element type since we won't know until it's
702/// used what the element type is supposed to be.
703#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
704#[cfg_attr(feature = "nightly", derive(Encodable_NoContext, Decodable_NoContext))]
705pub enum InferTy {
706    /// A type variable.
707    TyVar(TyVid),
708    /// An integral type variable (`{integer}`).
709    ///
710    /// These are created when the compiler sees an integer literal like
711    /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.).
712    /// We don't know until it's used what type it's supposed to be, so
713    /// we create a fresh type variable.
714    IntVar(IntVid),
715    /// A floating-point type variable (`{float}`).
716    ///
717    /// These are created when the compiler sees an float literal like
718    /// `1.0` that could be either an `f32` or an `f64`.
719    /// We don't know until it's used what type it's supposed to be, so
720    /// we create a fresh type variable.
721    FloatVar(FloatVid),
722
723    /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement
724    /// for an unbound type variable. This is convenient for caching etc. See
725    /// `rustc_infer::infer::freshen` for more details.
726    ///
727    /// Compare with [`TyVar`][Self::TyVar].
728    FreshTy(u32),
729    /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar].
730    FreshIntTy(u32),
731    /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar].
732    FreshFloatTy(u32),
733}
734
735/// Raw `TyVid` are used as the unification key for `sub_relations`;
736/// they carry no values.
737#[cfg(feature = "nightly")]
738impl UnifyKey for TyVid {
739    type Value = ();
740    #[inline]
741    fn index(&self) -> u32 {
742        self.as_u32()
743    }
744    #[inline]
745    fn from_index(i: u32) -> TyVid {
746        TyVid::from_u32(i)
747    }
748    fn tag() -> &'static str {
749        "TyVid"
750    }
751}
752
753#[cfg(feature = "nightly")]
754impl UnifyValue for IntVarValue {
755    type Error = NoError;
756
757    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
758        match (*value1, *value2) {
759            (IntVarValue::Unknown, IntVarValue::Unknown) => Ok(IntVarValue::Unknown),
760            (
761                IntVarValue::Unknown,
762                known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
763            )
764            | (
765                known @ (IntVarValue::UintType(_) | IntVarValue::IntType(_)),
766                IntVarValue::Unknown,
767            ) => Ok(known),
768            _ => panic!("differing ints should have been resolved first"),
769        }
770    }
771}
772
773#[cfg(feature = "nightly")]
774impl UnifyKey for IntVid {
775    type Value = IntVarValue;
776    #[inline] // make this function eligible for inlining - it is quite hot.
777    fn index(&self) -> u32 {
778        self.as_u32()
779    }
780    #[inline]
781    fn from_index(i: u32) -> IntVid {
782        IntVid::from_u32(i)
783    }
784    fn tag() -> &'static str {
785        "IntVid"
786    }
787}
788
789#[cfg(feature = "nightly")]
790impl UnifyValue for FloatVarValue {
791    type Error = NoError;
792
793    fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
794        match (*value1, *value2) {
795            (FloatVarValue::Unknown, FloatVarValue::Unknown) => Ok(FloatVarValue::Unknown),
796            (FloatVarValue::Unknown, FloatVarValue::Known(known))
797            | (FloatVarValue::Known(known), FloatVarValue::Unknown) => {
798                Ok(FloatVarValue::Known(known))
799            }
800            (FloatVarValue::Known(_), FloatVarValue::Known(_)) => {
801                panic!("differing floats should have been resolved first")
802            }
803        }
804    }
805}
806
807#[cfg(feature = "nightly")]
808impl UnifyKey for FloatVid {
809    type Value = FloatVarValue;
810    #[inline]
811    fn index(&self) -> u32 {
812        self.as_u32()
813    }
814    #[inline]
815    fn from_index(i: u32) -> FloatVid {
816        FloatVid::from_u32(i)
817    }
818    fn tag() -> &'static str {
819        "FloatVid"
820    }
821}
822
823#[cfg(feature = "nightly")]
824impl<CTX> HashStable<CTX> for InferTy {
825    fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
826        use InferTy::*;
827        std::mem::discriminant(self).hash_stable(ctx, hasher);
828        match self {
829            TyVar(_) | IntVar(_) | FloatVar(_) => {
830                panic!("type variables should not be hashed: {self:?}")
831            }
832            FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher),
833        }
834    }
835}
836
837impl fmt::Display for InferTy {
838    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
839        use InferTy::*;
840        match *self {
841            TyVar(_) => write!(f, "_"),
842            IntVar(_) => write!(f, "{}", "{integer}"),
843            FloatVar(_) => write!(f, "{}", "{float}"),
844            FreshTy(v) => write!(f, "FreshTy({v})"),
845            FreshIntTy(v) => write!(f, "FreshIntTy({v})"),
846            FreshFloatTy(v) => write!(f, "FreshFloatTy({v})"),
847        }
848    }
849}
850
851impl fmt::Debug for IntTy {
852    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
853        write!(f, "{}", self.name_str())
854    }
855}
856
857impl fmt::Debug for UintTy {
858    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
859        write!(f, "{}", self.name_str())
860    }
861}
862
863impl fmt::Debug for FloatTy {
864    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865        write!(f, "{}", self.name_str())
866    }
867}
868
869impl fmt::Debug for InferTy {
870    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
871        use InferTy::*;
872        match *self {
873            TyVar(ref v) => v.fmt(f),
874            IntVar(ref v) => v.fmt(f),
875            FloatVar(ref v) => v.fmt(f),
876            FreshTy(v) => write!(f, "FreshTy({v:?})"),
877            FreshIntTy(v) => write!(f, "FreshIntTy({v:?})"),
878            FreshFloatTy(v) => write!(f, "FreshFloatTy({v:?})"),
879        }
880    }
881}
882
883#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
884#[cfg_attr(
885    feature = "nightly",
886    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
887)]
888#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
889pub struct TypeAndMut<I: Interner> {
890    pub ty: I::Ty,
891    pub mutbl: Mutability,
892}
893
894#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
895#[cfg_attr(
896    feature = "nightly",
897    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
898)]
899#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
900pub struct FnSig<I: Interner> {
901    pub inputs_and_output: I::Tys,
902    pub c_variadic: bool,
903    #[type_visitable(ignore)]
904    #[type_foldable(identity)]
905    pub safety: I::Safety,
906    #[type_visitable(ignore)]
907    #[type_foldable(identity)]
908    pub abi: I::Abi,
909}
910
911impl<I: Interner> FnSig<I> {
912    pub fn inputs(self) -> I::FnInputTys {
913        self.inputs_and_output.inputs()
914    }
915
916    pub fn output(self) -> I::Ty {
917        self.inputs_and_output.output()
918    }
919
920    pub fn is_fn_trait_compatible(self) -> bool {
921        let FnSig { safety, abi, c_variadic, .. } = self;
922        !c_variadic && safety.is_safe() && abi.is_rust()
923    }
924}
925
926impl<I: Interner> ty::Binder<I, FnSig<I>> {
927    #[inline]
928    pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
929        self.map_bound(|fn_sig| fn_sig.inputs())
930    }
931
932    #[inline]
933    #[track_caller]
934    pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
935        self.map_bound(|fn_sig| fn_sig.inputs().get(index).unwrap())
936    }
937
938    pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
939        self.map_bound(|fn_sig| fn_sig.inputs_and_output)
940    }
941
942    #[inline]
943    pub fn output(self) -> ty::Binder<I, I::Ty> {
944        self.map_bound(|fn_sig| fn_sig.output())
945    }
946
947    pub fn c_variadic(self) -> bool {
948        self.skip_binder().c_variadic
949    }
950
951    pub fn safety(self) -> I::Safety {
952        self.skip_binder().safety
953    }
954
955    pub fn abi(self) -> I::Abi {
956        self.skip_binder().abi
957    }
958
959    pub fn is_fn_trait_compatible(&self) -> bool {
960        self.skip_binder().is_fn_trait_compatible()
961    }
962
963    // Used to split a single value into the two fields in `TyKind::FnPtr`.
964    pub fn split(self) -> (ty::Binder<I, FnSigTys<I>>, FnHeader<I>) {
965        let hdr =
966            FnHeader { c_variadic: self.c_variadic(), safety: self.safety(), abi: self.abi() };
967        (self.map_bound(|sig| FnSigTys { inputs_and_output: sig.inputs_and_output }), hdr)
968    }
969}
970
971impl<I: Interner> fmt::Debug for FnSig<I> {
972    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973        let sig = self;
974        let FnSig { inputs_and_output: _, c_variadic, safety, abi } = sig;
975
976        write!(f, "{}", safety.prefix_str())?;
977        if !abi.is_rust() {
978            write!(f, "extern \"{abi:?}\" ")?;
979        }
980
981        write!(f, "fn(")?;
982        let inputs = sig.inputs();
983        for (i, ty) in inputs.iter().enumerate() {
984            if i > 0 {
985                write!(f, ", ")?;
986            }
987            write!(f, "{ty:?}")?;
988        }
989        if *c_variadic {
990            if inputs.is_empty() {
991                write!(f, "...")?;
992            } else {
993                write!(f, ", ...")?;
994            }
995        }
996        write!(f, ")")?;
997
998        let output = sig.output();
999        match output.kind() {
1000            Tuple(list) if list.is_empty() => Ok(()),
1001            _ => write!(f, " -> {:?}", sig.output()),
1002        }
1003    }
1004}
1005
1006// FIXME: this is a distinct type because we need to define `Encode`/`Decode`
1007// impls in this crate for `Binder<I, I::Ty>`.
1008#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
1009#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
1010#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1011pub struct UnsafeBinderInner<I: Interner>(ty::Binder<I, I::Ty>);
1012
1013impl<I: Interner> From<ty::Binder<I, I::Ty>> for UnsafeBinderInner<I> {
1014    fn from(value: ty::Binder<I, I::Ty>) -> Self {
1015        UnsafeBinderInner(value)
1016    }
1017}
1018
1019impl<I: Interner> From<UnsafeBinderInner<I>> for ty::Binder<I, I::Ty> {
1020    fn from(value: UnsafeBinderInner<I>) -> Self {
1021        value.0
1022    }
1023}
1024
1025impl<I: Interner> fmt::Debug for UnsafeBinderInner<I> {
1026    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027        self.0.fmt(f)
1028    }
1029}
1030
1031impl<I: Interner> Deref for UnsafeBinderInner<I> {
1032    type Target = ty::Binder<I, I::Ty>;
1033
1034    fn deref(&self) -> &Self::Target {
1035        &self.0
1036    }
1037}
1038
1039#[cfg(feature = "nightly")]
1040impl<I: Interner, E: rustc_serialize::Encoder> rustc_serialize::Encodable<E>
1041    for UnsafeBinderInner<I>
1042where
1043    I::Ty: rustc_serialize::Encodable<E>,
1044    I::BoundVarKinds: rustc_serialize::Encodable<E>,
1045{
1046    fn encode(&self, e: &mut E) {
1047        self.bound_vars().encode(e);
1048        self.as_ref().skip_binder().encode(e);
1049    }
1050}
1051
1052#[cfg(feature = "nightly")]
1053impl<I: Interner, D: rustc_serialize::Decoder> rustc_serialize::Decodable<D>
1054    for UnsafeBinderInner<I>
1055where
1056    I::Ty: TypeVisitable<I> + rustc_serialize::Decodable<D>,
1057    I::BoundVarKinds: rustc_serialize::Decodable<D>,
1058{
1059    fn decode(decoder: &mut D) -> Self {
1060        let bound_vars = rustc_serialize::Decodable::decode(decoder);
1061        UnsafeBinderInner(ty::Binder::bind_with_vars(
1062            rustc_serialize::Decodable::decode(decoder),
1063            bound_vars,
1064        ))
1065    }
1066}
1067
1068// This is just a `FnSig` without the `FnHeader` fields.
1069#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1070#[cfg_attr(
1071    feature = "nightly",
1072    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1073)]
1074#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1075pub struct FnSigTys<I: Interner> {
1076    pub inputs_and_output: I::Tys,
1077}
1078
1079impl<I: Interner> FnSigTys<I> {
1080    pub fn inputs(self) -> I::FnInputTys {
1081        self.inputs_and_output.inputs()
1082    }
1083
1084    pub fn output(self) -> I::Ty {
1085        self.inputs_and_output.output()
1086    }
1087}
1088
1089impl<I: Interner> ty::Binder<I, FnSigTys<I>> {
1090    // Used to combine the two fields in `TyKind::FnPtr` into a single value.
1091    pub fn with(self, hdr: FnHeader<I>) -> ty::Binder<I, FnSig<I>> {
1092        self.map_bound(|sig_tys| FnSig {
1093            inputs_and_output: sig_tys.inputs_and_output,
1094            c_variadic: hdr.c_variadic,
1095            safety: hdr.safety,
1096            abi: hdr.abi,
1097        })
1098    }
1099
1100    #[inline]
1101    pub fn inputs(self) -> ty::Binder<I, I::FnInputTys> {
1102        self.map_bound(|sig_tys| sig_tys.inputs())
1103    }
1104
1105    #[inline]
1106    #[track_caller]
1107    pub fn input(self, index: usize) -> ty::Binder<I, I::Ty> {
1108        self.map_bound(|sig_tys| sig_tys.inputs().get(index).unwrap())
1109    }
1110
1111    pub fn inputs_and_output(self) -> ty::Binder<I, I::Tys> {
1112        self.map_bound(|sig_tys| sig_tys.inputs_and_output)
1113    }
1114
1115    #[inline]
1116    pub fn output(self) -> ty::Binder<I, I::Ty> {
1117        self.map_bound(|sig_tys| sig_tys.output())
1118    }
1119}
1120
1121#[derive_where(Clone, Copy, Debug, PartialEq, Eq, Hash; I: Interner)]
1122#[cfg_attr(
1123    feature = "nightly",
1124    derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
1125)]
1126#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
1127pub struct FnHeader<I: Interner> {
1128    pub c_variadic: bool,
1129    pub safety: I::Safety,
1130    pub abi: I::Abi,
1131}