@@ -162,8 +162,8 @@ enum NodeState {
162162#[ derive( Debug ) ]
163163pub struct Outcome < O , E > {
164164 /// Obligations that were completely evaluated, including all
165- /// (transitive) subobligations.
166- pub completed : Vec < O > ,
165+ /// (transitive) subobligations. Only computed if requested.
166+ pub completed : Option < Vec < O > > ,
167167
168168 /// Backtrace of obligations that were found to be in error.
169169 pub errors : Vec < Error < O , E > > ,
@@ -177,6 +177,14 @@ pub struct Outcome<O, E> {
177177 pub stalled : bool ,
178178}
179179
180+ /// Should `process_obligations` compute the `Outcome::completed` field of its
181+ /// result?
182+ #[ derive( PartialEq ) ]
183+ pub enum DoCompleted {
184+ No ,
185+ Yes ,
186+ }
187+
180188#[ derive( Debug , PartialEq , Eq ) ]
181189pub struct Error < O , E > {
182190 pub error : E ,
@@ -282,8 +290,8 @@ impl<O: ForestObligation> ObligationForest<O> {
282290 } ) ;
283291 }
284292 }
285- let successful_obligations = self . compress ( ) ;
286- assert ! ( successful_obligations. is_empty( ) ) ;
293+ let successful_obligations = self . compress ( DoCompleted :: Yes ) ;
294+ assert ! ( successful_obligations. unwrap ( ) . is_empty( ) ) ;
287295 errors
288296 }
289297
@@ -311,7 +319,8 @@ impl<O: ForestObligation> ObligationForest<O> {
311319 /// be called in a loop until `outcome.stalled` is false.
312320 ///
313321 /// This CANNOT be unrolled (presently, at least).
314- pub fn process_obligations < P > ( & mut self , processor : & mut P ) -> Outcome < O , P :: Error >
322+ pub fn process_obligations < P > ( & mut self , processor : & mut P , do_completed : DoCompleted )
323+ -> Outcome < O , P :: Error >
315324 where P : ObligationProcessor < Obligation =O >
316325 {
317326 debug ! ( "process_obligations(len={})" , self . nodes. len( ) ) ;
@@ -366,7 +375,7 @@ impl<O: ForestObligation> ObligationForest<O> {
366375 // There's no need to perform marking, cycle processing and compression when nothing
367376 // changed.
368377 return Outcome {
369- completed : vec ! [ ] ,
378+ completed : if do_completed == DoCompleted :: Yes { Some ( vec ! [ ] ) } else { None } ,
370379 errors,
371380 stalled,
372381 } ;
@@ -376,12 +385,12 @@ impl<O: ForestObligation> ObligationForest<O> {
376385 self . process_cycles ( processor) ;
377386
378387 // Now we have to compress the result
379- let completed_obligations = self . compress ( ) ;
388+ let completed = self . compress ( do_completed ) ;
380389
381390 debug ! ( "process_obligations: complete" ) ;
382391
383392 Outcome {
384- completed : completed_obligations ,
393+ completed,
385394 errors,
386395 stalled,
387396 }
@@ -524,7 +533,7 @@ impl<O: ForestObligation> ObligationForest<O> {
524533 /// Beforehand, all nodes must be marked as `Done` and no cycles
525534 /// on these nodes may be present. This is done by e.g. `process_cycles`.
526535 #[ inline( never) ]
527- fn compress ( & mut self ) -> Vec < O > {
536+ fn compress ( & mut self , do_completed : DoCompleted ) -> Option < Vec < O > > {
528537 let nodes_len = self . nodes . len ( ) ;
529538 let mut node_rewrites: Vec < _ > = self . scratch . take ( ) . unwrap ( ) ;
530539 node_rewrites. extend ( 0 ..nodes_len) ;
@@ -573,21 +582,26 @@ impl<O: ForestObligation> ObligationForest<O> {
573582 if dead_nodes == 0 {
574583 node_rewrites. truncate ( 0 ) ;
575584 self . scratch = Some ( node_rewrites) ;
576- return vec ! [ ] ;
585+ return if do_completed == DoCompleted :: Yes { Some ( vec ! [ ] ) } else { None } ;
577586 }
578587
579588 // Pop off all the nodes we killed and extract the success
580589 // stories.
581- let successful = ( 0 ..dead_nodes)
582- . map ( |_| self . nodes . pop ( ) . unwrap ( ) )
583- . flat_map ( |node| {
584- match node. state . get ( ) {
585- NodeState :: Error => None ,
586- NodeState :: Done => Some ( node. obligation ) ,
587- _ => unreachable ! ( )
588- }
589- } )
590- . collect ( ) ;
590+ let successful = if do_completed == DoCompleted :: Yes {
591+ Some ( ( 0 ..dead_nodes)
592+ . map ( |_| self . nodes . pop ( ) . unwrap ( ) )
593+ . flat_map ( |node| {
594+ match node. state . get ( ) {
595+ NodeState :: Error => None ,
596+ NodeState :: Done => Some ( node. obligation ) ,
597+ _ => unreachable ! ( )
598+ }
599+ } )
600+ . collect ( ) )
601+ } else {
602+ self . nodes . truncate ( self . nodes . len ( ) - dead_nodes) ;
603+ None
604+ } ;
591605 self . apply_rewrites ( & node_rewrites) ;
592606
593607 node_rewrites. truncate ( 0 ) ;
0 commit comments