From 55c6357daf130597522fb32a5be2fd44b828a833 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Jun 2018 13:39:16 -0400 Subject: [PATCH] micro-optimize empty predicate and normalize lists --- .../borrow_check/nll/type_check/mod.rs | 31 +++++++++++++------ 1 file 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> + 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| {