@@ -359,17 +359,8 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
359359 let obligation = & pending_obligation. obligation ;
360360 match obligation. predicate {
361361 ty:: Predicate :: Trait ( ref data) => {
362- // For defaulted traits, we use a co-inductive strategy to
363- // solve, so that recursion is ok.
364- if selcx. tcx ( ) . trait_has_default_impl ( data. def_id ( ) ) {
365- debug ! ( "process_predicate: trait has default impl" ) ;
366- for bt_obligation in backtrace {
367- debug ! ( "process_predicate: bt_obligation = {:?}" , bt_obligation. obligation) ;
368- if bt_obligation. obligation . predicate == obligation. predicate {
369- debug ! ( "process_predicate: found a match!" ) ;
370- return Ok ( Some ( vec ! [ ] ) ) ;
371- }
372- }
362+ if coinductive_match ( selcx, obligation, data, & backtrace) {
363+ return Ok ( Some ( vec ! [ ] ) ) ;
373364 }
374365
375366 let trait_obligation = obligation. with ( data. clone ( ) ) ;
@@ -483,6 +474,42 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
483474 }
484475}
485476
477+ /// For defaulted traits, we use a co-inductive strategy to solve, so
478+ /// that recursion is ok. This routine returns true if the top of the
479+ /// stack (`top_obligation` and `top_data`):
480+ /// - is a defaulted trait, and
481+ /// - it also appears in the backtrace at some position `X`; and,
482+ /// - all the predicates at positions `X..` between `X` an the top are
483+ /// also defaulted traits.
484+ fn coinductive_match < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
485+ top_obligation : & PredicateObligation < ' tcx > ,
486+ top_data : & ty:: PolyTraitPredicate < ' tcx > ,
487+ backtrace : & Backtrace < PendingPredicateObligation < ' tcx > > )
488+ -> bool
489+ {
490+ if selcx. tcx ( ) . trait_has_default_impl ( top_data. def_id ( ) ) {
491+ for bt_obligation in backtrace. clone ( ) {
492+ // *Everything* in the backtrace must be a defaulted trait.
493+ match bt_obligation. obligation . predicate {
494+ ty:: Predicate :: Trait ( ref data) => {
495+ if !selcx. tcx ( ) . trait_has_default_impl ( data. def_id ( ) ) {
496+ break ;
497+ }
498+ }
499+ _ => { break ; }
500+ }
501+
502+ // And we must find a recursive match.
503+ if bt_obligation. obligation . predicate == top_obligation. predicate {
504+ debug ! ( "process_predicate: found a match in the backtrace" ) ;
505+ return true ;
506+ }
507+ }
508+ }
509+
510+ false
511+ }
512+
486513fn register_region_obligation < ' tcx > ( t_a : Ty < ' tcx > ,
487514 r_b : ty:: Region ,
488515 cause : ObligationCause < ' tcx > ,
0 commit comments