@@ -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