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