where
T: TypeFoldable<'tcx>,
{
- let mut r = ShallowResolver::new(self);
- value.fold_with(&mut r)
+ value.fold_with(&mut ShallowResolver { infcx: self })
}
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
// variables, thus we don't need to substitute back the original values.
self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
}
-}
-
-pub struct ShallowResolver<'a, 'tcx> {
- infcx: &'a InferCtxt<'a, 'tcx>,
-}
-
-impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
- #[inline(always)]
- pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
- ShallowResolver { infcx }
- }
/// If `typ` is a type variable of some kind, resolve it one level
/// (but do not resolve types found in the result). If `typ` is
/// not a type variable, just return it unmodified.
- pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
+ // FIXME(eddyb) inline into `ShallowResolver::visit_ty`.
+ fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
match typ.kind {
ty::Infer(ty::TyVar(v)) => {
// Not entirely obvious: if `typ` is a type variable,
// depth.
//
// Note: if these two lines are combined into one we get
- // dynamic borrow errors on `self.infcx.inner`.
- let known = self.infcx.inner.borrow_mut().type_variables.probe(v).known();
- known.map(|t| self.fold_ty(t)).unwrap_or(typ)
+ // dynamic borrow errors on `self.inner`.
+ let known = self.inner.borrow_mut().type_variables.probe(v).known();
+ known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ)
}
ty::Infer(ty::IntVar(v)) => self
- .infcx
.inner
.borrow_mut()
.int_unification_table
.probe_value(v)
- .map(|v| v.to_type(self.infcx.tcx))
+ .map(|v| v.to_type(self.tcx))
.unwrap_or(typ),
ty::Infer(ty::FloatVar(v)) => self
- .infcx
.inner
.borrow_mut()
.float_unification_table
.probe_value(v)
- .map(|v| v.to_type(self.infcx.tcx))
+ .map(|v| v.to_type(self.tcx))
.unwrap_or(typ),
_ => typ,
}
}
- // `resolver.shallow_resolve_changed(ty)` is equivalent to
- // `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
- // inlined, despite being large, because it has only two call sites that
- // are extremely hot.
+ /// `infer_ty_changed(infer_ty)` is equivalent to `shallow_resolve(ty) != ty`
+ /// (where `ty.kind = ty::Infer(infer_ty)`), but more efficient. It's always
+ /// inlined, despite being large, because it has only two call sites that
+ /// are extremely hot.
#[inline(always)]
- pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool {
- match infer {
+ pub fn infer_ty_changed(&self, infer_ty: ty::InferTy) -> bool {
+ match infer_ty {
ty::TyVar(v) => {
use self::type_variable::TypeVariableValue;
- // If `inlined_probe` returns a `Known` value its `kind` never
- // matches `infer`.
- match self.infcx.inner.borrow_mut().type_variables.inlined_probe(v) {
+ // If `inlined_probe` returns a `Known` value, it never equals
+ // `ty::Infer(ty::TyVar(v))`.
+ match self.inner.borrow_mut().type_variables.inlined_probe(v) {
TypeVariableValue::Unknown { .. } => false,
TypeVariableValue::Known { .. } => true,
}
}
ty::IntVar(v) => {
- // If inlined_probe_value returns a value it's always a
+ // If `inlined_probe_value` returns a value it's always a
// `ty::Int(_)` or `ty::UInt(_)`, which never matches a
// `ty::Infer(_)`.
- self.infcx.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
+ self.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
}
ty::FloatVar(v) => {
- // If inlined_probe_value returns a value it's always a
+ // If `inlined_probe_value` returns a value it's always a
// `ty::Float(_)`, which never matches a `ty::Infer(_)`.
//
// Not `inlined_probe_value(v)` because this call site is colder.
- self.infcx.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
+ self.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
}
_ => unreachable!(),
}
}
+struct ShallowResolver<'a, 'tcx> {
+ infcx: &'a InferCtxt<'a, 'tcx>,
+}
+
impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.infcx.tcx
}
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
- self.shallow_resolve(ty)
+ self.infcx.shallow_resolve_ty(ty)
}
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {