@@ -407,17 +407,17 @@ fn process_child_obligations<'a,'tcx>(
407
407
// ~~~ (*) see above
408
408
debug ! ( "process_child_obligations: cycle index = {}" , index) ;
409
409
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) {
411
418
debug ! ( "process_child_obligations: coinductive match" ) ;
412
419
None
413
420
} 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 ( ) ;
421
421
report_overflow_error_cycle ( selcx. infcx ( ) , & cycle) ;
422
422
}
423
423
} else {
@@ -663,47 +663,40 @@ fn process_predicate1<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>,
663
663
664
664
/// For defaulted traits, we use a co-inductive strategy to solve, so
665
665
/// that recursion is ok. This routine returns true if the top of the
666
- /// stack (`top_obligation` and `top_data `):
666
+ /// stack (`cycle[0] `):
667
667
/// - is a defaulted trait, and
668
668
/// - it also appears in the backtrace at some position `X`; and,
669
669
/// - all the predicates at positions `X..` between `X` an the top are
670
670
/// also defaulted traits.
671
671
fn coinductive_match < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
672
- top_obligation : & PredicateObligation < ' tcx > ,
673
- backtrace : & Backtrace < PendingPredicateObligation < ' tcx > > )
672
+ cycle : & [ PredicateObligation < ' tcx > ] )
674
673
-> bool
675
674
{
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 ( ) ;
697
676
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
703
698
}
704
699
}
705
-
706
- false
707
700
}
708
701
709
702
fn register_region_obligation < ' tcx > ( t_a : Ty < ' tcx > ,
0 commit comments