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};
11use thin_vec::ThinVec;
12
13use crate::data_structures::HashMap;
14use crate::inherent::*;
15use crate::{self as ty, Interner, Region, TypingModeEqWrapper, UniverseIndex};
16
17#[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)]
18#[derive_where(Copy; I: Interner, V: Copy)]
19#[cfg_attr(
20    feature = "nightly",
21    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) {
                match *self {
                    CanonicalQueryInput {
                        canonical: ref __binding_0, typing_mode: ref __binding_1 }
                        => {
                        ::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)
22)]
23pub struct CanonicalQueryInput<I: Interner, V> {
24    pub canonical: Canonical<I, V>,
25    pub typing_mode: TypingModeEqWrapper<I>,
26}
27
28impl<I: Interner, V: Eq> Eq for CanonicalQueryInput<I, V> {}
29
30/// A "canonicalized" type `V` is one where all free inference
31/// variables have been rewritten to "canonical vars". These are
32/// numbered starting from 0 in order of first appearance.
33#[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)]
34#[derive_where(Copy; I: Interner, V: Copy)]
35#[cfg_attr(
36    feature = "nightly",
37    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) {
                match *self {
                    Canonical {
                        value: ref __binding_0,
                        max_universe: ref __binding_1,
                        var_kinds: ref __binding_2 } => {
                        ::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)
38)]
39pub struct Canonical<I: Interner, V> {
40    pub value: V,
41    pub max_universe: UniverseIndex,
42    pub var_kinds: I::CanonicalVarKinds,
43}
44
45impl<I: Interner, V: Eq> Eq for Canonical<I, V> {}
46
47impl<I: Interner, V> Canonical<I, V> {
48    /// Allows you to map the `value` of a canonical while keeping the
49    /// same set of bound variables.
50    ///
51    /// **WARNING:** This function is very easy to mis-use, hence the
52    /// name!  In particular, the new value `W` must use all **the
53    /// same type/region variables** in **precisely the same order**
54    /// as the original! (The ordering is defined by the
55    /// `TypeFoldable` implementation of the type in question.)
56    ///
57    /// An example of a **correct** use of this:
58    ///
59    /// ```rust,ignore (not real code)
60    /// let a: Canonical<I, T> = ...;
61    /// let b: Canonical<I, (T,)> = a.unchecked_map(|v| (v, ));
62    /// ```
63    ///
64    /// An example of an **incorrect** use of this:
65    ///
66    /// ```rust,ignore (not real code)
67    /// let a: Canonical<I, T> = ...;
68    /// let ty: Ty<I> = ...;
69    /// let b: Canonical<I, (T, Ty<I>)> = a.unchecked_map(|v| (v, ty));
70    /// ```
71    pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<I, W> {
72        let Canonical { max_universe, var_kinds, value } = self;
73        Canonical { max_universe, var_kinds, value: map_op(value) }
74    }
75}
76
77impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        let Self { value, max_universe, var_kinds } = self;
80        f.write_fmt(format_args!("Canonical {{ value: {0}, max_universe: {1:?}, var_kinds: {2:?} }}",
        value, max_universe, var_kinds))write!(
81            f,
82            "Canonical {{ value: {value}, max_universe: {max_universe:?}, var_kinds: {var_kinds:?} }}",
83        )
84    }
85}
86
87/// Information about a canonical variable that is included with the
88/// canonical value. This is sufficient information for code to create
89/// a copy of the canonical value in some other inference context,
90/// with fresh inference variables replacing the canonical values.
91#[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)]
92#[derive(GenericTypeVisitable)]
93#[cfg_attr(
94    feature = "nightly",
95    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)
96)]
97pub enum CanonicalVarKind<I: Interner> {
98    /// General type variable `?T` that can be unified with arbitrary types.
99    ///
100    /// We also store the index of the first type variable which is sub-unified
101    /// with this one. If there is no inference variable related to this one,
102    /// its `sub_root` just points to itself.
103    Ty { ui: UniverseIndex, sub_root: ty::BoundVar },
104
105    /// Integral type variable `?I` (that can only be unified with integral types).
106    Int,
107
108    /// Floating-point type variable `?F` (that can only be unified with float types).
109    Float,
110
111    /// A "placeholder" that represents "any type".
112    PlaceholderTy(ty::PlaceholderType<I>),
113
114    /// Region variable `'?R`.
115    Region(UniverseIndex),
116
117    /// A "placeholder" that represents "any region". Created when you
118    /// are solving a goal like `for<'a> T: Foo<'a>` to represent the
119    /// bound region `'a`.
120    PlaceholderRegion(ty::PlaceholderRegion<I>),
121
122    /// Some kind of const inference variable.
123    Const(UniverseIndex),
124
125    /// A "placeholder" that represents "any const".
126    PlaceholderConst(ty::PlaceholderConst<I>),
127}
128
129impl<I: Interner> Eq for CanonicalVarKind<I> {}
130
131impl<I: Interner> CanonicalVarKind<I> {
132    pub fn universe(self) -> UniverseIndex {
133        match self {
134            CanonicalVarKind::Ty { ui, sub_root: _ } => ui,
135            CanonicalVarKind::Region(ui) => ui,
136            CanonicalVarKind::Const(ui) => ui,
137            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
138            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
139            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
140            CanonicalVarKind::Float | CanonicalVarKind::Int => UniverseIndex::ROOT,
141        }
142    }
143
144    /// Replaces the universe of this canonical variable with `ui`.
145    ///
146    /// In case this is a float or int variable, this causes an ICE if
147    /// the updated universe is not the root.
148    pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
149        match self {
150            CanonicalVarKind::Ty { ui: _, sub_root } => CanonicalVarKind::Ty { ui, sub_root },
151            CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
152            CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
153
154            CanonicalVarKind::PlaceholderTy(placeholder) => {
155                CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui))
156            }
157            CanonicalVarKind::PlaceholderRegion(placeholder) => {
158                CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui))
159            }
160            CanonicalVarKind::PlaceholderConst(placeholder) => {
161                CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
162            }
163            CanonicalVarKind::Int | CanonicalVarKind::Float => {
164                {
    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);
165                self
166            }
167        }
168    }
169
170    pub fn is_existential(self) -> bool {
171        match self {
172            CanonicalVarKind::Ty { .. }
173            | CanonicalVarKind::Int
174            | CanonicalVarKind::Float
175            | CanonicalVarKind::Region(_)
176            | CanonicalVarKind::Const(_) => true,
177            CanonicalVarKind::PlaceholderTy(_)
178            | CanonicalVarKind::PlaceholderRegion(..)
179            | CanonicalVarKind::PlaceholderConst(_) => false,
180        }
181    }
182
183    pub fn is_region(self) -> bool {
184        match self {
185            CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
186            CanonicalVarKind::Ty { .. }
187            | CanonicalVarKind::Int
188            | CanonicalVarKind::Float
189            | CanonicalVarKind::PlaceholderTy(_)
190            | CanonicalVarKind::Const(_)
191            | CanonicalVarKind::PlaceholderConst(_) => false,
192        }
193    }
194
195    pub fn expect_placeholder_index(self) -> usize {
196        match self {
197            CanonicalVarKind::Ty { .. }
198            | CanonicalVarKind::Int
199            | CanonicalVarKind::Float
200            | CanonicalVarKind::Region(_)
201            | CanonicalVarKind::Const(_) => {
202                {
    ::core::panicking::panic_fmt(format_args!("expected placeholder: {0:?}",
            self));
}panic!("expected placeholder: {self:?}")
203            }
204
205            CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(),
206            CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(),
207            CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.var().as_usize(),
208        }
209    }
210}
211
212/// A set of values corresponding to the canonical variables from some
213/// `Canonical`. You can give these values to
214/// `canonical_value.instantiate` to instantiate them into the canonical
215/// value at the right places.
216///
217/// When you canonicalize a value `V`, you get back one of these
218/// vectors with the original values that were replaced by canonical
219/// variables. You will need to supply it later to instantiate the
220/// canonicalized query response.
221#[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)]
222#[cfg_attr(
223    feature = "nightly",
224    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) {
                match *self {
                    CanonicalVarValues { var_values: ref __binding_0 } => {
                        ::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)
225)]
226#[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, 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)]
227pub struct CanonicalVarValues<I: Interner> {
228    pub var_values: I::GenericArgs,
229}
230
231impl<I: Interner> Eq for CanonicalVarValues<I> {}
232
233impl<I: Interner> CanonicalVarValues<I> {
234    pub fn is_identity(&self) -> bool {
235        self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
236            ty::GenericArgKind::Lifetime(r) => {
237                #[allow(non_exhaustive_omitted_patterns)] match r.kind() {
    ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if
        br.var().as_usize() == bv => true,
    _ => false,
}matches!(r.kind(), ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if br.var().as_usize() == bv)
238            }
239            ty::GenericArgKind::Type(ty) => {
240                #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if
        bt.var().as_usize() == bv => true,
    _ => false,
}matches!(ty.kind(), ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if bt.var().as_usize() == bv)
241            }
242            ty::GenericArgKind::Const(ct) => {
243                #[allow(non_exhaustive_omitted_patterns)] match ct.kind() {
    ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if
        bc.var().as_usize() == bv => true,
    _ => false,
}matches!(ct.kind(), ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if bc.var().as_usize() == bv)
244            }
245        })
246    }
247
248    pub fn is_identity_modulo_regions(&self) -> bool {
249        let mut var = ty::BoundVar::ZERO;
250        for arg in self.var_values.iter() {
251            match arg.kind() {
252                ty::GenericArgKind::Lifetime(r) => {
253                    if #[allow(non_exhaustive_omitted_patterns)] match r.kind() {
    ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if var == br.var() =>
        true,
    _ => false,
}matches!(r.kind(), ty::ReBound(ty::BoundVarIndexKind::Canonical, br) if var == br.var())
254                    {
255                        var = var + 1;
256                    } else {
257                        // It's ok if this region var isn't an identity variable
258                    }
259                }
260                ty::GenericArgKind::Type(ty) => {
261                    if #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if var == bt.var() =>
        true,
    _ => false,
}matches!(ty.kind(), ty::Bound(ty::BoundVarIndexKind::Canonical, bt) if var == bt.var())
262                    {
263                        var = var + 1;
264                    } else {
265                        return false;
266                    }
267                }
268                ty::GenericArgKind::Const(ct) => {
269                    if #[allow(non_exhaustive_omitted_patterns)] match ct.kind() {
    ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if
        var == bc.var() => true,
    _ => false,
}matches!(ct.kind(), ty::ConstKind::Bound(ty::BoundVarIndexKind::Canonical, bc) if var == bc.var())
270                    {
271                        var = var + 1;
272                    } else {
273                        return false;
274                    }
275                }
276            }
277        }
278
279        true
280    }
281
282    // Given a list of canonical variables, construct a set of values which are
283    // the identity response.
284    pub fn make_identity(cx: I, infos: I::CanonicalVarKinds) -> CanonicalVarValues<I> {
285        CanonicalVarValues {
286            var_values: cx.mk_args_from_iter(infos.iter().enumerate().map(
287                |(i, kind)| -> I::GenericArg {
288                    match kind {
289                        CanonicalVarKind::Ty { .. }
290                        | CanonicalVarKind::Int
291                        | CanonicalVarKind::Float
292                        | CanonicalVarKind::PlaceholderTy(_) => {
293                            Ty::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
294                        }
295                        CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
296                            Region::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
297                        }
298                        CanonicalVarKind::Const(_) | CanonicalVarKind::PlaceholderConst(_) => {
299                            Const::new_canonical_bound(cx, ty::BoundVar::from_usize(i)).into()
300                        }
301                    }
302                },
303            )),
304        }
305    }
306
307    /// Creates dummy var values which should not be used in a
308    /// canonical response.
309    pub fn dummy() -> CanonicalVarValues<I> {
310        CanonicalVarValues { var_values: Default::default() }
311    }
312
313    pub fn instantiate(
314        cx: I,
315        var_kinds: I::CanonicalVarKinds,
316        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
317    ) -> CanonicalVarValues<I> {
318        // Instantiating `CanonicalVarValues` is really hot, but limited to less than
319        // 4 most of the time. Avoid creating a `Vec` here.
320        if var_kinds.len() <= 4 {
321            let mut var_values = ArrayVec::<_, 4>::new();
322            for info in var_kinds.iter() {
323                var_values.push(f(&var_values, info));
324            }
325            CanonicalVarValues { var_values: cx.mk_args(&var_values) }
326        } else {
327            CanonicalVarValues::instantiate_cold(cx, var_kinds, f)
328        }
329    }
330
331    #[cold]
332    fn instantiate_cold(
333        cx: I,
334        var_kinds: I::CanonicalVarKinds,
335        mut f: impl FnMut(&[I::GenericArg], CanonicalVarKind<I>) -> I::GenericArg,
336    ) -> CanonicalVarValues<I> {
337        let mut var_values = Vec::with_capacity(var_kinds.len());
338        for info in var_kinds.iter() {
339            var_values.push(f(&var_values, info));
340        }
341        CanonicalVarValues { var_values: cx.mk_args(&var_values) }
342    }
343
344    #[inline]
345    pub fn len(&self) -> usize {
346        self.var_values.len()
347    }
348}
349
350impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> {
351    type Item = I::GenericArg;
352    type IntoIter = <I::GenericArgs as SliceLike>::IntoIter;
353
354    fn into_iter(self) -> Self::IntoIter {
355        self.var_values.iter()
356    }
357}
358
359impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
360    type Output = I::GenericArg;
361
362    fn index(&self, value: ty::BoundVar) -> &I::GenericArg {
363        &self.var_values.as_slice()[value.as_usize()]
364    }
365}
366
367#[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)]
368pub struct CanonicalParamEnvCacheEntry<I: Interner> {
369    pub param_env: I::ParamEnv,
370    pub variables: ThinVec<I::GenericArg>,
371    pub variable_lookup_table: HashMap<I::GenericArg, usize>,
372    pub var_kinds: Vec<CanonicalVarKind<I>>,
373}