add a fast-path to resolve_type_vars_if_possible

this avoids needless substituting

before:
577.76user 4.27system 7:36.13elapsed 127%CPU (0avgtext+0avgdata 1141608maxresident)k

after:
573.01user 4.04system 7:33.86elapsed 127%CPU (0avgtext+0avgdata 1141656maxresident)k
This commit is contained in:
Ariel Ben-Yehuda 2015-08-17 23:50:24 +03:00
parent 96e6b2fef8
commit 8aeaaac654
6 changed files with 48 additions and 6 deletions

View file

@ -614,7 +614,7 @@ pub fn plug_leaks<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
snapshot: &CombinedSnapshot,
value: &T)
-> T
where T : TypeFoldable<'tcx>
where T : TypeFoldable<'tcx> + ty::HasTypeFlags
{
debug_assert!(leak_check(infcx, &skol_map, snapshot).is_ok());

View file

@ -985,7 +985,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
snapshot: &CombinedSnapshot,
value: &T)
-> T
where T : TypeFoldable<'tcx>
where T : TypeFoldable<'tcx> + HasTypeFlags
{
/*! See `higher_ranked::plug_leaks` */
@ -1256,7 +1256,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
}
pub fn resolve_type_vars_if_possible<T:TypeFoldable<'tcx>>(&self, value: &T) -> T {
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
where T: TypeFoldable<'tcx> + HasTypeFlags
{
/*!
* Where possible, replaces type/int/float variables in
* `value` with their final value. Note that region variables
@ -1266,6 +1268,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
* at will.
*/
if !value.needs_infer() {
return value.clone(); // avoid duplicated subst-folding
}
let mut r = resolve::OpportunisticTypeResolver::new(self);
value.fold_with(&mut r)
}

View file

@ -160,7 +160,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
pub fn report_overflow_error<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
obligation: &Obligation<'tcx, T>)
-> !
where T: fmt::Display + TypeFoldable<'tcx>
where T: fmt::Display + TypeFoldable<'tcx> + HasTypeFlags
{
let predicate =
infcx.resolve_type_vars_if_possible(&obligation.predicate);

View file

@ -927,6 +927,13 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
}
}
impl<'tcx, T: HasTypeFlags> HasTypeFlags for Normalized<'tcx, T> {
fn has_type_flags(&self, flags: ty::TypeFlags) -> bool {
self.value.has_type_flags(flags) ||
self.obligations.has_type_flags(flags)
}
}
impl<'tcx, T:fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Normalized({:?},{:?})",

View file

@ -7280,6 +7280,24 @@ impl<'tcx,T:HasTypeFlags> HasTypeFlags for VecPerParamSpace<T> {
}
}
impl HasTypeFlags for abi::Abi {
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
false
}
}
impl HasTypeFlags for ast::Unsafety {
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
false
}
}
impl HasTypeFlags for BuiltinBounds {
fn has_type_flags(&self, _flags: TypeFlags) -> bool {
false
}
}
impl<'tcx> HasTypeFlags for ClosureTy<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.sig.has_type_flags(flags)
@ -7292,6 +7310,12 @@ impl<'tcx> HasTypeFlags for ClosureUpvar<'tcx> {
}
}
impl<'tcx> HasTypeFlags for ExistentialBounds<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.projection_bounds.has_type_flags(flags)
}
}
impl<'tcx> HasTypeFlags for ty::InstantiatedPredicates<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.predicates.has_type_flags(flags)
@ -7367,6 +7391,12 @@ impl<'tcx> HasTypeFlags for Ty<'tcx> {
}
}
impl<'tcx> HasTypeFlags for TypeAndMut<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.ty.has_type_flags(flags)
}
}
impl<'tcx> HasTypeFlags for TraitRef<'tcx> {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
self.substs.has_type_flags(flags)

View file

@ -14,7 +14,7 @@
//! type equality, etc.
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
use middle::ty::{self, Ty, TypeError};
use middle::ty::{self, HasTypeFlags, Ty, TypeError};
use middle::ty_fold::TypeFoldable;
use std::rc::Rc;
use syntax::abi;
@ -78,7 +78,7 @@ pub trait TypeRelation<'a,'tcx> : Sized {
where T: Relate<'a,'tcx>;
}
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> {
pub trait Relate<'a,'tcx>: TypeFoldable<'tcx> + HasTypeFlags {
fn relate<R:TypeRelation<'a,'tcx>>(relation: &mut R,
a: &Self,
b: &Self)