1use std::cmp;
2use std::marker::PhantomData;
3
4use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue};
5use rustc_middle::{bug, ty};
6use rustc_span::Span;
7use rustc_span::def_id::DefId;
8
9#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for RegionVariableValue<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for RegionVariableValue<'tcx> {
#[inline]
fn clone(&self) -> RegionVariableValue<'tcx> {
let _: ::core::clone::AssertParamIsClone<ty::Region<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ty::UniverseIndex>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for RegionVariableValue<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
RegionVariableValue::Known { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Known",
"value", &__self_0),
RegionVariableValue::Unknown { universe: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Unknown", "universe", &__self_0),
}
}
}Debug)]
10pub(crate) enum RegionVariableValue<'tcx> {
11 Known { value: ty::Region<'tcx> },
12 Unknown { universe: ty::UniverseIndex },
13}
14
15#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for RegionVidKey<'tcx> {
#[inline]
fn eq(&self, other: &RegionVidKey<'tcx>) -> bool {
self.vid == other.vid && self.phantom == other.phantom
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for RegionVidKey<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for RegionVidKey<'tcx> {
#[inline]
fn clone(&self) -> RegionVidKey<'tcx> {
let _: ::core::clone::AssertParamIsClone<ty::RegionVid>;
let _:
::core::clone::AssertParamIsClone<PhantomData<RegionVariableValue<'tcx>>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for RegionVidKey<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "RegionVidKey",
"vid", &self.vid, "phantom", &&self.phantom)
}
}Debug)]
16pub(crate) struct RegionVidKey<'tcx> {
17 pub vid: ty::RegionVid,
18 pub phantom: PhantomData<RegionVariableValue<'tcx>>,
19}
20
21impl<'tcx> From<ty::RegionVid> for RegionVidKey<'tcx> {
22 fn from(vid: ty::RegionVid) -> Self {
23 RegionVidKey { vid, phantom: PhantomData }
24 }
25}
26
27impl<'tcx> UnifyKey for RegionVidKey<'tcx> {
28 type Value = RegionVariableValue<'tcx>;
29 #[inline]
30 fn index(&self) -> u32 {
31 self.vid.as_u32()
32 }
33 #[inline]
34 fn from_index(i: u32) -> Self {
35 RegionVidKey::from(ty::RegionVid::from_u32(i))
36 }
37 fn tag() -> &'static str {
38 "RegionVidKey"
39 }
40}
41
42pub(crate) struct RegionUnificationError;
43
44impl<'tcx> UnifyValue for RegionVariableValue<'tcx> {
45 type Error = RegionUnificationError;
46
47 fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
48 match (*value1, *value2) {
49 (RegionVariableValue::Known { .. }, RegionVariableValue::Known { .. }) => {
50 Err(RegionUnificationError)
51 }
52
53 (RegionVariableValue::Known { value }, RegionVariableValue::Unknown { universe })
54 | (RegionVariableValue::Unknown { universe }, RegionVariableValue::Known { value }) => {
55 let universe_of_value = match value.kind() {
56 ty::ReStatic
57 | ty::ReErased
58 | ty::ReLateParam(..)
59 | ty::ReEarlyParam(..)
60 | ty::ReError(_) => ty::UniverseIndex::ROOT,
61 ty::RePlaceholder(placeholder) => placeholder.universe,
62 ty::ReVar(..) | ty::ReBound(..) => ::rustc_middle::util::bug::bug_fmt(format_args!("not a universal region"))bug!("not a universal region"),
63 };
64
65 if universe.can_name(universe_of_value) {
66 Ok(RegionVariableValue::Known { value })
67 } else {
68 Err(RegionUnificationError)
69 }
70 }
71
72 (
73 RegionVariableValue::Unknown { universe: a },
74 RegionVariableValue::Unknown { universe: b },
75 ) => {
76 Ok(RegionVariableValue::Unknown { universe: a.min(b) })
82 }
83 }
84 }
85}
86
87#[derive(#[automatically_derived]
impl ::core::marker::Copy for ConstVariableOrigin { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ConstVariableOrigin {
#[inline]
fn clone(&self) -> ConstVariableOrigin {
let _: ::core::clone::AssertParamIsClone<Span>;
let _: ::core::clone::AssertParamIsClone<Option<DefId>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ConstVariableOrigin {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ConstVariableOrigin", "span", &self.span, "param_def_id",
&&self.param_def_id)
}
}Debug)]
90pub struct ConstVariableOrigin {
91 pub span: Span,
92 pub param_def_id: Option<DefId>,
96}
97
98#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for ConstVariableValue<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ConstVariableValue<'tcx> {
#[inline]
fn clone(&self) -> ConstVariableValue<'tcx> {
let _: ::core::clone::AssertParamIsClone<ty::Const<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ConstVariableOrigin>;
let _: ::core::clone::AssertParamIsClone<ty::UniverseIndex>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ConstVariableValue<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ConstVariableValue::Known { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Known",
"value", &__self_0),
ConstVariableValue::Unknown { origin: __self_0, universe: __self_1
} =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"Unknown", "origin", __self_0, "universe", &__self_1),
}
}
}Debug)]
99pub(crate) enum ConstVariableValue<'tcx> {
100 Known { value: ty::Const<'tcx> },
101 Unknown { origin: ConstVariableOrigin, universe: ty::UniverseIndex },
102}
103
104impl<'tcx> ConstVariableValue<'tcx> {
105 pub(crate) fn known(&self) -> Option<ty::Const<'tcx>> {
108 match *self {
109 ConstVariableValue::Unknown { .. } => None,
110 ConstVariableValue::Known { value } => Some(value),
111 }
112 }
113}
114
115#[derive(#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for ConstVidKey<'tcx> {
#[inline]
fn eq(&self, other: &ConstVidKey<'tcx>) -> bool {
self.vid == other.vid && self.phantom == other.phantom
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ConstVidKey<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ConstVidKey<'tcx> {
#[inline]
fn clone(&self) -> ConstVidKey<'tcx> {
let _: ::core::clone::AssertParamIsClone<ty::ConstVid>;
let _:
::core::clone::AssertParamIsClone<PhantomData<ty::Const<'tcx>>>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ConstVidKey<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "ConstVidKey",
"vid", &self.vid, "phantom", &&self.phantom)
}
}Debug)]
116pub(crate) struct ConstVidKey<'tcx> {
117 pub vid: ty::ConstVid,
118 pub phantom: PhantomData<ty::Const<'tcx>>,
119}
120
121impl<'tcx> From<ty::ConstVid> for ConstVidKey<'tcx> {
122 fn from(vid: ty::ConstVid) -> Self {
123 ConstVidKey { vid, phantom: PhantomData }
124 }
125}
126
127impl<'tcx> UnifyKey for ConstVidKey<'tcx> {
128 type Value = ConstVariableValue<'tcx>;
129 #[inline]
130 fn index(&self) -> u32 {
131 self.vid.as_u32()
132 }
133 #[inline]
134 fn from_index(i: u32) -> Self {
135 ConstVidKey::from(ty::ConstVid::from_u32(i))
136 }
137 fn tag() -> &'static str {
138 "ConstVidKey"
139 }
140 fn order_roots(a: Self, _: &Self::Value, b: Self, _: &Self::Value) -> Option<(Self, Self)> {
141 if a.vid.as_u32() < b.vid.as_u32() { Some((a, b)) } else { Some((b, a)) }
142 }
143}
144
145impl<'tcx> UnifyValue for ConstVariableValue<'tcx> {
146 type Error = NoError;
147
148 fn unify_values(&value1: &Self, &value2: &Self) -> Result<Self, Self::Error> {
149 match (value1, value2) {
150 (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => {
151 ::rustc_middle::util::bug::bug_fmt(format_args!("equating two const variables, both of which have known values"))bug!("equating two const variables, both of which have known values")
152 }
153
154 (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => Ok(value1),
156 (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => Ok(value2),
157
158 (
160 ConstVariableValue::Unknown { origin, universe: universe1 },
161 ConstVariableValue::Unknown { origin: _, universe: universe2 },
162 ) => {
163 let universe = cmp::min(universe1, universe2);
169 Ok(ConstVariableValue::Unknown { origin, universe })
170 }
171 }
172 }
173}