Split and inline ShallowResolver::fold_ty
.
This commit is contained in:
parent
c2cf3f7b24
commit
fb8e6819aa
1 changed files with 46 additions and 37 deletions
|
@ -30,7 +30,7 @@ use rustc_middle::ty::relate::RelateResult;
|
||||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
|
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
|
||||||
use rustc_middle::ty::visit::TypeVisitable;
|
use rustc_middle::ty::visit::TypeVisitable;
|
||||||
pub use rustc_middle::ty::IntVarValue;
|
pub use rustc_middle::ty::IntVarValue;
|
||||||
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
|
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -1870,43 +1870,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||||
/// If `ty` is a type variable of some kind, resolve it one level
|
/// If `ty` is a type variable of some kind, resolve it one level
|
||||||
/// (but do not resolve types found in the result). If `typ` is
|
/// (but do not resolve types found in the result). If `typ` is
|
||||||
/// not a type variable, just return it unmodified.
|
/// not a type variable, just return it unmodified.
|
||||||
|
#[inline]
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *ty.kind() {
|
if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty }
|
||||||
ty::Infer(ty::TyVar(v)) => {
|
|
||||||
// Not entirely obvious: if `typ` is a type variable,
|
|
||||||
// it can be resolved to an int/float variable, which
|
|
||||||
// can then be recursively resolved, hence the
|
|
||||||
// recursion. Note though that we prevent type
|
|
||||||
// variables from unifying to other type variables
|
|
||||||
// directly (though they may be embedded
|
|
||||||
// structurally), and we prevent cycles in any case,
|
|
||||||
// so this recursion should always be of very limited
|
|
||||||
// depth.
|
|
||||||
//
|
|
||||||
// Note: if these two lines are combined into one we get
|
|
||||||
// dynamic borrow errors on `self.inner`.
|
|
||||||
let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
|
|
||||||
known.map_or(ty, |t| self.fold_ty(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Infer(ty::IntVar(v)) => self
|
|
||||||
.infcx
|
|
||||||
.inner
|
|
||||||
.borrow_mut()
|
|
||||||
.int_unification_table()
|
|
||||||
.probe_value(v)
|
|
||||||
.map_or(ty, |v| v.to_type(self.infcx.tcx)),
|
|
||||||
|
|
||||||
ty::Infer(ty::FloatVar(v)) => self
|
|
||||||
.infcx
|
|
||||||
.inner
|
|
||||||
.borrow_mut()
|
|
||||||
.float_unification_table()
|
|
||||||
.probe_value(v)
|
|
||||||
.map_or(ty, |v| v.to_type(self.infcx.tcx)),
|
|
||||||
|
|
||||||
_ => ty,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||||
|
@ -1925,6 +1891,49 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
|
||||||
|
// This is separate from `fold_ty` to keep that method small and inlinable.
|
||||||
|
#[inline(never)]
|
||||||
|
fn fold_infer_ty(&mut self, v: InferTy) -> Option<Ty<'tcx>> {
|
||||||
|
match v {
|
||||||
|
ty::TyVar(v) => {
|
||||||
|
// Not entirely obvious: if `typ` is a type variable,
|
||||||
|
// it can be resolved to an int/float variable, which
|
||||||
|
// can then be recursively resolved, hence the
|
||||||
|
// recursion. Note though that we prevent type
|
||||||
|
// variables from unifying to other type variables
|
||||||
|
// directly (though they may be embedded
|
||||||
|
// structurally), and we prevent cycles in any case,
|
||||||
|
// so this recursion should always be of very limited
|
||||||
|
// depth.
|
||||||
|
//
|
||||||
|
// Note: if these two lines are combined into one we get
|
||||||
|
// dynamic borrow errors on `self.inner`.
|
||||||
|
let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
|
||||||
|
known.map(|t| self.fold_ty(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::IntVar(v) => self
|
||||||
|
.infcx
|
||||||
|
.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.int_unification_table()
|
||||||
|
.probe_value(v)
|
||||||
|
.map(|v| v.to_type(self.infcx.tcx)),
|
||||||
|
|
||||||
|
ty::FloatVar(v) => self
|
||||||
|
.infcx
|
||||||
|
.inner
|
||||||
|
.borrow_mut()
|
||||||
|
.float_unification_table()
|
||||||
|
.probe_value(v)
|
||||||
|
.map(|v| v.to_type(self.infcx.tcx)),
|
||||||
|
|
||||||
|
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeTrace<'tcx> {
|
impl<'tcx> TypeTrace<'tcx> {
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
self.cause.span
|
self.cause.span
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue