Skip to main content

rustc_type_ir/
canonical.rs

1use std::fmt;
2use std::ops::Index;
3
4use arrayvec::ArrayVec;
5use derive_where::derive_where;
6#[cfg(feature = "nightly")]
7use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
8use rustc_type_ir_macros::{
9    GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
10};
11
12use crate::data_structures::{DelayedMap, HashMap};
13use crate::inherent::*;
14use crate::{self as ty, Interner, TypingModeEqWrapper, UniverseIndex};
15
16#[automatically_derived]
impl<I: Interner, V> ::core::clone::Clone for CanonicalQueryInput<I, V> where
    I: Interner, V: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            CanonicalQueryInput {
                canonical: ref __field_canonical,
                typing_mode: ref __field_typing_mode } =>
                CanonicalQueryInput {
                    canonical: ::core::clone::Clone::clone(__field_canonical),
                    typing_mode: ::core::clone::Clone::clone(__field_typing_mode),
                },
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::hash::Hash for CanonicalQueryInput<I, V> where
    I: Interner, V: ::core::hash::Hash {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            CanonicalQueryInput {
                canonical: ref __field_canonical,
                typing_mode: ref __field_typing_mode } => {
                ::core::hash::Hash::hash(__field_canonical, __state);
                ::core::hash::Hash::hash(__field_typing_mode, __state);
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::cmp::PartialEq for CanonicalQueryInput<I, V>
    where I: Interner, V: ::core::cmp::PartialEq {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        match (self, __other) {
            (CanonicalQueryInput {
                canonical: ref __field_canonical,
                typing_mode: ref __field_typing_mode }, CanonicalQueryInput {
                canonical: ref __other_field_canonical,
                typing_mode: ref __other_field_typing_mode }) =>
                true &&
                        ::core::cmp::PartialEq::eq(__field_canonical,
                            __other_field_canonical) &&
                    ::core::cmp::PartialEq::eq(__field_typing_mode,
                        __other_field_typing_mode),
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::fmt::Debug for CanonicalQueryInput<I, V> where
    I: Interner, V: ::core::fmt::Debug {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CanonicalQueryInput {
                canonical: ref __field_canonical,
                typing_mode: ref __field_typing_mode } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "CanonicalQueryInput");
                ::core::fmt::DebugStruct::field(&mut __builder, "canonical",
                    __field_canonical);
                ::core::fmt::DebugStruct::field(&mut __builder, "typing_mode",
                    __field_typing_mode);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::marker::Copy for CanonicalQueryInput<I, V> where
    I: Interner, V: Copy {
}#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, V)]
17#[derive_where(Copy; I: Interner, V: Copy)]
18#[cfg_attr(
19    feature = "nightly",
20    derive(const _: () =
    {
        impl<I: Interner, V, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for CanonicalQueryInput<I, V>
            where Canonical<I, V>: ::rustc_serialize::Encodable<__E>,
            TypingModeEqWrapper<I>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let CanonicalQueryInput {
                        canonical: ref __binding_0, typing_mode: ref __binding_1 } =
                    *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, V, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for CanonicalQueryInput<I, V>
            where Canonical<I, V>: ::rustc_serialize::Decodable<__D>,
            TypingModeEqWrapper<I>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                CanonicalQueryInput {
                    canonical: ::rustc_serialize::Decodable::decode(__decoder),
                    typing_mode: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, V> ::rustc_data_structures::stable_hash::StableHash
            for CanonicalQueryInput<I, V> where
            Canonical<I, V>: ::rustc_data_structures::stable_hash::StableHash,
            TypingModeEqWrapper<I>: ::rustc_data_structures::stable_hash::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CanonicalQueryInput {
                        canonical: ref __binding_0, typing_mode: ref __binding_1 }
                        => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
21)]
22pub struct CanonicalQueryInput<I: Interner, V> {
23    pub canonical: Canonical<I, V>,
24    pub typing_mode: TypingModeEqWrapper<I>,
25}
26
27impl<I: Interner, V: Eq> Eq for CanonicalQueryInput<I, V> {}
28
29/// A "canonicalized" type `V` is one where all free inference
30/// variables have been rewritten to "canonical vars". These are
31/// numbered starting from 0 in order of first appearance.
32#[automatically_derived]
impl<I: Interner, V> ::core::clone::Clone for Canonical<I, V> where
    I: Interner, V: ::core::clone::Clone {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Canonical {
                value: ref __field_value,
                max_universe: ref __field_max_universe,
                var_kinds: ref __field_var_kinds } =>
                Canonical {
                    value: ::core::clone::Clone::clone(__field_value),
                    max_universe: ::core::clone::Clone::clone(__field_max_universe),
                    var_kinds: ::core::clone::Clone::clone(__field_var_kinds),
                },
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::hash::Hash for Canonical<I, V> where I: Interner,
    V: ::core::hash::Hash {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            Canonical {
                value: ref __field_value,
                max_universe: ref __field_max_universe,
                var_kinds: ref __field_var_kinds } => {
                ::core::hash::Hash::hash(__field_value, __state);
                ::core::hash::Hash::hash(__field_max_universe, __state);
                ::core::hash::Hash::hash(__field_var_kinds, __state);
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::cmp::PartialEq for Canonical<I, V> where
    I: Interner, V: ::core::cmp::PartialEq {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        match (self, __other) {
            (Canonical {
                value: ref __field_value,
                max_universe: ref __field_max_universe,
                var_kinds: ref __field_var_kinds }, Canonical {
                value: ref __other_field_value,
                max_universe: ref __other_field_max_universe,
                var_kinds: ref __other_field_var_kinds }) =>
                true &&
                            ::core::cmp::PartialEq::eq(__field_value,
                                __other_field_value) &&
                        ::core::cmp::PartialEq::eq(__field_max_universe,
                            __other_field_max_universe) &&
                    ::core::cmp::PartialEq::eq(__field_var_kinds,
                        __other_field_var_kinds),
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::fmt::Debug for Canonical<I, V> where I: Interner,
    V: ::core::fmt::Debug {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            Canonical {
                value: ref __field_value,
                max_universe: ref __field_max_universe,
                var_kinds: ref __field_var_kinds } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "Canonical");
                ::core::fmt::DebugStruct::field(&mut __builder, "value",
                    __field_value);
                ::core::fmt::DebugStruct::field(&mut __builder,
                    "max_universe", __field_max_universe);
                ::core::fmt::DebugStruct::field(&mut __builder, "var_kinds",
                    __field_var_kinds);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner, V> ::core::marker::Copy for Canonical<I, V> where
    I: Interner, V: Copy {
}#[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, V)]
33#[derive_where(Copy; I: Interner, V: Copy)]
34#[cfg_attr(
35    feature = "nightly",
36    derive(const _: () =
    {
        impl<I: Interner, V, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for Canonical<I, V> where
            V: ::rustc_serialize::Encodable<__E>,
            I::CanonicalVarKinds: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let Canonical {
                        value: ref __binding_0,
                        max_universe: ref __binding_1,
                        var_kinds: ref __binding_2 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, V, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for Canonical<I, V> where
            V: ::rustc_serialize::Decodable<__D>,
            I::CanonicalVarKinds: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                Canonical {
                    value: ::rustc_serialize::Decodable::decode(__decoder),
                    max_universe: ::rustc_serialize::Decodable::decode(__decoder),
                    var_kinds: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, V> ::rustc_data_structures::stable_hash::StableHash
            for Canonical<I, V> where
            V: ::rustc_data_structures::stable_hash::StableHash,
            I::CanonicalVarKinds: ::rustc_data_structures::stable_hash::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    Canonical {
                        value: ref __binding_0,
                        max_universe: ref __binding_1,
                        var_kinds: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
37)]
38pub struct Canonical<I: Interner, V> {
39    pub value: V,
40    pub max_universe: UniverseIndex,
41    pub var_kinds: I::CanonicalVarKinds,
42}
43
44impl<I: Interner, V: Eq> Eq for Canonical<I, V> {}
45
46impl<I: Interner, V> Canonical<I, V> {
47    /// Allows you to map the `value` of a canonical while keeping the
48    /// same set of bound variables.
49    ///
50    /// **WARNING:** This function is very easy to mis-use, hence the
51    /// name!  In particular, the new value `W` must use all **the
52    /// same type/region variables** in **precisely the same order**
53    /// as the original! (The ordering is defined by the
54    /// `TypeFoldable` implementation of the type in question.)
55    ///
56    /// An example of a **correct** use of this:
57    ///
58    /// ```rust,ignore (not real code)
59    /// let a: Canonical<I, T> = ...;
60    /// let b: Canonical<I, (T,)> = a.unchecked_map(|v| (v, ));
61    /// ```
62    ///
63    /// An example of an **incorrect** use of this:
64    ///
65    /// ```rust,ignore (not real code)
66    /// let a: Canonical<I, T> = ...;
67    /// let ty: Ty<I> = ...;
68    /// let b: Canonical<I, (T, Ty<I>)> = a.unchecked_map(|v| (v, ty));
69    /// ```
70    pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<I, W> {
71        let Canonical { max_universe, var_kinds, value } = self;
72        Canonical { max_universe, var_kinds, value: map_op(value) }
73    }
74
75    pub fn project<W>(self, f: impl FnOnce(V) -> W) -> Canonicalized<W> {
76        Canonicalized(f(self.value))
77    }
78}
79
80impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
81    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82        let Self { value, max_universe, var_kinds } = self;
83        f.write_fmt(format_args!("Canonical {{ value: {0}, max_universe: {1:?}, var_kinds: {2:?} }}",
        value, max_universe, var_kinds))write!(
84            f,
85            "Canonical {{ value: {value}, max_universe: {max_universe:?}, var_kinds: {var_kinds:?} }}",
86        )
87    }
88}
89
90/// A projection of a `Canonical<V>`, as produced by `Canonical::project`. Useful as a marker when
91/// dealing with fields within a `Canonical<V>`, because it indicates that `T` may contain
92/// canonical bound variables that must be instantiated before use.
93///
94/// The field is private and the contents can only be accessed directly with `into_uninstantiated`,
95/// which is easy to spot.
96#[derive(#[automatically_derived]impl<T: ::core::marker::Copy> ::core::marker::Copy for
    Canonicalized<T> {
}Copy, #[automatically_derived]impl<T: ::core::clone::Clone> ::core::clone::Clone for
    Canonicalized<T> {
    #[inline]
    #[rustc_trivial_field_reads]
    fn clone(&self) -> Self {
        Canonicalized(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]impl<T: ::core::fmt::Debug> ::core::fmt::Debug for
    Canonicalized<T> {
    #[inline]
    #[rustc_trivial_field_reads]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Canonicalized",
            &&self.0)
    }
}Debug)]
97pub struct Canonicalized<T>(T);
98
99impl<T> Canonicalized<T> {
100    pub fn into_uninstantiated(self) -> T {
101        self.0
102    }
103}
104
105impl<T: SliceLike> Canonicalized<T> {
106    pub fn len(self) -> usize {
107        self.0.len()
108    }
109
110    pub fn iter(self) -> impl Iterator<Item = Canonicalized<T::Item>> {
111        self.0.iter().map(|x| Canonicalized(x))
112    }
113}
114
115/// Information about a canonical variable that is included with the
116/// canonical value. This is sufficient information for code to create
117/// a copy of the canonical value in some other inference context,
118/// with fresh inference variables replacing the canonical values.
119#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for CanonicalVarKind<I> where
    I: Interner {
    #[inline]
    fn clone(&self) -> Self { *self }
}
#[automatically_derived]
impl<I: Interner> ::core::marker::Copy for CanonicalVarKind<I> where
    I: Interner {
}
#[automatically_derived]
impl<I: Interner> ::core::hash::Hash for CanonicalVarKind<I> where I: Interner
    {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            CanonicalVarKind::Ty {
                ui: ref __field_ui, sub_root: ref __field_sub_root } => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_ui, __state);
                ::core::hash::Hash::hash(__field_sub_root, __state);
            }
            CanonicalVarKind::Int => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
            }
            CanonicalVarKind::Float => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
            }
            CanonicalVarKind::PlaceholderTy(ref __field_0) => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_0, __state);
            }
            CanonicalVarKind::Region(ref __field_0) => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_0, __state);
            }
            CanonicalVarKind::PlaceholderRegion(ref __field_0) => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_0, __state);
            }
            CanonicalVarKind::Const(ref __field_0) => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_0, __state);
            }
            CanonicalVarKind::PlaceholderConst(ref __field_0) => {
                ::core::hash::Hash::hash(&::core::mem::discriminant(self),
                    __state);
                ::core::hash::Hash::hash(__field_0, __state);
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for CanonicalVarKind<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        if ::core::mem::discriminant(self) ==
                ::core::mem::discriminant(__other) {
            match (self, __other) {
                (CanonicalVarKind::Ty {
                    ui: ref __field_ui, sub_root: ref __field_sub_root },
                    CanonicalVarKind::Ty {
                    ui: ref __other_field_ui,
                    sub_root: ref __other_field_sub_root }) =>
                    true &&
                            ::core::cmp::PartialEq::eq(__field_ui, __other_field_ui) &&
                        ::core::cmp::PartialEq::eq(__field_sub_root,
                            __other_field_sub_root),
                (CanonicalVarKind::PlaceholderTy(ref __field_0),
                    CanonicalVarKind::PlaceholderTy(ref __other_field_0)) =>
                    true &&
                        ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
                (CanonicalVarKind::Region(ref __field_0),
                    CanonicalVarKind::Region(ref __other_field_0)) =>
                    true &&
                        ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
                (CanonicalVarKind::PlaceholderRegion(ref __field_0),
                    CanonicalVarKind::PlaceholderRegion(ref __other_field_0)) =>
                    true &&
                        ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
                (CanonicalVarKind::Const(ref __field_0),
                    CanonicalVarKind::Const(ref __other_field_0)) =>
                    true &&
                        ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
                (CanonicalVarKind::PlaceholderConst(ref __field_0),
                    CanonicalVarKind::PlaceholderConst(ref __other_field_0)) =>
                    true &&
                        ::core::cmp::PartialEq::eq(__field_0, __other_field_0),
                _ => true,
            }
        } else { false }
    }
}
#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for CanonicalVarKind<I> where I: Interner
    {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CanonicalVarKind::Ty {
                ui: ref __field_ui, sub_root: ref __field_sub_root } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f, "Ty");
                ::core::fmt::DebugStruct::field(&mut __builder, "ui",
                    __field_ui);
                ::core::fmt::DebugStruct::field(&mut __builder, "sub_root",
                    __field_sub_root);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
            CanonicalVarKind::Int =>
                ::core::fmt::Formatter::write_str(__f, "Int"),
            CanonicalVarKind::Float =>
                ::core::fmt::Formatter::write_str(__f, "Float"),
            CanonicalVarKind::PlaceholderTy(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "PlaceholderTy");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CanonicalVarKind::Region(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Region");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CanonicalVarKind::PlaceholderRegion(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f,
                        "PlaceholderRegion");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CanonicalVarKind::Const(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f, "Const");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
            CanonicalVarKind::PlaceholderConst(ref __field_0) => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_tuple(__f,
                        "PlaceholderConst");
                ::core::fmt::DebugTuple::field(&mut __builder, __field_0);
                ::core::fmt::DebugTuple::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
