Skip to content

Commit

Permalink
Rollup merge of rust-lang#51412 - nnethercote:pending_obligations, r=…
Browse files Browse the repository at this point in the history
…estebank

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%.
  • Loading branch information
Mark-Simulacrum committed Jun 8, 2018
2 parents 898bb78 + b0440d3 commit 8ac351c
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/librustc/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>(
Expand Down Expand Up @@ -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> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc_data_structures/obligation_forest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand Down
2 changes: 0 additions & 2 deletions src/librustc_typeck/check/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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={:?}",
Expand Down Expand Up @@ -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)),
Expand Down

0 comments on commit 8ac351c

Please sign in to comment.