infer: export methods on InferCtxt instead of ShallowResolver.
This commit is contained in:
parent
5f13820478
commit
d8448d2291
2 changed files with 29 additions and 38 deletions
|
|
@ -1347,8 +1347,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
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 {
|
||||
|
|
@ -1565,22 +1564,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
// 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,
|
||||
|
|
@ -1594,64 +1583,62 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
|
|||
// 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!(),
|
||||
|
|
@ -1659,13 +1646,17 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::infer::{InferCtxt, ShallowResolver};
|
||||
use crate::infer::InferCtxt;
|
||||
use rustc::ty::error::ExpectedFound;
|
||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
|
||||
use rustc_data_structures::obligation_forest::ProcessResult;
|
||||
|
|
@ -267,7 +267,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||
// code is so hot. 1 and 0 dominate; 2+ is fairly rare.
|
||||
1 => {
|
||||
let infer = pending_obligation.stalled_on[0];
|
||||
ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer)
|
||||
self.selcx.infcx().infer_ty_changed(infer)
|
||||
}
|
||||
0 => {
|
||||
// In this case we haven't changed, but wish to make a change.
|
||||
|
|
@ -278,7 +278,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||
// form was a perf win. See #64545 for details.
|
||||
(|| {
|
||||
for &infer in &pending_obligation.stalled_on {
|
||||
if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) {
|
||||
if self.selcx.infcx().infer_ty_changed(infer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue