diff options
| author | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-06-07 08:31:57 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <nnethercote@mozilla.com> | 2018-06-07 20:25:05 +1000 |
| commit | cdfd9ca08800f7a69fb2a740ac31dbff13b94bce (patch) | |
| tree | 0d1138c259146a95665519c08e346037a619d775 /src | |
| parent | c131bdcaff68d35f96e954baac4340206779335f (diff) | |
| download | rust-cdfd9ca08800f7a69fb2a740ac31dbff13b94bce.tar.gz rust-cdfd9ca08800f7a69fb2a740ac31dbff13b94bce.zip | |
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%.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/traits/fulfill.rs | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index dff89f3c888..b8ed9da8fce 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -251,6 +251,13 @@ struct FulfillProcessor<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> { register_region_obligations: bool } +fn mk_pending(os: Vec<PredicateObligation<'tcx>>) -> Vec<PendingPredicateObligation<'tcx>> { + os.into_iter().map(|o| PendingPredicateObligation { + obligation: o, + stalled_on: vec![] + }).collect() +} + impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, 'tcx> { type Obligation = PendingPredicateObligation<'tcx>; type Error = FulfillmentErrorCode<'tcx>; @@ -260,10 +267,6 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, -> Result<Option<Vec<Self::Obligation>>, Self::Error> { process_predicate(self.selcx, obligation, self.register_region_obligations) - .map(|os| os.map(|os| os.into_iter().map(|o| PendingPredicateObligation { - obligation: o, - stalled_on: vec![] - }).collect())) } fn process_backedge<'c, I>(&mut self, cycle: I, @@ -300,7 +303,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( selcx: &mut SelectionContext<'a, 'gcx, 'tcx>, pending_obligation: &mut PendingPredicateObligation<'tcx>, register_region_obligations: bool) - -> Result<Option<Vec<PredicateObligation<'tcx>>>, + -> Result<Option<Vec<PendingPredicateObligation<'tcx>>>, FulfillmentErrorCode<'tcx>> { // if we were stalled on some unresolved variables, first check @@ -343,7 +346,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( Ok(Some(vtable)) => { debug!("selecting trait `{:?}` at depth {} yielded Ok(Some)", data, obligation.recursion_depth); - Ok(Some(vtable.nested_obligations())) + Ok(Some(mk_pending(vtable.nested_obligations()))) } Ok(None) => { debug!("selecting trait `{:?}` at depth {} yielded Ok(None)", @@ -444,7 +447,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( trait_ref_type_vars(selcx, data.to_poly_trait_ref(tcx)); Ok(None) } - Ok(v) => Ok(v), + Ok(Some(os)) => Ok(Some(mk_pending(os))), Err(e) => Err(CodeProjectionError(e)) } } @@ -481,7 +484,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( pending_obligation.stalled_on = vec![ty]; Ok(None) } - s => Ok(s) + Some(os) => Ok(Some(mk_pending(os))) } } @@ -496,7 +499,7 @@ fn process_predicate<'a, 'gcx, 'tcx>( Ok(None) } Some(Ok(ok)) => { - Ok(Some(ok.obligations)) + Ok(Some(mk_pending(ok.obligations))) } Some(Err(err)) => { let expected_found = ExpectedFound::new(subtype.skip_binder().a_is_expected, |
