Skip to content

Commit cdfd9ca

Browse files
committed
Simplify process_obligation.
`process_predicates` returns a `Result<Option<Vec<PredicateObligation>>>`. `process_obligation` calls it and then fiddles with the output (using `map`, `map`, `into_iter`, `collect`) to produce a a `Result<Option<Vec<PendingPredicateObligation>>>`. This function is sufficiently hot that the fiddling is expensive. It's much better for `process_predicate` to directly return a `Result<Option<Vec<PendingPredicateObligation>>>` because `Ok(None)` accounts for ~90% of the results, and `Ok(vec![])` accounts for another ~5%.
1 parent c131bdc commit cdfd9ca

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

src/librustc/traits/fulfill.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ struct FulfillProcessor<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
251251
register_region_obligations: bool
252252
}
253253

254+
fn mk_pending(os: Vec<PredicateObligation<'tcx>>) -> Vec<PendingPredicateObligation<'tcx>> {
255+
os.into_iter().map(|o| PendingPredicateObligation {
256+
obligation: o,
257+
stalled_on: vec![]
258+
}).collect()
259+
}
260+
254261
impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, 'tcx> {
255262
type Obligation = PendingPredicateObligation<'tcx>;
256263
type Error = FulfillmentErrorCode<'tcx>;
@@ -260,10 +267,6 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
260267
-> Result<Option<Vec<Self::Obligation>>, Self::Error>
261268
{
262269
process_predicate(self.selcx, obligation, self.register_region_obligations)
263-
.map(|os| os.map(|os| os.into_iter().map(|o| PendingPredicateObligation {
264-
obligation: o,
265-
stalled_on: vec![]
266-
}).collect()))
267270
}
268271

269272
fn process_backedge<'c, I>(&mut self, cycle: I,
@@ -300,7 +303,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
300303
selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
301304
pending_obligation: &mut PendingPredicateObligation<'tcx>,
302305
register_region_obligations: bool)
303-
-> Result<Option<Vec<PredicateObligation<'tcx>>>,
306+
-> Result<Option<Vec<PendingPredicateObligation<'tcx>>>,
304307
FulfillmentErrorCode<'tcx>>
305308
{
306309
// if we were stalled on some unresolved variables, first check
@@ -343,7 +346,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
343346
Ok(Some(vtable)) => {
344347
debug!("selecting trait `{:?}` at depth {} yielded Ok(Some)",
345348
data, obligation.recursion_depth);
346-
Ok(Some(vtable.nested_obligations()))
349+
Ok(Some(mk_pending(vtable.nested_obligations())))
347350
}
348351
Ok(None) => {
349352
debug!("selecting trait `{:?}` at depth {} yielded Ok(None)",
@@ -444,7 +447,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
444447
trait_ref_type_vars(selcx, data.to_poly_trait_ref(tcx));
445448
Ok(None)
446449
}
447-
Ok(v) => Ok(v),
450+
Ok(Some(os)) => Ok(Some(mk_pending(os))),
448451
Err(e) => Err(CodeProjectionError(e))
449452
}
450453
}
@@ -481,7 +484,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
481484
pending_obligation.stalled_on = vec![ty];
482485
Ok(None)
483486
}
484-
s => Ok(s)
487+
Some(os) => Ok(Some(mk_pending(os)))
485488
}
486489
}
487490

@@ -496,7 +499,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
496499
Ok(None)
497500
}
498501
Some(Ok(ok)) => {
499-
Ok(Some(ok.obligations))
502+
Ok(Some(mk_pending(ok.obligations)))
500503
}
501504
Some(Err(err)) => {
502505
let expected_found = ExpectedFound::new(subtype.skip_binder().a_is_expected,

0 commit comments

Comments
 (0)