@@ -95,6 +95,10 @@ pub trait ForestObligation: Clone + Debug {
9595pub trait ObligationProcessor {
9696 type Obligation : ForestObligation ;
9797 type Error : Debug ;
98+ type OUT : OutcomeTrait <
99+ Obligation = Self :: Obligation ,
100+ Error = Error < Self :: Obligation , Self :: Error > ,
101+ > ;
98102
99103 fn needs_process_obligation ( & self , obligation : & Self :: Obligation ) -> bool ;
100104
@@ -111,7 +115,11 @@ pub trait ObligationProcessor {
111115 /// In other words, if we had O1 which required O2 which required
112116 /// O3 which required O1, we would give an iterator yielding O1,
113117 /// O2, O3 (O1 is not yielded twice).
114- 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 >
115123 where
116124 I : Clone + Iterator < Item = & ' c Self :: Obligation > ;
117125}
@@ -402,12 +410,11 @@ impl<O: ForestObligation> ObligationForest<O> {
402410
403411 /// Performs a fixpoint computation over the obligation list.
404412 #[ inline( never) ]
405- 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
406414 where
407415 P : ObligationProcessor < Obligation = O > ,
408- OUT : OutcomeTrait < Obligation = O , Error = Error < O , P :: Error > > ,
409416 {
410- let mut outcome = OUT :: new ( ) ;
417+ let mut outcome = P :: OUT :: new ( ) ;
411418
412419 // Fixpoint computation: we repeat until the inner loop stalls.
413420 loop {
@@ -473,7 +480,7 @@ impl<O: ForestObligation> ObligationForest<O> {
473480 }
474481
475482 self . mark_successes ( ) ;
476- self . process_cycles ( processor) ;
483+ self . process_cycles ( processor, & mut outcome ) ;
477484 self . compress ( |obl| outcome. record_completed ( obl) ) ;
478485 }
479486
@@ -558,7 +565,7 @@ impl<O: ForestObligation> ObligationForest<O> {
558565
559566 /// Report cycles between all `Success` nodes, and convert all `Success`
560567 /// nodes to `Done`. This must be called after `mark_successes`.
561- fn process_cycles < P > ( & mut self , processor : & mut P )
568+ fn process_cycles < P > ( & mut self , processor : & mut P , outcome : & mut P :: OUT )
562569 where
563570 P : ObligationProcessor < Obligation = O > ,
564571 {
@@ -568,16 +575,21 @@ impl<O: ForestObligation> ObligationForest<O> {
568575 // to handle the no-op cases immediately to avoid the cost of the
569576 // function call.
570577 if node. state . get ( ) == NodeState :: Success {
571- self . find_cycles_from_node ( & mut stack, processor, index) ;
578+ self . find_cycles_from_node ( & mut stack, processor, index, outcome ) ;
572579 }
573580 }
574581
575582 debug_assert ! ( stack. is_empty( ) ) ;
576583 self . reused_node_vec = stack;
577584 }
578585
579- fn find_cycles_from_node < P > ( & self , stack : & mut Vec < usize > , processor : & mut P , index : usize )
580- 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
581593 P : ObligationProcessor < Obligation = O > ,
582594 {
583595 let node = & self . nodes [ index] ;
@@ -586,17 +598,20 @@ impl<O: ForestObligation> ObligationForest<O> {
586598 None => {
587599 stack. push ( index) ;
588600 for & dep_index in node. dependents . iter ( ) {
589- self . find_cycles_from_node ( stack, processor, dep_index) ;
601+ self . find_cycles_from_node ( stack, processor, dep_index, outcome ) ;
590602 }
591603 stack. pop ( ) ;
592604 node. state . set ( NodeState :: Done ) ;
593605 }
594606 Some ( rpos) => {
595607 // Cycle detected.
596- processor. process_backedge (
608+ let result = processor. process_backedge (
597609 stack[ rpos..] . iter ( ) . map ( |& i| & self . nodes [ i] . obligation ) ,
598610 PhantomData ,
599611 ) ;
612+ if let Err ( err) = result {
613+ outcome. record_error ( Error { error : err, backtrace : self . error_at ( index) } ) ;
614+ }
600615 }
601616 }
602617 }
0 commit comments