1
Fork 0

expose evaluate_obligation that captures overflow, use in rustdoc

This commit is contained in:
Niko Matsakis 2018-09-13 14:59:01 -04:00
parent f58f2c8efa
commit 2fd5516272
2 changed files with 30 additions and 12 deletions

View file

@ -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 =

View file

@ -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
}