about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-06-01 13:39:16 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-06-09 11:02:13 -0400
commit55c6357daf130597522fb32a5be2fd44b828a833 (patch)
treecdd1a7d3fd4e50d05aae203a20d6904d012fa1d8
parent73a09f35b114d9ddf10e29df4e730d15e64f58c7 (diff)
downloadrust-55c6357daf130597522fb32a5be2fd44b828a833.tar.gz
rust-55c6357daf130597522fb32a5be2fd44b828a833.zip
micro-optimize empty predicate and normalize lists
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 697287d80c3..0dc2d5ab258 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1551,31 +1551,36 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     where
         T: IntoIterator<Item = ty::Predicate<'tcx>> + Clone,
     {
+        let cause = self.misc(self.last_span);
+        let obligations: Vec<_> = predicates
+            .into_iter()
+            .map(|p| traits::Obligation::new(cause.clone(), self.param_env, p))
+            .collect();
+
+        // Micro-optimization
+        if obligations.is_empty() {
+            return;
+        }
+
         // This intermediate vector is mildly unfortunate, in that we
         // sometimes create it even when logging is disabled, but only
         // if debug-info is enabled, and I doubt it is actually
         // expensive. -nmatsakis
         let predicates_vec: Vec<_> = if cfg!(debug_assertions) {
-            predicates.clone().into_iter().collect()
+            obligations.iter().map(|o| o.predicate).collect()
         } else {
             Vec::new()
         };
 
         debug!(
             "prove_predicates(predicates={:?}, location={:?})",
-            predicates_vec,
-            location,
+            predicates_vec, location,
         );
 
         self.fully_perform_op(
             location.at_self(),
             || format!("prove_predicates({:?})", predicates_vec),
-            |this| {
-                let cause = this.misc(this.last_span);
-                let obligations = predicates
-                    .into_iter()
-                    .map(|p| traits::Obligation::new(cause.clone(), this.param_env, p))
-                    .collect();
+            |_this| {
                 Ok(InferOk {
                     value: (),
                     obligations,
@@ -1615,12 +1620,18 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
     where
         T: fmt::Debug + TypeFoldable<'tcx>,
     {
+        // Micro-optimization: avoid work when we don't have to
+        if !value.has_projections() {
+            return value.clone();
+        }
+
         debug!("normalize(value={:?}, location={:?})", value, location);
         self.fully_perform_op(
             location.to_locations(),
             || format!("normalize(value={:?})", value),
             |this| {
-                let Normalized { value, obligations } = this.infcx
+                let Normalized { value, obligations } = this
+                    .infcx
                     .at(&this.misc(this.last_span), this.param_env)
                     .normalize(value)
                     .unwrap_or_else(|NoSolution| {