@@ -95,6 +95,10 @@ pub trait ForestObligation: Clone + Debug {
95
95
pub trait ObligationProcessor {
96
96
type Obligation : ForestObligation ;
97
97
type Error : Debug ;
98
+ type OUT : OutcomeTrait <
99
+ Obligation = Self :: Obligation ,
100
+ Error = Error < Self :: Obligation , Self :: Error > ,
101
+ > ;
98
102
99
103
fn needs_process_obligation ( & self , obligation : & Self :: Obligation ) -> bool ;
100
104
@@ -111,7 +115,11 @@ pub trait ObligationProcessor {
111
115
/// In other words, if we had O1 which required O2 which required
112
116
/// O3 which required O1, we would give an iterator yielding O1,
113
117
/// 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 >
115
123
where
116
124
I : Clone + Iterator < Item = & ' c Self :: Obligation > ;
117
125
}
@@ -402,12 +410,11 @@ impl<O: ForestObligation> ObligationForest<O> {
402
410
403
411
/// Performs a fixpoint computation over the obligation list.
404
412
#[ 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
406
414
where
407
415
P : ObligationProcessor < Obligation = O > ,
408
- OUT : OutcomeTrait < Obligation = O , Error = Error < O , P :: Error > > ,
409
416
{
410
- let mut outcome = OUT :: new ( ) ;
417
+ let mut outcome = P :: OUT :: new ( ) ;
411
418
412
419
// Fixpoint computation: we repeat until the inner loop stalls.
413
420
loop {
@@ -473,7 +480,7 @@ impl<O: ForestObligation> ObligationForest<O> {
473
480
}
474
481
475
482
self . mark_successes ( ) ;
476
- self . process_cycles ( processor) ;
483
+ self . process_cycles ( processor, & mut outcome ) ;
477
484
self . compress ( |obl| outcome. record_completed ( obl) ) ;
478
485
}
479
486
@@ -558,7 +565,7 @@ impl<O: ForestObligation> ObligationForest<O> {
558
565
559
566
/// Report cycles between all `Success` nodes, and convert all `Success`
560
567
/// 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 )
562
569
where
563
570
P : ObligationProcessor < Obligation = O > ,
564
571
{
@@ -568,16 +575,21 @@ impl<O: ForestObligation> ObligationForest<O> {
568
575
// to handle the no-op cases immediately to avoid the cost of the
569
576
// function call.
570
577
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 ) ;
572
579
}
573
580
}
574
581
575
582
debug_assert ! ( stack. is_empty( ) ) ;
576
583
self . reused_node_vec = stack;
577
584
}
578
585
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
581
593
P : ObligationProcessor < Obligation = O > ,
582
594
{
583
595
let node = & self . nodes [ index] ;
@@ -586,17 +598,20 @@ impl<O: ForestObligation> ObligationForest<O> {
586
598
None => {
587
599
stack. push ( index) ;
588
600
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 ) ;
590
602
}
591
603
stack. pop ( ) ;
592
604
node. state . set ( NodeState :: Done ) ;
593
605
}
594
606
Some ( rpos) => {
595
607
// Cycle detected.
596
- processor. process_backedge (
608
+ let result = processor. process_backedge (
597
609
stack[ rpos..] . iter ( ) . map ( |& i| & self . nodes [ i] . obligation ) ,
598
610
PhantomData ,
599
611
) ;
612
+ if let Err ( err) = result {
613
+ outcome. record_error ( Error { error : err, backtrace : self . error_at ( index) } ) ;
614
+ }
600
615
}
601
616
}
602
617
}
0 commit comments