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