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:
commit
7fbfd8d770
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