about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-08-17 23:50:24 +0300
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>2015-08-18 00:24:16 +0300
commit8aeaaac6545565345f4df7d24d6421f93f28d698 (patch)
tree4ecddbf85f68f795d8e1d38a64a3ac05e235c65f /src
parent96e6b2fef82c13aa542713e7923d7d0a76bd698b (diff)
downloadrust-8aeaaac6545565345f4df7d24d6421f93f28d698.tar.gz
rust-8aeaaac6545565345f4df7d24d6421f93f28d698.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/infer/higher_ranked/mod.rs2
-rw-r--r--src/librustc/middle/infer/mod.rs9
-rw-r--r--src/librustc/middle/traits/error_reporting.rs2
-rw-r--r--src/librustc/middle/traits/project.rs7
-rw-r--r--src/librustc/middle/ty.rs30
-rw-r--r--src/librustc/middle/ty_relate/mod.rs4
6 files changed, 48 insertions, 6 deletions
diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs
index 1919d8ffd29..5f2f4df2f16 100644
--- a/src/librustc/middle/infer/higher_ranked/mod.rs
+++ b/src/librustc/middle/infer/higher_ranked/mod.rs
@@ -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());
 
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index 1b47ce75bc5..d56a73c3657 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -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)
     }
diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs
index 467c752499b..3be05c45c4d 100644
--- a/src/librustc/middle/traits/error_reporting.rs
+++ b/src/librustc/middle/traits/error_reporting.rs
@@ -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);
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index ef3a217ecdb..cacefbb1a85 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -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({:?},{:?})",
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 9f5b24c6b76..f99760b6210 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -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)
diff --git a/src/librustc/middle/ty_relate/mod.rs b/src/librustc/middle/ty_relate/mod.rs
index 05b08b356ef..f307f674732 100644
--- a/src/librustc/middle/ty_relate/mod.rs
+++ b/src/librustc/middle/ty_relate/mod.rs
@@ -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)