diff options
| author | bors <bors@rust-lang.org> | 2018-11-07 03:21:02 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-11-07 03:21:02 +0000 |
| commit | 1433507eba7d1a114e4c6f27ae0e1a74f60f20de (patch) | |
| tree | bdefceb804ebe06423a47711fd1132f3b2219818 /src/librustc/traits/query/evaluate_obligation.rs | |
| parent | da5f414c2c0bfe5198934493f04c676e2b23ff2e (diff) | |
| parent | 59e6ce4b19a8c2b9ec9a1fbf51ed232b040b177b (diff) | |
| download | rust-1.30.1.tar.gz rust-1.30.1.zip | |
Auto merge of #55738 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum 1.30.1
1.30.1 stable release I believe this includes all of the relevant pieces from https://github.com/rust-lang/rust/issues/55594. Backports all proceeded smoothly. cc @rust-lang/release
Diffstat (limited to 'src/librustc/traits/query/evaluate_obligation.rs')
| -rw-r--r-- | src/librustc/traits/query/evaluate_obligation.rs | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs index 6bd92678362..f573b1ef45e 100644 --- a/src/librustc/traits/query/evaluate_obligation.rs +++ b/src/librustc/traits/query/evaluate_obligation.rs @@ -20,7 +20,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, ) -> bool { - self.evaluate_obligation(obligation).may_apply() + self.evaluate_obligation_no_overflow(obligation).may_apply() } /// Evaluates whether the predicate can be satisfied in the given @@ -30,28 +30,44 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, ) -> bool { - self.evaluate_obligation(obligation) == EvaluationResult::EvaluatedToOk + self.evaluate_obligation_no_overflow(obligation) == EvaluationResult::EvaluatedToOk } - // Helper function that canonicalizes and runs the query, as well as handles - // overflow. - fn evaluate_obligation( + /// Evaluate a given predicate, capturing overflow and propagating it back. + pub fn evaluate_obligation( &self, obligation: &PredicateObligation<'tcx>, - ) -> EvaluationResult { + ) -> Result<EvaluationResult, OverflowError> { let mut _orig_values = SmallVec::new(); let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate), &mut _orig_values); // Run canonical query. If overflow occurs, rerun from scratch but this time // in standard trait query mode so that overflow is handled appropriately // within `SelectionContext`. - match self.tcx.global_tcx().evaluate_obligation(c_pred) { + self.tcx.global_tcx().evaluate_obligation(c_pred) + } + + // Helper function that canonicalizes and runs the query. If an + // overflow results, we re-run it in the local context so we can + // report a nice error. + fn evaluate_obligation_no_overflow( + &self, + obligation: &PredicateObligation<'tcx>, + ) -> EvaluationResult { + match self.evaluate_obligation(obligation) { Ok(result) => result, Err(OverflowError) => { let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); selcx.evaluate_obligation_recursively(obligation) - .expect("Overflow should be caught earlier in standard query mode") + .unwrap_or_else(|r| { + span_bug!( + obligation.cause.span, + "Overflow should be caught earlier in standard query mode: {:?}, {:?}", + obligation, + r, + ) + }) } } } |
