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