120#[derive(const _: () =
    {
        unsafe impl<I: Interner, __V>
            ::rustc_type_ir::GenericTypeVisitable<__V> for CanonicalVarKind<I>
            where UniverseIndex: ::rustc_type_ir::GenericTypeVisitable<__V>,
            ty::BoundVar: ::rustc_type_ir::GenericTypeVisitable<__V>,
            ty::PlaceholderType<I>: ::rustc_type_ir::GenericTypeVisitable<__V>,
            UniverseIndex: ::rustc_type_ir::GenericTypeVisitable<__V>,
            ty::PlaceholderRegion<I>: ::rustc_type_ir::GenericTypeVisitable<__V>,
            UniverseIndex: ::rustc_type_ir::GenericTypeVisitable<__V>,
            ty::PlaceholderConst<I>: ::rustc_type_ir::GenericTypeVisitable<__V>
            {
            fn generic_visit_with(&self, __visitor: &mut __V) {
                match *self {
                    CanonicalVarKind::Ty {
                        ui: ref __binding_0, sub_root: ref __binding_1 } => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_1,
                                __visitor);
                        }
                    }
                    CanonicalVarKind::Int => {}
                    CanonicalVarKind::Float => {}
                    CanonicalVarKind::PlaceholderTy(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                    CanonicalVarKind::Region(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                    CanonicalVarKind::PlaceholderRegion(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                    CanonicalVarKind::Const(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                    CanonicalVarKind::PlaceholderConst(ref __binding_0) => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                }
            }
        }
    };GenericTypeVisitable)]
