Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Ariel Ben-Yehuda committed Aug 17, 2015
1 parent 96e6b2f commit 8aeaaac
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/librustc/middle/infer/higher_ranked/mod.rs
Expand Up @@ -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());

Expand Down
9 changes: 7 additions & 2 deletions src/librustc/middle/infer/mod.rs
Expand Up @@ -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` */

Expand Down Expand Up @@ -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
Expand All @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/error_reporting.rs
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/middle/traits/project.rs
Expand Up @@ -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({:?},{:?})",
Expand Down
30 changes: 30 additions & 0 deletions src/librustc/middle/ty.rs
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/ty_relate/mod.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 8aeaaac

Please sign in to comment.