1
Fork 0

Rollup merge of #124690 - compiler-errors:only-ambig-if-ambig, r=lcnr

Only consider ambiguous goals when finding best obligation for ambiguities

We don't care about ambiguous goals when reporting true errors, and vice versa for ambiguities.

r? lcnr
This commit is contained in:
Matthias Krüger 2024-05-04 22:27:31 +02:00 committed by GitHub
commit 7fbfd8d770
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 20 deletions

View file

@ -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))?;