Shallow resolve ty and const vars to their root vars
This commit is contained in:
parent
1f53258660
commit
13a83cb639
2 changed files with 58 additions and 13 deletions
|
|
@ -1099,22 +1099,45 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
//
|
||||
// Note: if these two lines are combined into one we get
|
||||
// dynamic borrow errors on `self.inner`.
|
||||
let known = self.inner.borrow_mut().type_variables().probe(v).known();
|
||||
known.map_or(ty, |t| self.shallow_resolve(t))
|
||||
let (root_vid, value) =
|
||||
self.inner.borrow_mut().type_variables().probe_with_root_vid(v);
|
||||
value.known().map_or_else(
|
||||
|| if root_vid == v { ty } else { Ty::new_var(self.tcx, root_vid) },
|
||||
|t| self.shallow_resolve(t),
|
||||
)
|
||||
}
|
||||
|
||||
ty::IntVar(v) => {
|
||||
match self.inner.borrow_mut().int_unification_table().probe_value(v) {
|
||||
let (root, value) =
|
||||
self.inner.borrow_mut().int_unification_table().inlined_probe_key_value(v);
|
||||
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,
|
||||
ty::IntVarValue::Unknown => {
|
||||
if root == v {
|
||||
ty
|
||||
} else {
|
||||
Ty::new_int_var(self.tcx, root)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::FloatVar(v) => {
|
||||
match self.inner.borrow_mut().float_unification_table().probe_value(v) {
|
||||
let (root, value) = self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.float_unification_table()
|
||||
.inlined_probe_key_value(v);
|
||||
match value {
|
||||
ty::FloatVarValue::Known(ty) => Ty::new_float(self.tcx, ty),
|
||||
ty::FloatVarValue::Unknown => ty,
|
||||
ty::FloatVarValue::Unknown => {
|
||||
if root == v {
|
||||
ty
|
||||
} else {
|
||||
Ty::new_float_var(self.tcx, root)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1128,13 +1151,16 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Infer(infer_ct) => match infer_ct {
|
||||
InferConst::Var(vid) => self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.const_unification_table()
|
||||
.probe_value(vid)
|
||||
.known()
|
||||
.unwrap_or(ct),
|
||||
InferConst::Var(vid) => {
|
||||
let (root, value) = self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.const_unification_table()
|
||||
.inlined_probe_key_value(vid);
|
||||
value.known().unwrap_or_else(|| {
|
||||
if root.vid == vid { ct } else { ty::Const::new_var(self.tcx, root.vid) }
|
||||
})
|
||||
}
|
||||
InferConst::Fresh(_) => ct,
|
||||
},
|
||||
ty::ConstKind::Param(_)
|
||||
|
|
|
|||
|
|
@ -258,6 +258,25 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
|
|||
self.eq_relations().inlined_probe_value(vid)
|
||||
}
|
||||
|
||||
/// Retrieves the type to which `vid` has been instantiated, if
|
||||
/// any, along with the root `vid`.
|
||||
pub(crate) fn probe_with_root_vid(
|
||||
&mut self,
|
||||
vid: ty::TyVid,
|
||||
) -> (ty::TyVid, TypeVariableValue<'tcx>) {
|
||||
self.inlined_probe_with_vid(vid)
|
||||
}
|
||||
|
||||
/// An always-inlined variant of `probe_with_root_vid`, for very hot call sites.
|
||||
#[inline(always)]
|
||||
pub(crate) fn inlined_probe_with_vid(
|
||||
&mut self,
|
||||
vid: ty::TyVid,
|
||||
) -> (ty::TyVid, TypeVariableValue<'tcx>) {
|
||||
let (id, value) = self.eq_relations().inlined_probe_key_value(vid);
|
||||
(id.vid, value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> {
|
||||
self.storage.eq_relations.with_log(self.undo_log)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue