Skip to main content

rustc_type_ir/
canonical.rs

1use std::fmt;
2
3use arrayvec::ArrayVec;
4use derive_where::derive_where;
5#[cfg(feature = "nightly")]
6use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext};
7use rustc_type_ir_macros::{
8    GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic,
9};
10use thin_vec::ThinVec;
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
76impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        let Self { value, max_universe, var_kinds } = self;
79        f.write_fmt(format_args!("Canonical {{ value: {0}, max_universe: {1:?}, var_kinds: {2:?} }}",
        value, max_universe, var_kinds))write!(
80            f,
81            "Canonical {{ value: {value}, max_universe: {max_universe:?}, var_kinds: {var_kinds:?} }}",
82        )
83    }
84}
85
86/// Information about a canonical variable that is included with the
87/// canonical value. This is sufficient information for code to create
88/// a copy of the canonical value in some other inference context,
89/// with fresh inference variables replacing the canonical values.
90#[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)]
91#[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)]
92#[cfg_attr(
93    feature = "nightly",
94    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) {
                ::std::mem::discriminant(self).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)
95)]
96pub enum CanonicalVarKind<I: Interner> {
97    /// General type variable `?T` that can be unified with arbitrary types.
98    ///
99    /// We also store the index of the first type variable which is sub-unified
100    /// with this one. If there is no inference variable related to this one,
101    /// its `sub_root` just points to itself.
102    Ty { ui: UniverseIndex, sub_root: ty::BoundVar },
103
104    /// Integral type variable `?I` (that can only be unified with integral types).
105    Int,
106
107    /// Floating-point type variable `?F` (that can only be unified with float types).
108    Float,
109
110    /// A "placeholder" that represents "any type".
111    PlaceholderTy(ty::PlaceholderType<I>),
112
113    /// Region variable `'?R`.
114    Region(UniverseIndex),
115
116    /// A "placeholder" that represents "any region". Created when you
117    /// are solving a goal like `for<'a> T: Foo<'a>` to represent the
118    /// bound region `'a`.
119    PlaceholderRegion(ty::PlaceholderRegion<I>),
120
121    /// Some kind of const inference variable.
122    Const(UniverseIndex),
123
124    /// A "placeholder" that represents "any const".
125    PlaceholderConst(ty::PlaceholderConst<I>),
126}
127
128impl<I: Interner> Eq for CanonicalVarKind<I> {}
129
130impl<I: Interner> CanonicalVarKind<I> {
131    pub fn universe(self) -> UniverseIndex {
132        match self {
133            CanonicalVarKind::Ty { ui, sub_root: _ } => ui,
134            CanonicalVarKind::Region(ui) => ui,
135            CanonicalVarKind::Const(ui) => ui,
136            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
137            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
138            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
139            CanonicalVarKind::Float | CanonicalVarKind::Int => UniverseIndex::ROOT,
140        }
141    }
142
143    /// Replaces the universe of this canonical variable with `ui`.
144    ///
145    /// In case this is a float or int variable, this causes an ICE if
146    /// the updated universe is not the root.
147    pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
148        match self {
149            CanonicalVarKind::Ty { ui: _, sub_root } => CanonicalVarKind::Ty { ui, sub_root },
150            CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
151            CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
152
153            CanonicalVarKind::PlaceholderTy(placeholder) => {
154                CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
155            }
156            CanonicalVarKind::PlaceholderRegion(placeholder) => {
157                CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
158            }
159            CanonicalVarKind::PlaceholderConst(placeholder) => {
160                CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
161            }
162            CanonicalVarKind::Int | CanonicalVarKind::Float => {
163                {
    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);
164                self
165            }
166        }
167    }
168
169    pub fn is_existential(self) -> bool {
170        match self {
171            CanonicalVarKind::Ty { .. }
172            | CanonicalVarKind::Int
173            | CanonicalVarKind::Float
174            | CanonicalVarKind::Region(_)
175            | CanonicalVarKind::Const(_) => true,
176            CanonicalVarKind::PlaceholderTy(_)
177            | CanonicalVarKind::PlaceholderRegion(..)
178            | CanonicalVarKind::PlaceholderConst(_) => false,
179        }
180    }
181
182    pub fn is_region(self) -> bool {
183        match self {
184            CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
185            CanonicalVarKind::Ty { .. }
186            | CanonicalVarKind::Int
187            | CanonicalVarKind::Float
188            | CanonicalVarKind::PlaceholderTy(_)
189            | CanonicalVarKind::Const(_)
190            | CanonicalVarKind::PlaceholderConst(_) => false,
191        }
192    }
193
194    pub fn expect_placeholder_index(self) -> usize {
195        match self {
196            CanonicalVarKind::Ty { .. }
197            | CanonicalVarKind::Int
198            | CanonicalVarKind::Float
199            | CanonicalVarKind::Region(_)
200            | CanonicalVarKind::Const(_) => {
201                {
    ::core::panicking::panic_fmt(format_args!("expected placeholder: {0:?}",
            self));
}panic!("expected placeholder: {self:?}")
202            }
203
204            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
205            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
206            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
207        }
208    }
209}
210
211/// A set of values corresponding to the canonical variables from some
212/// `Canonical`. You can give these values to
213/// `canonical_value.instantiate` to instantiate them into the canonical
214/// value at the right places.
215///
216/// When you canonicalize a value `V`, you get back one of these
217/// vectors with the original values that were replaced by canonical
218/// variables. You will need to supply it later to instantiate the
219/// canonicalized query response.
220#[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)]
221#[cfg_attr(
222    feature = "nightly",
223    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)
224)]
225#[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)]
226pub struct CanonicalVarValues<I: Interner> {
227    pub var_values: I::GenericArgs,
228}
229
230impl<I: Interner> Eq for CanonicalVarValues<I> {}
231
232impl<I: Interner> CanonicalVarValues<I> {
233    pub fn instantiate(
234        cx: I,
235        var_kinds: I::CanonicalVarKinds,
236        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
237    ) -> CanonicalVarValues<I> {
238        // Instantiating `CanonicalVarValues` is really hot, but limited to less than
239        // 4 most of the time. Avoid creating a `Vec` here.
240        if var_kinds.len() <= 4 {
241            let mut var_values = ArrayVec::<_, 4>::new();
242            for info in var_kinds.iter() {
243                var_values.push(f(&var_values, info));
244            }
245            CanonicalVarValues { var_values: cx.mk_args(&var_values) }
246        } else {
247            CanonicalVarValues::instantiate_cold(cx, var_kinds, f)
248        }
249    }
250
251    #[cold]
252    fn instantiate_cold(
253        cx: I,
254        var_kinds: I::CanonicalVarKinds,
255        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
256    ) -> CanonicalVarValues<I> {
257        let mut var_values = Vec::with_capacity(var_kinds.len());
258        for info in var_kinds.iter() {
259            var_values.push(f(&var_values, info));
260        }
261        CanonicalVarValues { var_values: cx.mk_args(&var_values) }
262    }
263
264    #[inline]
265    pub fn len(&self) -> usize {
266        self.var_values.len()
267    }
268}
269
270#[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)]
271pub struct CanonicalParamEnvCache<I: Interner>(
272    pub HashMap<I::ParamEnv, CanonicalParamEnvCacheEntry<I>>,
273);
274
275#[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)]
276pub struct CanonicalParamEnvCacheEntry<I: Interner> {
277    // Note: this `param_env` is the canonicalized form of the key for this entry in the enclosing
278    // `CanonicalParamEnvCache`.
279    pub param_env: I::ParamEnv,
280    pub variables: ThinVec<I::GenericArg>,
281    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
282    pub var_kinds: Vec<CanonicalVarKind<I>>,
283}
284
285/// State used and modified by a canonicalizer during canonicalization. To avoid many allocations,
286/// this state is reused by many canonicalizers from a single `InferCtxt`.
287#[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)]
288pub struct CanonicalizerState<I: Interner> {
289    pub variables: ThinVec<I::GenericArg>,
290    pub var_kinds: Vec<CanonicalVarKind<I>>,
291    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
292
293    /// Maps each `sub_unification_table_root_var` to the index of the first
294    /// variable which used it.
295    ///
296    /// This means in case two type variables have the same sub relations root,
297    /// we set the `sub_root` of the second variable to the position of the first.
298    /// Otherwise the `sub_root` of each type variable is just its own position.
299    pub sub_root_lookup_table: HashMap<ty::TyVid, usize>,
300
301    /// We can simply cache based on the ty itself, because we use
302    /// `ty::BoundVarIndexKind::Canonical`.
303    pub cache: DelayedMap<I::Ty, I::Ty>,
304}
305
306impl<I: Interner> CanonicalizerState<I> {
307    pub fn clear(&mut self) {
308        // Deconstruct to ensure no fields are missed.
309        let Self { variables, var_kinds, variable_lookup_table, sub_root_lookup_table, cache } =
310            self;
311        variables.clear();
312        var_kinds.clear();
313        variable_lookup_table.clear();
314        sub_root_lookup_table.clear();
315        cache.clear();
316    }
317}