@@ -407,17 +407,17 @@ fn process_child_obligations<'a,'tcx>(
407407 // ~~~ (*) see above
408408 debug ! ( "process_child_obligations: cycle index = {}" , index) ;
409409
410- if coinductive_match ( selcx, & obligation, & backtrace) {
410+ let backtrace = backtrace. clone ( ) ;
411+ let cycle: Vec < _ > =
412+ iter:: once ( & obligation)
413+ . chain ( Some ( pending_obligation) )
414+ . chain ( backtrace. take ( index + 1 ) . map ( |p| & p. obligation ) )
415+ . cloned ( )
416+ . collect ( ) ;
417+ if coinductive_match ( selcx, & cycle) {
411418 debug ! ( "process_child_obligations: coinductive match" ) ;
412419 None
413420 } else {
414- let backtrace = backtrace. clone ( ) ;
415- let cycle: Vec < _ > =
416- iter:: once ( & obligation)
417- . chain ( Some ( pending_obligation) )
418- . chain ( backtrace. take ( index + 1 ) . map ( |p| & p. obligation ) )
419- . cloned ( )
420- . collect ( ) ;
421421 report_overflow_error_cycle ( selcx. infcx ( ) , & cycle) ;
422422 }
423423 } else {
@@ -663,47 +663,40 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
663663
664664/// For defaulted traits, we use a co-inductive strategy to solve, so
665665/// that recursion is ok. This routine returns true if the top of the
666- /// stack (`top_obligation` and `top_data `):
666+ /// stack (`cycle[0] `):
667667/// - is a defaulted trait, and
668668/// - it also appears in the backtrace at some position `X`; and,
669669/// - all the predicates at positions `X..` between `X` an the top are
670670/// also defaulted traits.
671671fn coinductive_match < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
672- top_obligation : & PredicateObligation < ' tcx > ,
673- backtrace : & Backtrace < PendingPredicateObligation < ' tcx > > )
672+ cycle : & [ PredicateObligation < ' tcx > ] )
674673 -> bool
675674{
676- // only trait predicates can be coinductive matches
677- let top_data = match top_obligation. predicate {
678- ty:: Predicate :: Trait ( ref data) => data,
679- _ => return false
680- } ;
681-
682- if selcx. tcx ( ) . trait_has_default_impl ( top_data. def_id ( ) ) {
683- debug ! ( "coinductive_match: top_data={:?}" , top_data) ;
684- for bt_obligation in backtrace. clone ( ) {
685- debug ! ( "coinductive_match: bt_obligation={:?}" , bt_obligation) ;
686-
687- // *Everything* in the backtrace must be a defaulted trait.
688- match bt_obligation. obligation . predicate {
689- ty:: Predicate :: Trait ( ref data) => {
690- if !selcx. tcx ( ) . trait_has_default_impl ( data. def_id ( ) ) {
691- debug ! ( "coinductive_match: trait does not have default impl" ) ;
692- break ;
693- }
694- }
695- _ => { break ; }
696- }
675+ let len = cycle. len ( ) ;
697676
698- // And we must find a recursive match.
699- if bt_obligation. obligation . predicate == top_obligation. predicate {
700- debug ! ( "coinductive_match: found a match in the backtrace" ) ;
701- return true ;
702- }
677+ assert_eq ! ( cycle[ 0 ] . predicate, cycle[ len - 1 ] . predicate) ;
678+
679+ cycle[ 0 ..len-1 ]
680+ . iter ( )
681+ . all ( |bt_obligation| {
682+ let result = coinductive_obligation ( selcx, bt_obligation) ;
683+ debug ! ( "coinductive_match: bt_obligation={:?} coinductive={}" ,
684+ bt_obligation, result) ;
685+ result
686+ } )
687+ }
688+
689+ fn coinductive_obligation < ' a , ' tcx > ( selcx : & SelectionContext < ' a , ' tcx > ,
690+ obligation : & PredicateObligation < ' tcx > )
691+ -> bool {
692+ match obligation. predicate {
693+ ty:: Predicate :: Trait ( ref data) => {
694+ selcx. tcx ( ) . trait_has_default_impl ( data. def_id ( ) )
695+ }
696+ _ => {
697+ false
703698 }
704699 }
705-
706- false
707700}
708701
709702fn register_region_obligation < ' tcx > ( t_a : Ty < ' tcx > ,
0 commit comments