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#[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 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#[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 Ty { ui: UniverseIndex, sub_root: ty::BoundVar },
104
105 Int,
107
108 Float,
110
111 PlaceholderTy(ty::PlaceholderType<I>),
113
114 Region(UniverseIndex),
116
117 PlaceholderRegion(ty::PlaceholderRegion<I>),
121
122 Const(UniverseIndex),
124
125 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 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#[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 }
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 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 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 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}