@@ -162,8 +162,8 @@ enum NodeState {
162
162
#[ derive( Debug ) ]
163
163
pub struct Outcome < O , E > {
164
164
/// 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 > > ,
167
167
168
168
/// Backtrace of obligations that were found to be in error.
169
169
pub errors : Vec < Error < O , E > > ,
@@ -177,6 +177,14 @@ pub struct Outcome<O, E> {
177
177
pub stalled : bool ,
178
178
}
179
179
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
+
180
188
#[ derive( Debug , PartialEq , Eq ) ]
181
189
pub struct Error < O , E > {
182
190
pub error : E ,
@@ -282,8 +290,8 @@ impl<O: ForestObligation> ObligationForest<O> {
282
290
} ) ;
283
291
}
284
292
}
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( ) ) ;
287
295
errors
288
296
}
289
297
@@ -311,7 +319,8 @@ impl<O: ForestObligation> ObligationForest<O> {
311
319
/// be called in a loop until `outcome.stalled` is false.
312
320
///
313
321
/// 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 >
315
324
where P : ObligationProcessor < Obligation =O >
316
325
{
317
326
debug ! ( "process_obligations(len={})" , self . nodes. len( ) ) ;
@@ -366,7 +375,7 @@ impl<O: ForestObligation> ObligationForest<O> {
366
375
// There's no need to perform marking, cycle processing and compression when nothing
367
376
// changed.
368
377
return Outcome {
369
- completed : vec ! [ ] ,
378
+ completed : if do_completed == DoCompleted :: Yes { Some ( vec ! [ ] ) } else { None } ,
370
379
errors,
371
380
stalled,
372
381
} ;
@@ -376,12 +385,12 @@ impl<O: ForestObligation> ObligationForest<O> {
376
385
self . process_cycles ( processor) ;
377
386
378
387
// Now we have to compress the result
379
- let completed_obligations = self . compress ( ) ;
388
+ let completed = self . compress ( do_completed ) ;
380
389
381
390
debug ! ( "process_obligations: complete" ) ;
382
391
383
392
Outcome {
384
- completed : completed_obligations ,
393
+ completed,
385
394
errors,
386
395
stalled,
387
396
}
@@ -524,7 +533,7 @@ impl<O: ForestObligation> ObligationForest<O> {
524
533
/// Beforehand, all nodes must be marked as `Done` and no cycles
525
534
/// on these nodes may be present. This is done by e.g. `process_cycles`.
526
535
#[ inline( never) ]
527
- fn compress ( & mut self ) -> Vec < O > {
536
+ fn compress ( & mut self , do_completed : DoCompleted ) -> Option < Vec < O > > {
528
537
let nodes_len = self . nodes . len ( ) ;
529
538
let mut node_rewrites: Vec < _ > = self . scratch . take ( ) . unwrap ( ) ;
530
539
node_rewrites. extend ( 0 ..nodes_len) ;
@@ -573,21 +582,26 @@ impl<O: ForestObligation> ObligationForest<O> {
573
582
if dead_nodes == 0 {
574
583
node_rewrites. truncate ( 0 ) ;
575
584
self . scratch = Some ( node_rewrites) ;
576
- return vec ! [ ] ;
585
+ return if do_completed == DoCompleted :: Yes { Some ( vec ! [ ] ) } else { None } ;
577
586
}
578
587
579
588
// Pop off all the nodes we killed and extract the success
580
589
// 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
+ } ;
591
605
self . apply_rewrites ( & node_rewrites) ;
592
606
593
607
node_rewrites. truncate ( 0 ) ;
0 commit comments