diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-05-04 22:27:31 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-04 22:27:31 +0200 |
| commit | 7fbfd8d7708f87d4d1dd48ba49f18004a5cd625c (patch) | |
| tree | e11938be4eb42f1c1397474d6ee1785d9a689281 /compiler | |
| parent | f4d0776b4fb81539ff4a7a493612a022043d88b4 (diff) | |
| parent | 6714216eaa8e3431706e451e2ff26401551207ea (diff) | |
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
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/fulfill.rs | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 796222129f1..c0ece9655a5 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -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))?; |
