1 use crate::ty
::{self, FloatVarValue, InferConst, IntVarValue, Ty, TyCtxt}
;
2 use rustc_data_structures
::unify
::InPlace
;
3 use rustc_data_structures
::unify
::{EqUnifyValue, NoError, UnificationTable, UnifyKey, UnifyValue}
;
4 use rustc_span
::symbol
::Symbol
;
5 use rustc_span
::{Span, DUMMY_SP}
;
8 use std
::marker
::PhantomData
;
11 fn to_type
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
>;
14 /// Raw `TyVid` are used as the unification key for `sub_relations`;
15 /// they carry no values.
16 impl UnifyKey
for ty
::TyVid
{
18 fn index(&self) -> u32 {
21 fn from_index(i
: u32) -> ty
::TyVid
{
22 ty
::TyVid { index: i }
24 fn tag() -> &'
static str {
29 impl UnifyKey
for ty
::IntVid
{
30 type Value
= Option
<IntVarValue
>;
31 fn index(&self) -> u32 {
34 fn from_index(i
: u32) -> ty
::IntVid
{
35 ty
::IntVid { index: i }
37 fn tag() -> &'
static str {
42 impl EqUnifyValue
for IntVarValue {}
44 #[derive(PartialEq, Copy, Clone, Debug)]
45 pub struct RegionVidKey
{
46 /// The minimum region vid in the unification set. This is needed
47 /// to have a canonical name for a type to prevent infinite
49 pub min_vid
: ty
::RegionVid
,
52 impl UnifyValue
for RegionVidKey
{
55 fn unify_values(value1
: &Self, value2
: &Self) -> Result
<Self, NoError
> {
56 let min_vid
= if value1
.min_vid
.index() < value2
.min_vid
.index() {
62 Ok(RegionVidKey { min_vid }
)
66 impl UnifyKey
for ty
::RegionVid
{
67 type Value
= RegionVidKey
;
68 fn index(&self) -> u32 {
71 fn from_index(i
: u32) -> ty
::RegionVid
{
72 ty
::RegionVid
::from(i
)
74 fn tag() -> &'
static str {
79 impl ToType
for IntVarValue
{
80 fn to_type
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
> {
82 ty
::IntType(i
) => tcx
.mk_mach_int(i
),
83 ty
::UintType(i
) => tcx
.mk_mach_uint(i
),
88 // Floating point type keys
90 impl UnifyKey
for ty
::FloatVid
{
91 type Value
= Option
<FloatVarValue
>;
92 fn index(&self) -> u32 {
95 fn from_index(i
: u32) -> ty
::FloatVid
{
96 ty
::FloatVid { index: i }
98 fn tag() -> &'
static str {
103 impl EqUnifyValue
for FloatVarValue {}
105 impl ToType
for FloatVarValue
{
106 fn to_type
<'tcx
>(&self, tcx
: TyCtxt
<'tcx
>) -> Ty
<'tcx
> {
107 tcx
.mk_mach_float(self.0)
113 #[derive(Copy, Clone, Debug)]
114 pub struct ConstVariableOrigin
{
115 pub kind
: ConstVariableOriginKind
,
119 /// Reasons to create a const inference variable
120 #[derive(Copy, Clone, Debug)]
121 pub enum ConstVariableOriginKind
{
124 ConstParameterDefinition(Symbol
),
125 SubstitutionPlaceholder
,
128 #[derive(Copy, Clone, Debug)]
129 pub enum ConstVariableValue
<'tcx
> {
130 Known { value: &'tcx ty::Const<'tcx> }
,
131 Unknown { universe: ty::UniverseIndex }
,
134 impl<'tcx
> ConstVariableValue
<'tcx
> {
135 /// If this value is known, returns the const it is known to be.
136 /// Otherwise, `None`.
137 pub fn known(&self) -> Option
<&'tcx ty
::Const
<'tcx
>> {
139 ConstVariableValue
::Unknown { .. }
=> None
,
140 ConstVariableValue
::Known { value }
=> Some(value
),
144 pub fn is_unknown(&self) -> bool
{
146 ConstVariableValue
::Unknown { .. }
=> true,
147 ConstVariableValue
::Known { .. }
=> false,
152 #[derive(Copy, Clone, Debug)]
153 pub struct ConstVarValue
<'tcx
> {
154 pub origin
: ConstVariableOrigin
,
155 pub val
: ConstVariableValue
<'tcx
>,
158 impl<'tcx
> UnifyKey
for ty
::ConstVid
<'tcx
> {
159 type Value
= ConstVarValue
<'tcx
>;
160 fn index(&self) -> u32 {
163 fn from_index(i
: u32) -> Self {
164 ty
::ConstVid { index: i, phantom: PhantomData }
166 fn tag() -> &'
static str {
171 impl<'tcx
> UnifyValue
for ConstVarValue
<'tcx
> {
172 type Error
= (&'tcx ty
::Const
<'tcx
>, &'tcx ty
::Const
<'tcx
>);
174 fn unify_values(value1
: &Self, value2
: &Self) -> Result
<Self, Self::Error
> {
175 let val
= match (value1
.val
, value2
.val
) {
176 (ConstVariableValue
::Known { .. }
, ConstVariableValue
::Known { .. }
) => {
177 bug
!("equating two const variables, both of which have known values")
180 // If one side is known, prefer that one.
181 (ConstVariableValue
::Known { .. }
, ConstVariableValue
::Unknown { .. }
) => {
184 (ConstVariableValue
::Unknown { .. }
, ConstVariableValue
::Known { .. }
) => {
188 // If both sides are *unknown*, it hardly matters, does it?
190 ConstVariableValue
::Unknown { universe: universe1 }
,
191 ConstVariableValue
::Unknown { universe: universe2 }
,
193 // If we unify two unbound variables, ?T and ?U, then whatever
194 // value they wind up taking (which must be the same value) must
195 // be nameable by both universes. Therefore, the resulting
196 // universe is the minimum of the two universes, because that is
197 // the one which contains the fewest names in scope.
198 let universe
= cmp
::min(universe1
, universe2
);
199 Ok(ConstVariableValue
::Unknown { universe }
)
204 origin
: ConstVariableOrigin
{
205 kind
: ConstVariableOriginKind
::ConstInference
,
213 impl<'tcx
> EqUnifyValue
for &'tcx ty
::Const
<'tcx
> {}
215 pub fn replace_if_possible(
216 table
: &mut UnificationTable
<InPlace
<ty
::ConstVid
<'tcx
>>>,
217 c
: &'tcx ty
::Const
<'tcx
>,
218 ) -> &'tcx ty
::Const
<'tcx
> {
219 if let ty
::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. }
= c
{
220 match table
.probe_value(*vid
).val
.known() {