Skip to content

Commit 2fd5516

Browse files
committed
expose evaluate_obligation that captures overflow, use in rustdoc
1 parent f58f2c8 commit 2fd5516

File tree

2 files changed

+30
-12
lines changed

2 files changed

+30
-12
lines changed

src/librustc/traits/query/evaluate_obligation.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
2020
&self,
2121
obligation: &PredicateObligation<'tcx>,
2222
) -> bool {
23-
self.evaluate_obligation(obligation).may_apply()
23+
self.evaluate_obligation_no_overflow(obligation).may_apply()
2424
}
2525

2626
/// Evaluates whether the predicate can be satisfied in the given
@@ -30,22 +30,31 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
3030
&self,
3131
obligation: &PredicateObligation<'tcx>,
3232
) -> bool {
33-
self.evaluate_obligation(obligation) == EvaluationResult::EvaluatedToOk
33+
self.evaluate_obligation_no_overflow(obligation) == EvaluationResult::EvaluatedToOk
3434
}
3535

36-
// Helper function that canonicalizes and runs the query, as well as handles
37-
// overflow.
38-
fn evaluate_obligation(
36+
/// Evaluate a given predicate, capturing overflow and propagating it back.
37+
pub fn evaluate_obligation(
3938
&self,
4039
obligation: &PredicateObligation<'tcx>,
41-
) -> EvaluationResult {
40+
) -> Result<EvaluationResult, OverflowError> {
4241
let mut _orig_values = SmallVec::new();
4342
let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate),
4443
&mut _orig_values);
4544
// Run canonical query. If overflow occurs, rerun from scratch but this time
4645
// in standard trait query mode so that overflow is handled appropriately
4746
// within `SelectionContext`.
48-
match self.tcx.global_tcx().evaluate_obligation(c_pred) {
47+
self.tcx.global_tcx().evaluate_obligation(c_pred)
48+
}
49+
50+
// Helper function that canonicalizes and runs the query. If an
51+
// overflow results, we re-run it in the local context so we can
52+
// report a nice error.
53+
fn evaluate_obligation_no_overflow(
54+
&self,
55+
obligation: &PredicateObligation<'tcx>,
56+
) -> EvaluationResult {
57+
match self.evaluate_obligation(obligation) {
4958
Ok(result) => result,
5059
Err(OverflowError) => {
5160
let mut selcx =

src/librustdoc/clean/blanket_impl.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,20 @@ impl<'a, 'tcx, 'rcx, 'cstore> BlanketImplFinder <'a, 'tcx, 'rcx, 'cstore> {
103103
// FIXME(eddyb) ignoring `obligations` might cause false positives.
104104
drop(obligations);
105105

106-
let may_apply = infcx.predicate_may_hold(&traits::Obligation::new(
107-
cause.clone(),
108-
param_env,
109-
trait_ref.to_predicate(),
110-
));
106+
debug!(
107+
"invoking predicate_may_hold: {:?}",
108+
trait_ref,
109+
);
110+
let may_apply = match infcx.evaluate_obligation(
111+
&traits::Obligation::new(
112+
cause.clone(),
113+
param_env,
114+
trait_ref.to_predicate(),
115+
),
116+
) {
117+
Ok(eval_result) => eval_result.may_apply(),
118+
Err(traits::OverflowError) => true, // overflow doesn't mean yes *or* no
119+
};
111120
if !may_apply {
112121
return
113122
}

0 commit comments

Comments
 (0)