Only consider ambiguous goals when finding best obligation for ambiguities
This commit is contained in:
parent
d7ea27808d
commit
6714216eaa
3 changed files with 24 additions and 20 deletions
|
@ -137,7 +137,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
|||
.collect();
|
||||
|
||||
errors.extend(self.obligations.overflowed.drain(..).map(|obligation| FulfillmentError {
|
||||
obligation: find_best_leaf_obligation(infcx, &obligation),
|
||||
obligation: find_best_leaf_obligation(infcx, &obligation, true),
|
||||
code: FulfillmentErrorCode::Ambiguity { overflow: Some(true) },
|
||||
root_obligation: obligation,
|
||||
}));
|
||||
|
@ -198,7 +198,7 @@ fn fulfillment_error_for_no_solution<'tcx>(
|
|||
infcx: &InferCtxt<'tcx>,
|
||||
root_obligation: PredicateObligation<'tcx>,
|
||||
) -> FulfillmentError<'tcx> {
|
||||
let obligation = find_best_leaf_obligation(infcx, &root_obligation);
|
||||
let obligation = find_best_leaf_obligation(infcx, &root_obligation, false);
|
||||
|
||||
let code = match obligation.predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(_)) => {
|
||||
|
@ -266,7 +266,7 @@ fn fulfillment_error_for_stalled<'tcx>(
|
|||
});
|
||||
|
||||
FulfillmentError {
|
||||
obligation: find_best_leaf_obligation(infcx, &obligation),
|
||||
obligation: find_best_leaf_obligation(infcx, &obligation, true),
|
||||
code,
|
||||
root_obligation: obligation,
|
||||
}
|
||||
|
@ -275,12 +275,13 @@ fn fulfillment_error_for_stalled<'tcx>(
|
|||
fn find_best_leaf_obligation<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
consider_ambiguities: bool,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let obligation = infcx.resolve_vars_if_possible(obligation.clone());
|
||||
infcx
|
||||
.visit_proof_tree(
|
||||
obligation.clone().into(),
|
||||
&mut BestObligation { obligation: obligation.clone() },
|
||||
&mut BestObligation { obligation: obligation.clone(), consider_ambiguities },
|
||||
)
|
||||
.break_value()
|
||||
.unwrap_or(obligation)
|
||||
|
@ -288,6 +289,7 @@ fn find_best_leaf_obligation<'tcx>(
|
|||
|
||||
struct BestObligation<'tcx> {
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
consider_ambiguities: bool,
|
||||
}
|
||||
|
||||
impl<'tcx> BestObligation<'tcx> {
|
||||
|
@ -355,11 +357,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Skip nested goals that hold.
|
||||
//FIXME: We should change the max allowed certainty based on if we're
|
||||
// visiting an ambiguity or error obligation.
|
||||
if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
|
||||
continue;
|
||||
// Skip nested goals that aren't the *reason* for our goal's failure.
|
||||
match self.consider_ambiguities {
|
||||
true if matches!(nested_goal.result(), Ok(Certainty::Maybe(_))) => {}
|
||||
false if matches!(nested_goal.result(), Err(_)) => {}
|
||||
_ => continue,
|
||||
}
|
||||
|
||||
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue