Simplify IntVarValue/FloatVarValue
This commit is contained in:
parent
acaf0aeed0
commit
0a83764cbd
9 changed files with 145 additions and 172 deletions
|
@ -33,7 +33,6 @@
|
|||
use super::InferCtxt;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::infer::unify_key::ToType;
|
||||
use rustc_middle::ty::fold::TypeFolder;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
@ -204,22 +203,27 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
|||
|
||||
ty::IntVar(v) => {
|
||||
let mut inner = self.infcx.inner.borrow_mut();
|
||||
let input = inner
|
||||
.int_unification_table()
|
||||
.probe_value(v)
|
||||
.map(|v| v.to_type(self.infcx.tcx))
|
||||
.ok_or_else(|| ty::IntVar(inner.int_unification_table().find(v)));
|
||||
let value = inner.int_unification_table().probe_value(v);
|
||||
let input = match value {
|
||||
ty::IntVarValue::IntType(ty) => Ok(Ty::new_int(self.infcx.tcx, ty)),
|
||||
ty::IntVarValue::UintType(ty) => Ok(Ty::new_uint(self.infcx.tcx, ty)),
|
||||
ty::IntVarValue::Unknown => {
|
||||
Err(ty::IntVar(inner.int_unification_table().find(v)))
|
||||
}
|
||||
};
|
||||
drop(inner);
|
||||
Some(self.freshen_ty(input, |n| Ty::new_fresh_int(self.infcx.tcx, n)))
|
||||
}
|
||||
|
||||
ty::FloatVar(v) => {
|
||||
let mut inner = self.infcx.inner.borrow_mut();
|
||||
let input = inner
|
||||
.float_unification_table()
|
||||
.probe_value(v)
|
||||
.map(|v| v.to_type(self.infcx.tcx))
|
||||
.ok_or_else(|| ty::FloatVar(inner.float_unification_table().find(v)));
|
||||
let value = inner.float_unification_table().probe_value(v);
|
||||
let input = match value {
|
||||
ty::FloatVarValue::Known(ty) => Ok(Ty::new_float(self.infcx.tcx, ty)),
|
||||
ty::FloatVarValue::Unknown => {
|
||||
Err(ty::FloatVar(inner.float_unification_table().find(v)))
|
||||
}
|
||||
};
|
||||
drop(inner);
|
||||
Some(self.freshen_ty(input, |n| Ty::new_fresh_float(self.infcx.tcx, n)))
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed};
|
|||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
|
||||
use rustc_middle::infer::unify_key::ConstVariableOrigin;
|
||||
use rustc_middle::infer::unify_key::ConstVariableValue;
|
||||
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ToType};
|
||||
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
|
@ -811,13 +811,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
vars.extend(
|
||||
(0..inner.int_unification_table().len())
|
||||
.map(|i| ty::IntVid::from_u32(i as u32))
|
||||
.filter(|&vid| inner.int_unification_table().probe_value(vid).is_none())
|
||||
.filter(|&vid| inner.int_unification_table().probe_value(vid).is_unknown())
|
||||
.map(|v| Ty::new_int_var(self.tcx, v)),
|
||||
);
|
||||
vars.extend(
|
||||
(0..inner.float_unification_table().len())
|
||||
.map(|i| ty::FloatVid::from_u32(i as u32))
|
||||
.filter(|&vid| inner.float_unification_table().probe_value(vid).is_none())
|
||||
.filter(|&vid| inner.float_unification_table().probe_value(vid).is_unknown())
|
||||
.map(|v| Ty::new_float_var(self.tcx, v)),
|
||||
);
|
||||
vars
|
||||
|
@ -1025,14 +1025,28 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
ty::Const::new_var(self.tcx, vid, ty)
|
||||
}
|
||||
|
||||
pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
.const_unification_table()
|
||||
.new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
|
||||
.vid
|
||||
}
|
||||
|
||||
fn next_int_var_id(&self) -> IntVid {
|
||||
self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown)
|
||||
}
|
||||
|
||||
pub fn next_int_var(&self) -> Ty<'tcx> {
|
||||
let vid = self.inner.borrow_mut().int_unification_table().new_key(None);
|
||||
Ty::new_int_var(self.tcx, vid)
|
||||
Ty::new_int_var(self.tcx, self.next_int_var_id())
|
||||
}
|
||||
|
||||
fn next_float_var_id(&self) -> FloatVid {
|
||||
self.inner.borrow_mut().float_unification_table().new_key(ty::FloatVarValue::Unknown)
|
||||
}
|
||||
|
||||
pub fn next_float_var(&self) -> Ty<'tcx> {
|
||||
let vid = self.inner.borrow_mut().float_unification_table().new_key(None);
|
||||
Ty::new_float_var(self.tcx, vid)
|
||||
Ty::new_float_var(self.tcx, self.next_float_var_id())
|
||||
}
|
||||
|
||||
/// Creates a fresh region variable with the next available index.
|
||||
|
@ -1258,19 +1272,18 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
known.map(|t| self.shallow_resolve(t))
|
||||
}
|
||||
|
||||
ty::IntVar(v) => self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.int_unification_table()
|
||||
.probe_value(v)
|
||||
.map(|v| v.to_type(self.tcx)),
|
||||
ty::IntVar(v) => match self.inner.borrow_mut().int_unification_table().probe_value(v) {
|
||||
ty::IntVarValue::Unknown => None,
|
||||
ty::IntVarValue::IntType(ty) => Some(Ty::new_int(self.tcx, ty)),
|
||||
ty::IntVarValue::UintType(ty) => Some(Ty::new_uint(self.tcx, ty)),
|
||||
},
|
||||
|
||||
ty::FloatVar(v) => self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.float_unification_table()
|
||||
.probe_value(v)
|
||||
.map(|v| v.to_type(self.tcx)),
|
||||
ty::FloatVar(v) => {
|
||||
match self.inner.borrow_mut().float_unification_table().probe_value(v) {
|
||||
ty::FloatVarValue::Unknown => None,
|
||||
ty::FloatVarValue::Known(ty) => Some(Ty::new_float(self.tcx, ty)),
|
||||
}
|
||||
}
|
||||
|
||||
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None,
|
||||
}
|
||||
|
@ -1321,10 +1334,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// or else the root int var in the unification table.
|
||||
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
if let Some(value) = inner.int_unification_table().probe_value(vid) {
|
||||
value.to_type(self.tcx)
|
||||
} else {
|
||||
Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
|
||||
let value = inner.int_unification_table().probe_value(vid);
|
||||
match value {
|
||||
ty::IntVarValue::IntType(ty) => Ty::new_int(self.tcx, ty),
|
||||
ty::IntVarValue::UintType(ty) => Ty::new_uint(self.tcx, ty),
|
||||
ty::IntVarValue::Unknown => {
|
||||
Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1332,10 +1348,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// or else the root float var in the unification table.
|
||||
pub fn opportunistic_resolve_float_var(&self, vid: ty::FloatVid) -> Ty<'tcx> {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
if let Some(value) = inner.float_unification_table().probe_value(vid) {
|
||||
value.to_type(self.tcx)
|
||||
} else {
|
||||
Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid))
|
||||
let value = inner.float_unification_table().probe_value(vid);
|
||||
match value {
|
||||
ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty),
|
||||
ty::FloatVarValue::Unknown => {
|
||||
Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1626,7 +1644,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// If `inlined_probe_value` returns a value it's always a
|
||||
// `ty::Int(_)` or `ty::UInt(_)`, which never matches a
|
||||
// `ty::Infer(_)`.
|
||||
self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_some()
|
||||
!self.inner.borrow_mut().int_unification_table().inlined_probe_value(v).is_unknown()
|
||||
}
|
||||
|
||||
TyOrConstInferVar::TyFloat(v) => {
|
||||
|
@ -1634,7 +1652,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// `ty::Float(_)`, which never matches a `ty::Infer(_)`.
|
||||
//
|
||||
// Not `inlined_probe_value(v)` because this call site is colder.
|
||||
self.inner.borrow_mut().float_unification_table().probe_value(v).is_some()
|
||||
!self.inner.borrow_mut().float_unification_table().probe_value(v).is_unknown()
|
||||
}
|
||||
|
||||
TyOrConstInferVar::Const(v) => {
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
|
|||
use crate::traits::{Obligation, PredicateObligations};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitableExt, Upcast};
|
||||
use rustc_middle::ty::{IntType, UintType};
|
||||
|
@ -68,40 +68,38 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
match (a.kind(), b.kind()) {
|
||||
// Relate integral variables to other types
|
||||
(&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
.int_unification_table()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| int_unification_error(true, e))?;
|
||||
self.inner.borrow_mut().int_unification_table().union(a_id, b_id);
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
|
||||
self.unify_integral_variable(true, v_id, IntType(v))
|
||||
self.unify_integral_variable(v_id, IntType(v));
|
||||
Ok(b)
|
||||
}
|
||||
(&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
|
||||
self.unify_integral_variable(false, v_id, IntType(v))
|
||||
self.unify_integral_variable(v_id, IntType(v));
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
|
||||
self.unify_integral_variable(true, v_id, UintType(v))
|
||||
self.unify_integral_variable(v_id, UintType(v));
|
||||
Ok(b)
|
||||
}
|
||||
(&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
|
||||
self.unify_integral_variable(false, v_id, UintType(v))
|
||||
self.unify_integral_variable(v_id, UintType(v));
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
// Relate floating-point variables to other types
|
||||
(&ty::Infer(ty::FloatVar(a_id)), &ty::Infer(ty::FloatVar(b_id))) => {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
.float_unification_table()
|
||||
.unify_var_var(a_id, b_id)
|
||||
.map_err(|e| float_unification_error(true, e))?;
|
||||
self.inner.borrow_mut().float_unification_table().union(a_id, b_id);
|
||||
Ok(a)
|
||||
}
|
||||
(&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
|
||||
self.unify_float_variable(true, v_id, v)
|
||||
self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
|
||||
Ok(b)
|
||||
}
|
||||
(&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
|
||||
self.unify_float_variable(false, v_id, v)
|
||||
self.unify_float_variable(v_id, ty::FloatVarValue::Known(v));
|
||||
Ok(a)
|
||||
}
|
||||
|
||||
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
|
||||
|
@ -244,35 +242,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn unify_integral_variable(
|
||||
&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::IntVid,
|
||||
val: ty::IntVarValue,
|
||||
) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
.int_unification_table()
|
||||
.unify_var_value(vid, Some(val))
|
||||
.map_err(|e| int_unification_error(vid_is_expected, e))?;
|
||||
match val {
|
||||
IntType(v) => Ok(Ty::new_int(self.tcx, v)),
|
||||
UintType(v) => Ok(Ty::new_uint(self.tcx, v)),
|
||||
}
|
||||
#[inline(always)]
|
||||
fn unify_integral_variable(&self, vid: ty::IntVid, val: ty::IntVarValue) {
|
||||
self.inner.borrow_mut().int_unification_table().union_value(vid, val);
|
||||
}
|
||||
|
||||
fn unify_float_variable(
|
||||
&self,
|
||||
vid_is_expected: bool,
|
||||
vid: ty::FloatVid,
|
||||
val: ty::FloatTy,
|
||||
) -> RelateResult<'tcx, Ty<'tcx>> {
|
||||
self.inner
|
||||
.borrow_mut()
|
||||
.float_unification_table()
|
||||
.unify_var_value(vid, Some(ty::FloatVarValue(val)))
|
||||
.map_err(|e| float_unification_error(vid_is_expected, e))?;
|
||||
Ok(Ty::new_float(self.tcx, val))
|
||||
#[inline(always)]
|
||||
fn unify_float_variable(&self, vid: ty::FloatVid, val: ty::FloatVarValue) {
|
||||
self.inner.borrow_mut().float_unification_table().union_value(vid, val);
|
||||
}
|
||||
|
||||
fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
|
@ -350,19 +327,3 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
|
|||
/// Register `AliasRelate` obligation(s) that both types must be related to each other.
|
||||
fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>);
|
||||
}
|
||||
|
||||
fn int_unification_error<'tcx>(
|
||||
a_is_expected: bool,
|
||||
v: (ty::IntVarValue, ty::IntVarValue),
|
||||
) -> TypeError<'tcx> {
|
||||
let (a, b) = v;
|
||||
TypeError::IntMismatch(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
|
||||
fn float_unification_error<'tcx>(
|
||||
a_is_expected: bool,
|
||||
v: (ty::FloatVarValue, ty::FloatVarValue),
|
||||
) -> TypeError<'tcx> {
|
||||
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
|
||||
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ where
|
|||
|
||||
let infcx = this.infcx();
|
||||
|
||||
let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
|
||||
let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
|
||||
let a = infcx.shallow_resolve(a);
|
||||
let b = infcx.shallow_resolve(b);
|
||||
|
||||
match (a.kind(), b.kind()) {
|
||||
// If one side is known to be a variable and one is not,
|
||||
|
|
|
@ -80,8 +80,8 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
|||
}
|
||||
|
||||
let infcx = self.fields.infcx;
|
||||
let a = infcx.inner.borrow_mut().type_variables().replace_if_possible(a);
|
||||
let b = infcx.inner.borrow_mut().type_variables().replace_if_possible(b);
|
||||
let a = infcx.shallow_resolve(a);
|
||||
let b = infcx.shallow_resolve(b);
|
||||
|
||||
match (a.kind(), b.kind()) {
|
||||
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue