Rollup merge of #51412 - nnethercote:pending_obligations, r=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%.
This commit is contained in:
commit
8ac351c209
@ -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> {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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)),
|
||||
|
Loading…
Reference in New Issue
Block a user