@@ -137,7 +137,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
137137 . collect ( ) ;
138138
139139 errors. extend ( self . obligations . overflowed . drain ( ..) . map ( |obligation| FulfillmentError {
140- obligation : find_best_leaf_obligation ( infcx, & obligation) ,
140+ obligation : find_best_leaf_obligation ( infcx, & obligation, true ) ,
141141 code : FulfillmentErrorCode :: Ambiguity { overflow : Some ( true ) } ,
142142 root_obligation : obligation,
143143 } ) ) ;
@@ -198,7 +198,7 @@ fn fulfillment_error_for_no_solution<'tcx>(
198198 infcx : & InferCtxt < ' tcx > ,
199199 root_obligation : PredicateObligation < ' tcx > ,
200200) -> FulfillmentError < ' tcx > {
201- let obligation = find_best_leaf_obligation ( infcx, & root_obligation) ;
201+ let obligation = find_best_leaf_obligation ( infcx, & root_obligation, false ) ;
202202
203203 let code = match obligation. predicate . kind ( ) . skip_binder ( ) {
204204 ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Projection ( _) ) => {
@@ -266,7 +266,7 @@ fn fulfillment_error_for_stalled<'tcx>(
266266 } ) ;
267267
268268 FulfillmentError {
269- obligation : find_best_leaf_obligation ( infcx, & obligation) ,
269+ obligation : find_best_leaf_obligation ( infcx, & obligation, true ) ,
270270 code,
271271 root_obligation : obligation,
272272 }
@@ -275,19 +275,21 @@ fn fulfillment_error_for_stalled<'tcx>(
275275fn find_best_leaf_obligation < ' tcx > (
276276 infcx : & InferCtxt < ' tcx > ,
277277 obligation : & PredicateObligation < ' tcx > ,
278+ consider_ambiguities : bool ,
278279) -> PredicateObligation < ' tcx > {
279280 let obligation = infcx. resolve_vars_if_possible ( obligation. clone ( ) ) ;
280281 infcx
281282 . visit_proof_tree (
282283 obligation. clone ( ) . into ( ) ,
283- & mut BestObligation { obligation : obligation. clone ( ) } ,
284+ & mut BestObligation { obligation : obligation. clone ( ) , consider_ambiguities } ,
284285 )
285286 . break_value ( )
286287 . unwrap_or ( obligation)
287288}
288289
289290struct BestObligation < ' tcx > {
290291 obligation : PredicateObligation < ' tcx > ,
292+ consider_ambiguities : bool ,
291293}
292294
293295impl < ' tcx > BestObligation < ' tcx > {
@@ -355,11 +357,11 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
355357 }
356358 }
357359
358- // Skip nested goals that hold .
359- //FIXME: We should change the max allowed certainty based on if we're
360- // visiting an ambiguity or error obligation.
361- if matches ! ( nested_goal. result( ) , Ok ( Certainty :: Yes ) ) {
362- continue ;
360+ // Skip nested goals that aren't the *reason* for our goal's failure .
361+ match self . consider_ambiguities {
362+ true if matches ! ( nested_goal . result ( ) , Ok ( Certainty :: Maybe ( _ ) ) ) => { }
363+ false if matches ! ( nested_goal. result( ) , Err ( _ ) ) => { }
364+ _ => continue ,
363365 }
364366
365367 self . with_derived_obligation ( obligation, |this| nested_goal. visit_with ( this) ) ?;
0 commit comments