121#[cfg_attr(
122    feature = "nightly",
123    derive(const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for CanonicalVarKind<I> where
            ty::PlaceholderType<I>: ::rustc_serialize::Decodable<__D>,
            ty::PlaceholderRegion<I>: ::rustc_serialize::Decodable<__D>,
            ty::PlaceholderConst<I>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        CanonicalVarKind::Ty {
                            ui: ::rustc_serialize::Decodable::decode(__decoder),
                            sub_root: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    1usize => { CanonicalVarKind::Int }
                    2usize => { CanonicalVarKind::Float }
                    3usize => {
                        CanonicalVarKind::PlaceholderTy(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    4usize => {
                        CanonicalVarKind::Region(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    5usize => {
                        CanonicalVarKind::PlaceholderRegion(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    6usize => {
                        CanonicalVarKind::Const(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    7usize => {
                        CanonicalVarKind::PlaceholderConst(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `CanonicalVarKind`, expected 0..8, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for CanonicalVarKind<I> where
            ty::PlaceholderType<I>: ::rustc_serialize::Encodable<__E>,
            ty::PlaceholderRegion<I>: ::rustc_serialize::Encodable<__E>,
            ty::PlaceholderConst<I>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        CanonicalVarKind::Ty {
                            ui: ref __binding_0, sub_root: ref __binding_1 } => {
                            0usize
                        }
                        CanonicalVarKind::Int => { 1usize }
                        CanonicalVarKind::Float => { 2usize }
                        CanonicalVarKind::PlaceholderTy(ref __binding_0) => {
                            3usize
                        }
                        CanonicalVarKind::Region(ref __binding_0) => { 4usize }
                        CanonicalVarKind::PlaceholderRegion(ref __binding_0) => {
                            5usize
                        }
                        CanonicalVarKind::Const(ref __binding_0) => { 6usize }
                        CanonicalVarKind::PlaceholderConst(ref __binding_0) => {
                            7usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    CanonicalVarKind::Ty {
                        ui: ref __binding_0, sub_root: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                    CanonicalVarKind::Int => {}
                    CanonicalVarKind::Float => {}
                    CanonicalVarKind::PlaceholderTy(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    CanonicalVarKind::Region(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    CanonicalVarKind::PlaceholderRegion(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    CanonicalVarKind::Const(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    CanonicalVarKind::PlaceholderConst(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            CanonicalVarKind<I> where
            ty::PlaceholderType<I>: ::rustc_data_structures::stable_hash::StableHash,
            ty::PlaceholderRegion<I>: ::rustc_data_structures::stable_hash::StableHash,
            ty::PlaceholderConst<I>: ::rustc_data_structures::stable_hash::StableHash
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CanonicalVarKind::Ty {
                        ui: ref __binding_0, sub_root: ref __binding_1 } =>
                        0u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::Int => 1u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::Float => 2u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::PlaceholderTy(ref __binding_0) =>
                        3u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::Region(ref __binding_0) =>
                        4u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::PlaceholderRegion(ref __binding_0) =>
                        5u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::Const(ref __binding_0) =>
                        6u8.stable_hash(__hcx, __hasher),
                    CanonicalVarKind::PlaceholderConst(ref __binding_0) =>
                        7u8.stable_hash(__hcx, __hasher),
                }
                match *self {
                    CanonicalVarKind::Ty {
                        ui: ref __binding_0, sub_root: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                    CanonicalVarKind::Int => {}
                    CanonicalVarKind::Float => {}
                    CanonicalVarKind::PlaceholderTy(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    CanonicalVarKind::Region(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    CanonicalVarKind::PlaceholderRegion(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    CanonicalVarKind::Const(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    CanonicalVarKind::PlaceholderConst(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
124)]
125pub enum CanonicalVarKind<I: Interner> {
126    /// General type variable `?T` that can be unified with arbitrary types.
127    ///
128    /// We also store the index of the first type variable which is sub-unified
129    /// with this one. If there is no inference variable related to this one,
130    /// its `sub_root` just points to itself.
131    Ty { ui: UniverseIndex, sub_root: ty::BoundVar },
132
133    /// Integral type variable `?I` (that can only be unified with integral types).
134    Int,
135
136    /// Floating-point type variable `?F` (that can only be unified with float types).
137    Float,
138
139    /// A "placeholder" that represents "any type".
140    PlaceholderTy(ty::PlaceholderType<I>),
141
142    /// Region variable `'?R`.
143    Region(UniverseIndex),
144
145    /// A "placeholder" that represents "any region". Created when you
146    /// are solving a goal like `for<'a> T: Foo<'a>` to represent the
147    /// bound region `'a`.
148    PlaceholderRegion(ty::PlaceholderRegion<I>),
149
150    /// Some kind of const inference variable.
151    Const(UniverseIndex),
152
153    /// A "placeholder" that represents "any const".
154    PlaceholderConst(ty::PlaceholderConst<I>),
155}
156
157impl<I: Interner> Eq for CanonicalVarKind<I> {}
158
159impl<I: Interner> CanonicalVarKind<I> {
160    pub fn universe(self) -> UniverseIndex {
161        match self {
162            CanonicalVarKind::Ty { ui, sub_root: _ } => ui,
163            CanonicalVarKind::Region(ui) => ui,
164            CanonicalVarKind::Const(ui) => ui,
165            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
166            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
167            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
168            CanonicalVarKind::Float | CanonicalVarKind::Int => UniverseIndex::ROOT,
169        }
170    }
171
172    /// Replaces the universe of this canonical variable with `ui`.
173    ///
174    /// In case this is a float or int variable, this causes an ICE if
175    /// the updated universe is not the root.
176    pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
177        match self {
178            CanonicalVarKind::Ty { ui: _, sub_root } => CanonicalVarKind::Ty { ui, sub_root },
179            CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
180            CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
181
182            CanonicalVarKind::PlaceholderTy(placeholder) => {
183                CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
184            }
185            CanonicalVarKind::PlaceholderRegion(placeholder) => {
186                CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
187            }
188            CanonicalVarKind::PlaceholderConst(placeholder) => {
189                CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
190            }
191            CanonicalVarKind::Int | CanonicalVarKind::Float => {
192                {
    match (&ui, &UniverseIndex::ROOT) {
        (left_val, right_val) => {
            if !(*left_val == *right_val) {
                let kind = ::core::panicking::AssertKind::Eq;
                ::core::panicking::assert_failed(kind, &*left_val,
                    &*right_val, ::core::option::Option::None);
            }
        }
    }
};assert_eq!(ui, UniverseIndex::ROOT);
193                self
194            }
195        }
196    }
197
198    pub fn is_existential(self) -> bool {
199        match self {
200            CanonicalVarKind::Ty { .. }
201            | CanonicalVarKind::Int
202            | CanonicalVarKind::Float
203            | CanonicalVarKind::Region(_)
204            | CanonicalVarKind::Const(_) => true,
205            CanonicalVarKind::PlaceholderTy(_)
206            | CanonicalVarKind::PlaceholderRegion(..)
207            | CanonicalVarKind::PlaceholderConst(_) => false,
208        }
209    }
210
211    pub fn is_region(self) -> bool {
212        match self {
213            CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
214            CanonicalVarKind::Ty { .. }
215            | CanonicalVarKind::Int
216            | CanonicalVarKind::Float
217            | CanonicalVarKind::PlaceholderTy(_)
218            | CanonicalVarKind::Const(_)
219            | CanonicalVarKind::PlaceholderConst(_) => false,
220        }
221    }
222
223    pub fn expect_placeholder_index(self) -> usize {
224        match self {
225            CanonicalVarKind::Ty { .. }
226            | CanonicalVarKind::Int
227            | CanonicalVarKind::Float
228            | CanonicalVarKind::Region(_)
229            | CanonicalVarKind::Const(_) => {
230                {
    ::core::panicking::panic_fmt(format_args!("expected placeholder: {0:?}",
            self));
}panic!("expected placeholder: {self:?}")
231            }
232
233            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
234            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
235            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
236        }
237    }
238}
239
240/// A set of values corresponding to the canonical variables from some
241/// `Canonical`. You can give these values to
242/// `canonical_value.instantiate` to instantiate them into the canonical
243/// value at the right places.
244///
245/// When you canonicalize a value `V`, you get back one of these
246/// vectors with the original values that were replaced by canonical
247/// variables. You will need to supply it later to instantiate the
248/// canonicalized query response.
249#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for CanonicalVarValues<I> where
    I: Interner {
    #[inline]
    fn clone(&self) -> Self { *self }
}
#[automatically_derived]
impl<I: Interner> ::core::marker::Copy for CanonicalVarValues<I> where
    I: Interner {
}
#[automatically_derived]
impl<I: Interner> ::core::hash::Hash for CanonicalVarValues<I> where
    I: Interner {
    fn hash<__H: ::core::hash::Hasher>(&self, __state: &mut __H) {
        match self {
            CanonicalVarValues { var_values: ref __field_var_values } => {
                ::core::hash::Hash::hash(__field_var_values, __state);
            }
        }
    }
}
#[automatically_derived]
impl<I: Interner> ::core::cmp::PartialEq for CanonicalVarValues<I> where
    I: Interner {
    #[inline]
    fn eq(&self, __other: &Self) -> ::core::primitive::bool {
        match (self, __other) {
            (CanonicalVarValues { var_values: ref __field_var_values },
                CanonicalVarValues { var_values: ref __other_field_var_values
                }) =>
                true &&
                    ::core::cmp::PartialEq::eq(__field_var_values,
                        __other_field_var_values),
        }
    }
}
#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for CanonicalVarValues<I> where
    I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CanonicalVarValues { var_values: ref __field_var_values } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "CanonicalVarValues");
                ::core::fmt::DebugStruct::field(&mut __builder, "var_values",
                    __field_var_values);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)]
250#[cfg_attr(
251    feature = "nightly",
252    derive(const _: () =
    {
        impl<I: Interner, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for CanonicalVarValues<I> where
            I::GenericArgs: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let CanonicalVarValues { var_values: ref __binding_0 } =
                    *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<I: Interner, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for CanonicalVarValues<I> where
            I::GenericArgs: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                CanonicalVarValues {
                    var_values: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl<I: Interner> ::rustc_data_structures::stable_hash::StableHash for
            CanonicalVarValues<I> where
            I::GenericArgs: ::rustc_data_structures::stable_hash::StableHash {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    CanonicalVarValues { var_values: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash_NoContext)
253)]
254#[derive(const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeVisitable<I> for
            CanonicalVarValues<I> where I: Interner,
            I::GenericArgs: ::rustc_type_ir::TypeVisitable<I> {
            fn visit_with<__V: ::rustc_type_ir::TypeVisitor<I>>(&self,
                __visitor: &mut __V) -> __V::Result {
                match *self {
                    CanonicalVarValues { var_values: ref __binding_0 } => {
                        {
                            match ::rustc_type_ir::VisitorResult::branch(::rustc_type_ir::TypeVisitable::visit_with(__binding_0,
                                        __visitor)) {
                                ::core::ops::ControlFlow::Continue(()) => {}
                                ::core::ops::ControlFlow::Break(r) => {
                                    return ::rustc_type_ir::VisitorResult::from_residual(r);
                                }
                            }
                        }
                    }
                }
                <__V::Result as ::rustc_type_ir::VisitorResult>::output()
            }
        }
    };TypeVisitable_Generic, const _: () =
    {
        unsafe impl<I: Interner, __V>
            ::rustc_type_ir::GenericTypeVisitable<__V> for
            CanonicalVarValues<I> where
            I::GenericArgs: ::rustc_type_ir::GenericTypeVisitable<__V> {
            fn generic_visit_with(&self, __visitor: &mut __V) {
                match *self {
                    CanonicalVarValues { var_values: ref __binding_0 } => {
                        {
                            ::rustc_type_ir::GenericTypeVisitable::<__V>::generic_visit_with(__binding_0,
                                __visitor);
                        }
                    }
                }
            }
        }
    };GenericTypeVisitable, const _: () =
    {
        impl<I: Interner> ::rustc_type_ir::TypeFoldable<I> for
            CanonicalVarValues<I> where I: Interner,
            I::GenericArgs: ::rustc_type_ir::TypeFoldable<I> {
            fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<I>>(self,
                __folder: &mut __F) -> Result<Self, __F::Error> {
                Ok(match self {
                        CanonicalVarValues { var_values: __binding_0 } => {
                            CanonicalVarValues {
                                var_values: ::rustc_type_ir::TypeFoldable::try_fold_with(__binding_0,
                                        __folder)?,
                            }
                        }
                    })
            }
            fn fold_with<__F: ::rustc_type_ir::TypeFolder<I>>(self,
                __folder: &mut __F) -> Self {
                match self {
                    CanonicalVarValues { var_values: __binding_0 } => {
                        CanonicalVarValues {
                            var_values: ::rustc_type_ir::TypeFoldable::fold_with(__binding_0,
                                __folder),
                        }
                    }
                }
            }
        }
    };TypeFoldable_Generic, const _: () =
    {
        impl<I: Interner, J> ::rustc_type_ir::lift::Lift<J> for
            CanonicalVarValues<I> where J: Interner,
            I: ::rustc_type_ir::LiftInto<J> {
            type Lifted = CanonicalVarValues<J>;
            fn lift_to_interner(self, interner: J) -> Self::Lifted {
                match self {
                    CanonicalVarValues { var_values: __binding_0 } => {
                        CanonicalVarValues {
                            var_values: __binding_0.lift_to_interner(interner),
                        }
                    }
                }
            }
        }
    };Lift_Generic)]
255pub struct CanonicalVarValues<I: Interner> {
256    pub var_values: I::GenericArgs,
257}
258
259impl<I: Interner> Eq for CanonicalVarValues<I> {}
260
261impl<I: Interner> CanonicalVarValues<I> {
262    pub fn instantiate(
263        cx: I,
264        var_kinds: I::CanonicalVarKinds,
265        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
266    ) -> CanonicalVarValues<I> {
267        // Instantiating `CanonicalVarValues` is really hot, but limited to less than
268        // 4 most of the time. Avoid creating a `Vec` here.
269        if var_kinds.len() <= 4 {
270            let mut var_values = ArrayVec::<_, 4>::new();
271            for info in var_kinds.iter() {
272                // Note: the `f` call gets all the previously constructed `var_values`.
273                var_values.push(f(&var_values, info));
274            }
275            CanonicalVarValues { var_values: cx.mk_args(&var_values) }
276        } else {
277            CanonicalVarValues::instantiate_cold(cx, var_kinds, f)
278        }
279    }
280
281    #[cold]
282    fn instantiate_cold(
283        cx: I,
284        var_kinds: I::CanonicalVarKinds,
285        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
286    ) -> CanonicalVarValues<I> {
287        let mut var_values = Vec::with_capacity(var_kinds.len());
288        for info in var_kinds.iter() {
289            var_values.push(f(&var_values, info));
290        }
291        CanonicalVarValues { var_values: cx.mk_args(&var_values) }
292    }
293
294    #[inline]
295    pub fn len(&self) -> usize {
296        self.var_values.len()
297    }
298}
299
300impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
301    type Output = I::GenericArg;
302
303    fn index(&self, value: ty::BoundVar) -> &I::GenericArg {
304        &self.var_values.as_slice()[value.as_usize()]
305    }
306}
307
308#[automatically_derived]
impl<I: Interner> ::core::default::Default for CanonicalParamEnvCache<I> where
    I: Interner {
    fn default() -> Self {
        CanonicalParamEnvCache(::core::default::Default::default())
    }
}#[derive_where(Default; I: Interner)]
309pub struct CanonicalParamEnvCache<I: Interner>(
310    pub HashMap<I::ParamEnv, CanonicalParamEnvCacheEntry<I>>,
311);
312
313#[automatically_derived]
impl<I: Interner> ::core::clone::Clone for CanonicalParamEnvCacheEntry<I>
    where I: Interner {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            CanonicalParamEnvCacheEntry {
                param_env: ref __field_param_env,
                variables: ref __field_variables,
                variable_lookup_table: ref __field_variable_lookup_table,
                var_kinds: ref __field_var_kinds } =>
                CanonicalParamEnvCacheEntry {
                    param_env: ::core::clone::Clone::clone(__field_param_env),
                    variables: ::core::clone::Clone::clone(__field_variables),
                    variable_lookup_table: ::core::clone::Clone::clone(__field_variable_lookup_table),
                    var_kinds: ::core::clone::Clone::clone(__field_var_kinds),
                },
        }
    }
}
#[automatically_derived]
impl<I: Interner> ::core::fmt::Debug for CanonicalParamEnvCacheEntry<I> where
    I: Interner {
    fn fmt(&self, __f: &mut ::core::fmt::Formatter<'_>)
        -> ::core::fmt::Result {
        match self {
            CanonicalParamEnvCacheEntry {
                param_env: ref __field_param_env,
                variables: ref __field_variables,
                variable_lookup_table: ref __field_variable_lookup_table,
                var_kinds: ref __field_var_kinds } => {
                let mut __builder =
                    ::core::fmt::Formatter::debug_struct(__f,
                        "CanonicalParamEnvCacheEntry");
                ::core::fmt::DebugStruct::field(&mut __builder, "param_env",
                    __field_param_env);
                ::core::fmt::DebugStruct::field(&mut __builder, "variables",
                    __field_variables);
                ::core::fmt::DebugStruct::field(&mut __builder,
                    "variable_lookup_table", __field_variable_lookup_table);
                ::core::fmt::DebugStruct::field(&mut __builder, "var_kinds",
                    __field_var_kinds);
                ::core::fmt::DebugStruct::finish(&mut __builder)
            }
        }
    }
}#[derive_where(Clone, Debug; I: Interner)]
314pub struct CanonicalParamEnvCacheEntry<I: Interner> {
315    // Note: this `param_env` is the canonicalized form of the key for this entry in the enclosing
316    // `CanonicalParamEnvCache`.
317    pub param_env: I::ParamEnv,
318    pub variables: Vec<I::GenericArg>,
319    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
320    pub var_kinds: I::CanonicalVarKinds,
321}
322
323/// State used and modified by a canonicalizer during canonicalization. To avoid many allocations,
324/// this state is reused by many canonicalizers from `GlobalCaches`.
325#[automatically_derived]
impl<I: Interner> ::core::default::Default for CanonicalizerState<I> where
    I: Interner {
    fn default() -> Self {
        CanonicalizerState {
            variables: ::core::default::Default::default(),
            var_kinds: ::core::default::Default::default(),
            variable_lookup_table: ::core::default::Default::default(),
            sub_root_lookup_table: ::core::default::Default::default(),
            cache: ::core::default::Default::default(),
        }
    }
}#[derive_where(Default; I: Interner)]
326pub struct CanonicalizerState<I: Interner> {
327    pub variables: Vec<I::GenericArg>,
328    pub var_kinds: Vec<CanonicalVarKind<I>>,
329    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
330
331    /// Maps each `sub_unification_table_root_var` to the index of the first
332    /// variable which used it.
333    ///
334    /// This means in case two type variables have the same sub relations root,
335    /// we set the `sub_root` of the second variable to the position of the first.
336    /// Otherwise the `sub_root` of each type variable is just its own position.
337    pub sub_root_lookup_table: HashMap<ty::TyVid, usize>,
338
339    /// We can simply cache based on the ty itself, because we use
340    /// `ty::BoundVarIndexKind::Canonical`.
341    pub cache: DelayedMap<I::Ty, I::Ty>,
342}
343
344impl<I: Interner> CanonicalizerState<I> {
345    pub fn clear(&mut self) {
346        // Deconstruct to ensure no fields are missed.
347        let Self { variables, var_kinds, variable_lookup_table, sub_root_lookup_table, cache } =
348            self;
349
350        // The vectors can be simply cleared because `Vec::clear` is cheap: it just sets the length
351        // to zero. (The elements don't impl `Drop`.)
352        //
353        // The hash maps are different: `HashMap::clear` has to write some control bytes, the
354        // number of which is proportional to capacity. Most of the time the hash map capacity is
355        // small and it's not a problem, but on some benchmarks it can occasionally get very big.
356        // In which case we just start over with a fresh hash map so we aren't saddled with a high
357        // `clear` cost forevermore.
358
359        variables.clear();
360        var_kinds.clear();
361        if variable_lookup_table.capacity() <= 128 {
362            variable_lookup_table.clear();
363        } else {
364            *variable_lookup_table = HashMap::default();
365        }
366        if sub_root_lookup_table.capacity() <= 128 {
367            sub_root_lookup_table.clear();
368        } else {
369            *sub_root_lookup_table = HashMap::default();
370        }
371        if cache.capacity() <= 128 {
372            cache.clear();
373        } else {
374            *cache = Default::default();
375        }
376    }
377}