expose evaluate_obligation
that captures overflow, use in rustdoc
This commit is contained in:
parent
f58f2c8efa
commit
2fd5516272
2 changed files with 30 additions and 12 deletions
|
@ -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 =
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue