diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-04-19 15:13:20 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-06-08 09:00:17 +1000 |
| commit | b0440d359b0dab992e8f01d63523799a72c81285 (patch) | |
| tree | d0012b134f27abb24bef1f2ab1323e189012fd9d | |
| parent | be5f17ccff09569c2dd22df9330364a92fec2295 (diff) | |
| download | rust-b0440d359b0dab992e8f01d63523799a72c81285.tar.gz rust-b0440d359b0dab992e8f01d63523799a72c81285.zip | |
Avoid useless Vec clones in pending_obligations().
The only instance of `ObligationForest` in use has an obligation type of `PendingPredicateObligation`, which contains a `PredicateObligation` and a `Vec<Ty>`. `FulfillmentContext::pending_obligations()` calls `ObligationForest::pending_obligations()`, which clones all the `PendingPredicateObligation`s. But the `Vec<Ty>` field of those cloned obligations is never touched. This patch changes `ObligationForest::pending_obligations()` to `map_pending_obligations` -- which gives callers control about which part of the obligation to clone -- and takes advantage of the change to avoid cloning the `Vec<Ty>`. The change speeds up runs of a few rustc-perf benchmarks, the best by 1%.
| -rw-r--r-- | src/librustc/traits/engine.rs | 4 | ||||
| -rw-r--r-- | src/librustc/traits/fulfill.rs | 4 | ||||
| -rw-r--r-- | src/librustc_data_structures/obligation_forest/mod.rs | 6 | ||||
| -rw-r--r-- | src/librustc_typeck/check/closure.rs | 2 |
4 files changed, 7 insertions, 9 deletions
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index 8eee6f35ab9..40d54885619 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -13,7 +13,7 @@ use ty::{self, Ty, TyCtxt}; use hir::def_id::DefId; use super::{FulfillmentContext, FulfillmentError}; -use super::{ObligationCause, PendingPredicateObligation, PredicateObligation}; +use super::{ObligationCause, PredicateObligation}; pub trait TraitEngine<'tcx>: 'tcx { fn normalize_projection_type<'a, 'gcx>( @@ -49,7 +49,7 @@ pub trait TraitEngine<'tcx>: 'tcx { infcx: &InferCtxt<'a, 'gcx, 'tcx>, ) -> Result<(), Vec<FulfillmentError<'tcx>>>; - fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>>; + fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>; } impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> { diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 4447a2b6ed1..7c31d8cc060 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -241,8 +241,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { self.select(&mut selcx) } - fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>> { - self.predicates.pending_obligations() + fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>> { + self.predicates.map_pending_obligations(|o| o.obligation.clone()) } } diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 612f44f09cf..c3934c4e1b8 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -229,13 +229,13 @@ impl<O: ForestObligation> ObligationForest<O> { } /// Returns the set of obligations that are in a pending state. - pub fn pending_obligations(&self) -> Vec<O> - where O: Clone + pub fn map_pending_obligations<P, F>(&self, f: F) -> Vec<P> + where F: Fn(&O) -> P { self.nodes .iter() .filter(|n| n.state.get() == NodeState::Pending) - .map(|n| n.obligation.clone()) + .map(|n| f(&n.obligation)) .collect() } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 67245bec7fb..439c1b34227 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -225,7 +225,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_sig = fulfillment_cx .pending_obligations() .iter() - .map(|obligation| &obligation.obligation) .filter_map(|obligation| { debug!( "deduce_expectations_from_obligations: obligation.predicate={:?}", @@ -257,7 +256,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let expected_kind = fulfillment_cx .pending_obligations() .iter() - .map(|obligation| &obligation.obligation) .filter_map(|obligation| { let opt_trait_ref = match obligation.predicate { ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref(self.tcx)), |
