Shallow resolve ty and const vars to their root vars

This commit is contained in:
Shoyu Vanilla 2026-02-11 17:38:34 +09:00
parent 1f53258660
commit 13a83cb639
2 changed files with 58 additions and 13 deletions

View file

@ -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(_)

View file

@ -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)