@@ -7,10 +7,10 @@ use rustc_infer::traits::solve::inspect::ProbeKind;
77use  rustc_infer:: traits:: solve:: { CandidateSource ,  GoalSource ,  MaybeCause } ; 
88use  rustc_infer:: traits:: { 
99    self ,  FulfillmentError ,  FulfillmentErrorCode ,  MismatchedProjectionTypes ,  Obligation , 
10-     PredicateObligation ,  SelectionError ,  TraitEngine , 
10+     ObligationCause ,   PredicateObligation ,  SelectionError ,  TraitEngine , 
1111} ; 
12- use  rustc_middle:: ty; 
1312use  rustc_middle:: ty:: error:: { ExpectedFound ,  TypeError } ; 
13+ use  rustc_middle:: ty:: { self ,  TyCtxt } ; 
1414
1515use  super :: eval_ctxt:: GenerateProofTree ; 
1616use  super :: inspect:: { ProofTreeInferCtxtExt ,  ProofTreeVisitor } ; 
@@ -219,14 +219,14 @@ fn fulfillment_error_for_no_solution<'tcx>(
219219        } 
220220        ty:: PredicateKind :: Subtype ( pred)  => { 
221221            let  ( a,  b)  = infcx. enter_forall_and_leak_universe ( 
222-                 root_obligation . predicate . kind ( ) . rebind ( ( pred. a ,  pred. b ) ) , 
222+                 obligation . predicate . kind ( ) . rebind ( ( pred. a ,  pred. b ) ) , 
223223            ) ; 
224224            let  expected_found = ExpectedFound :: new ( true ,  a,  b) ; 
225225            FulfillmentErrorCode :: SubtypeError ( expected_found,  TypeError :: Sorts ( expected_found) ) 
226226        } 
227227        ty:: PredicateKind :: Coerce ( pred)  => { 
228228            let  ( a,  b)  = infcx. enter_forall_and_leak_universe ( 
229-                 root_obligation . predicate . kind ( ) . rebind ( ( pred. a ,  pred. b ) ) , 
229+                 obligation . predicate . kind ( ) . rebind ( ( pred. a ,  pred. b ) ) , 
230230            ) ; 
231231            let  expected_found = ExpectedFound :: new ( false ,  a,  b) ; 
232232            FulfillmentErrorCode :: SubtypeError ( expected_found,  TypeError :: Sorts ( expected_found) ) 
@@ -272,17 +272,30 @@ fn fulfillment_error_for_stalled<'tcx>(
272272    } 
273273} 
274274
275+ fn  find_best_leaf_obligation < ' tcx > ( 
276+     infcx :  & InferCtxt < ' tcx > , 
277+     obligation :  & PredicateObligation < ' tcx > , 
278+ )  -> PredicateObligation < ' tcx >  { 
279+     let  obligation = infcx. resolve_vars_if_possible ( obligation. clone ( ) ) ; 
280+     infcx
281+         . visit_proof_tree ( 
282+             obligation. clone ( ) . into ( ) , 
283+             & mut  BestObligation  {  obligation :  obligation. clone ( )  } , 
284+         ) 
285+         . break_value ( ) 
286+         . unwrap_or ( obligation) 
287+ } 
288+ 
275289struct  BestObligation < ' tcx >  { 
276290    obligation :  PredicateObligation < ' tcx > , 
277291} 
278292
279293impl < ' tcx >  BestObligation < ' tcx >  { 
280294    fn  with_derived_obligation ( 
281295        & mut  self , 
282-         derive_obligation :   impl   FnOnce ( & mut   Self )  ->  PredicateObligation < ' tcx > , 
296+         derived_obligation :  PredicateObligation < ' tcx > , 
283297        and_then :  impl  FnOnce ( & mut  Self )  -> <Self  as  ProofTreeVisitor < ' tcx > >:: Result , 
284298    )  -> <Self  as  ProofTreeVisitor < ' tcx > >:: Result  { 
285-         let  derived_obligation = derive_obligation ( self ) ; 
286299        let  old_obligation = std:: mem:: replace ( & mut  self . obligation ,  derived_obligation) ; 
287300        let  res = and_then ( self ) ; 
288301        self . obligation  = old_obligation; 
@@ -298,13 +311,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
298311    } 
299312
300313    fn  visit_goal ( & mut  self ,  goal :  & super :: inspect:: InspectGoal < ' _ ,  ' tcx > )  -> Self :: Result  { 
314+         // FIXME: Throw out candidates that have no failing WC and >0 failing misc goal. 
315+         // This most likely means that the goal just didn't unify at all, e.g. a param 
316+         // candidate with an alias in it. 
301317        let  candidates = goal. candidates ( ) ; 
302-         // FIXME: Throw out candidates that have no failing WC and >1 failing misc goal. 
303- 
304-         // HACK: 
305-         if  self . obligation . recursion_depth  > 3  { 
306-             return  ControlFlow :: Break ( self . obligation . clone ( ) ) ; 
307-         } 
308318
309319        let  [ candidate]  = candidates. as_slice ( )  else  { 
310320            return  ControlFlow :: Break ( self . obligation . clone ( ) ) ; 
@@ -320,80 +330,71 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
320330        let  tcx = goal. infcx ( ) . tcx ; 
321331        let  mut  impl_where_bound_count = 0 ; 
322332        for  nested_goal in  candidate. instantiate_nested_goals ( self . span ( ) )  { 
323-             if  matches ! ( nested_goal. source( ) ,  GoalSource :: ImplWhereBound )  { 
324-                 impl_where_bound_count += 1 ; 
325-             }  else  { 
326-                 continue ; 
333+             let  obligation; 
334+             match  nested_goal. source ( )  { 
335+                 GoalSource :: Misc  => { 
336+                     continue ; 
337+                 } 
338+                 GoalSource :: ImplWhereBound  => { 
339+                     obligation = Obligation  { 
340+                         cause :  derive_cause ( 
341+                             tcx, 
342+                             candidate. kind ( ) , 
343+                             self . obligation . cause . clone ( ) , 
344+                             impl_where_bound_count, 
345+                             parent_trait_pred, 
346+                         ) , 
347+                         param_env :  nested_goal. goal ( ) . param_env , 
348+                         predicate :  nested_goal. goal ( ) . predicate , 
349+                         recursion_depth :  self . obligation . recursion_depth  + 1 , 
350+                     } ; 
351+                     impl_where_bound_count += 1 ; 
352+                 } 
353+                 GoalSource :: InstantiateHigherRanked  => { 
354+                     obligation = self . obligation . clone ( ) ; 
355+                 } 
327356            } 
328357
329358            // 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. 
330361            if  matches ! ( nested_goal. result( ) ,  Ok ( Certainty :: Yes ) )  { 
331362                continue ; 
332363            } 
333364
334-             self . with_derived_obligation ( 
335-                 |self_| { 
336-                     let  mut  cause = self_. obligation . cause . clone ( ) ; 
337-                     cause = match  candidate. kind ( )  { 
338-                         ProbeKind :: TraitCandidate  { 
339-                             source :  CandidateSource :: Impl ( impl_def_id) , 
340-                             result :  _, 
341-                         }  => { 
342-                             let  idx = impl_where_bound_count - 1 ; 
343-                             if  let  Some ( ( _,  span) )  = tcx
344-                                 . predicates_of ( impl_def_id) 
345-                                 . instantiate_identity ( tcx) 
346-                                 . iter ( ) 
347-                                 . nth ( idx) 
348-                             { 
349-                                 cause. derived_cause ( parent_trait_pred,  |derived| { 
350-                                     traits:: ImplDerivedObligation ( Box :: new ( 
351-                                         traits:: ImplDerivedObligationCause  { 
352-                                             derived, 
353-                                             impl_or_alias_def_id :  impl_def_id, 
354-                                             impl_def_predicate_index :  Some ( idx) , 
355-                                             span, 
356-                                         } , 
357-                                     ) ) 
358-                                 } ) 
359-                             }  else  { 
360-                                 cause
361-                             } 
362-                         } 
363-                         ProbeKind :: TraitCandidate  { 
364-                             source :  CandidateSource :: BuiltinImpl ( ..) , 
365-                             result :  _, 
366-                         }  => { 
367-                             cause. derived_cause ( parent_trait_pred,  traits:: BuiltinDerivedObligation ) 
368-                         } 
369-                         _ => cause, 
370-                     } ; 
371- 
372-                     Obligation  { 
373-                         cause, 
374-                         param_env :  nested_goal. goal ( ) . param_env , 
375-                         predicate :  nested_goal. goal ( ) . predicate , 
376-                         recursion_depth :  self_. obligation . recursion_depth  + 1 , 
377-                     } 
378-                 } , 
379-                 |self_| self_. visit_goal ( & nested_goal) , 
380-             ) ?; 
365+             self . with_derived_obligation ( obligation,  |this| nested_goal. visit_with ( this) ) ?; 
381366        } 
382367
383368        ControlFlow :: Break ( self . obligation . clone ( ) ) 
384369    } 
385370} 
386371
387- fn  find_best_leaf_obligation < ' tcx > ( 
388-     infcx :  & InferCtxt < ' tcx > , 
389-     obligation :  & PredicateObligation < ' tcx > , 
390- )  -> PredicateObligation < ' tcx >  { 
391-     let  obligation = infcx. resolve_vars_if_possible ( obligation. clone ( ) ) ; 
392-     infcx
393-         . visit_proof_tree ( 
394-             obligation. clone ( ) . into ( ) , 
395-             & mut  BestObligation  {  obligation :  obligation. clone ( )  } , 
396-         ) 
397-         . break_value ( ) 
398-         . unwrap_or ( obligation) 
372+ fn  derive_cause < ' tcx > ( 
373+     tcx :  TyCtxt < ' tcx > , 
374+     candidate_kind :  ProbeKind < ' tcx > , 
375+     mut  cause :  ObligationCause < ' tcx > , 
376+     idx :  usize , 
377+     parent_trait_pred :  ty:: PolyTraitPredicate < ' tcx > , 
378+ )  -> ObligationCause < ' tcx >  { 
379+     match  candidate_kind { 
380+         ProbeKind :: TraitCandidate  {  source :  CandidateSource :: Impl ( impl_def_id) ,  result :  _ }  => { 
381+             if  let  Some ( ( _,  span) )  =
382+                 tcx. predicates_of ( impl_def_id) . instantiate_identity ( tcx) . iter ( ) . nth ( idx) 
383+             { 
384+                 cause = cause. derived_cause ( parent_trait_pred,  |derived| { 
385+                     traits:: ImplDerivedObligation ( Box :: new ( traits:: ImplDerivedObligationCause  { 
386+                         derived, 
387+                         impl_or_alias_def_id :  impl_def_id, 
388+                         impl_def_predicate_index :  Some ( idx) , 
389+                         span, 
390+                     } ) ) 
391+                 } ) 
392+             } 
393+         } 
394+         ProbeKind :: TraitCandidate  {  source :  CandidateSource :: BuiltinImpl ( ..) ,  result :  _ }  => { 
395+             cause = cause. derived_cause ( parent_trait_pred,  traits:: BuiltinDerivedObligation ) ; 
396+         } 
397+         _ => { } 
398+     } ; 
399+     cause
399400} 
0 commit comments