@@ -115,7 +115,11 @@ pub trait ObligationProcessor {
115
115
/// In other words, if we had O1 which required O2 which required
116
116
/// O3 which required O1, we would give an iterator yielding O1,
117
117
/// O2, O3 (O1 is not yielded twice).
118
- fn process_backedge < ' c , I > ( & mut self , cycle : I , _marker : PhantomData < & ' c Self :: Obligation > )
118
+ fn process_backedge < ' c , I > (
119
+ & mut self ,
120
+ cycle : I ,
121
+ _marker : PhantomData < & ' c Self :: Obligation > ,
122
+ ) -> Result < ( ) , Self :: Error >
119
123
where
120
124
I : Clone + Iterator < Item = & ' c Self :: Obligation > ;
121
125
}
@@ -406,12 +410,11 @@ impl<O: ForestObligation> ObligationForest<O> {
406
410
407
411
/// Performs a fixpoint computation over the obligation list.
408
412
#[ inline( never) ]
409
- pub fn process_obligations < P , OUT > ( & mut self , processor : & mut P ) -> OUT
413
+ pub fn process_obligations < P > ( & mut self , processor : & mut P ) -> P :: OUT
410
414
where
411
415
P : ObligationProcessor < Obligation = O > ,
412
- OUT : OutcomeTrait < Obligation = O , Error = Error < O , P :: Error > > ,
413
416
{
414
- let mut outcome = OUT :: new ( ) ;
417
+ let mut outcome = P :: OUT :: new ( ) ;
415
418
416
419
// Fixpoint computation: we repeat until the inner loop stalls.
417
420
loop {
@@ -477,7 +480,7 @@ impl<O: ForestObligation> ObligationForest<O> {
477
480
}
478
481
479
482
self . mark_successes ( ) ;
480
- self . process_cycles ( processor) ;
483
+ self . process_cycles ( processor, & mut outcome ) ;
481
484
self . compress ( |obl| outcome. record_completed ( obl) ) ;
482
485
}
483
486
@@ -562,7 +565,7 @@ impl<O: ForestObligation> ObligationForest<O> {
562
565
563
566
/// Report cycles between all `Success` nodes, and convert all `Success`
564
567
/// nodes to `Done`. This must be called after `mark_successes`.
565
- fn process_cycles < P > ( & mut self , processor : & mut P )
568
+ fn process_cycles < P > ( & mut self , processor : & mut P , outcome : & mut P :: OUT )
566
569
where
567
570
P : ObligationProcessor < Obligation = O > ,
568
571
{
@@ -572,16 +575,21 @@ impl<O: ForestObligation> ObligationForest<O> {
572
575
// to handle the no-op cases immediately to avoid the cost of the
573
576
// function call.
574
577
if node. state . get ( ) == NodeState :: Success {
575
- self . find_cycles_from_node ( & mut stack, processor, index) ;
578
+ self . find_cycles_from_node ( & mut stack, processor, index, outcome ) ;
576
579
}
577
580
}
578
581
579
582
debug_assert ! ( stack. is_empty( ) ) ;
580
583
self . reused_node_vec = stack;
581
584
}
582
585
583
- fn find_cycles_from_node < P > ( & self , stack : & mut Vec < usize > , processor : & mut P , index : usize )
584
- where
586
+ fn find_cycles_from_node < P > (
587
+ & self ,
588
+ stack : & mut Vec < usize > ,
589
+ processor : & mut P ,
590
+ index : usize ,
591
+ outcome : & mut P :: OUT ,
592
+ ) where
585
593
P : ObligationProcessor < Obligation = O > ,
586
594
{
587
595
let node = & self . nodes [ index] ;
@@ -590,17 +598,20 @@ impl<O: ForestObligation> ObligationForest<O> {
590
598
None => {
591
599
stack. push ( index) ;
592
600
for & dep_index in node. dependents . iter ( ) {
593
- self . find_cycles_from_node ( stack, processor, dep_index) ;
601
+ self . find_cycles_from_node ( stack, processor, dep_index, outcome ) ;
594
602
}
595
603
stack. pop ( ) ;
596
604
node. state . set ( NodeState :: Done ) ;
597
605
}
598
606
Some ( rpos) => {
599
607
// Cycle detected.
600
- processor. process_backedge (
608
+ let result = processor. process_backedge (
601
609
stack[ rpos..] . iter ( ) . map ( |& i| & self . nodes [ i] . obligation ) ,
602
610
PhantomData ,
603
611
) ;
612
+ if let Err ( err) = result {
613
+ outcome. record_error ( Error { error : err, backtrace : self . error_at ( index) } ) ;
614
+ }
604
615
}
605
616
}
606
617
}
0 commit comments