diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-09-13 14:59:01 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-09-13 14:59:01 -0400 |
| commit | 2fd5516272e44b08ec01fc48bf6987e9a3409b71 (patch) | |
| tree | 328d2e215a9525d44b47aaabaf713878c996f875 | |
| parent | f58f2c8efad4708f649e1b88622e1f89df0571f6 (diff) | |
| download | rust-2fd5516272e44b08ec01fc48bf6987e9a3409b71.tar.gz rust-2fd5516272e44b08ec01fc48bf6987e9a3409b71.zip | |
expose `evaluate_obligation` that captures overflow, use in rustdoc
| -rw-r--r-- | src/librustc/traits/query/evaluate_obligation.rs | 23 | ||||
| -rw-r--r-- | src/librustdoc/clean/blanket_impl.rs | 19 |
2 files changed, 30 insertions, 12 deletions
diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs index 1a906b5da6f..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,22 +30,31 @@ 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 = diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index e7e371cd567..3d591a702aa 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -103,11 +103,20 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> { // FIXME(eddyb) ignoring `obligations` might cause false positives. drop(obligations); - let may_apply = infcx.predicate_may_hold(&traits::Obligation::new( - cause.clone(), - param_env, - trait_ref.to_predicate(), - )); + debug!( + "invoking predicate_may_hold: {:?}", + trait_ref, + ); + let may_apply = match infcx.evaluate_obligation( + &traits::Obligation::new( + cause.clone(), + param_env, + trait_ref.to_predicate(), + ), + ) { + Ok(eval_result) => eval_result.may_apply(), + Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no + }; if !may_apply { return } |
