1
+ use std:: cmp:: Ordering ;
2
+ use std:: ops:: { Index , IndexMut } ;
3
+
4
+ use rustc_data_structures:: captures:: Captures ;
1
5
use rustc_data_structures:: graph:: dominators:: { self , Dominators } ;
2
6
use rustc_data_structures:: graph:: { self , GraphSuccessors , WithNumNodes , WithStartNode } ;
3
7
use rustc_index:: bit_set:: BitSet ;
4
8
use rustc_index:: { IndexSlice , IndexVec } ;
5
9
use rustc_middle:: mir:: { self , BasicBlock , TerminatorKind } ;
6
10
7
- use std:: cmp:: Ordering ;
8
- use std:: ops:: { Index , IndexMut } ;
9
-
10
11
/// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s
11
12
/// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s.
12
13
#[ derive( Debug ) ]
@@ -363,21 +364,21 @@ impl std::fmt::Debug for BcbBranch {
363
364
fn bcb_filtered_successors < ' a , ' tcx > (
364
365
body : & ' a mir:: Body < ' tcx > ,
365
366
bb : BasicBlock ,
366
- ) -> Box < dyn Iterator < Item = BasicBlock > + ' a > {
367
- let term_kind = & body[ bb] . terminator ( ) . kind ;
368
- Box :: new (
369
- match & term_kind {
370
- // SwitchInt successors are never unwind, and all of them should be traversed.
371
- TerminatorKind :: SwitchInt { ref targets , .. } => {
372
- None . into_iter ( ) . chain ( targets . all_targets ( ) . into_iter ( ) . copied ( ) )
373
- }
374
- // For all other kinds, return only the first successor, if any, and ignore unwinds.
375
- // NOTE: `chain(&[])` is required to coerce the `option::iter` (from
376
- // `next().into_iter()`) into the `mir::Successors` aliased type.
377
- _ => term_kind . successors ( ) . next ( ) . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) ) ,
378
- }
379
- . filter ( move | & successor| body [ successor ] . terminator ( ) . kind != TerminatorKind :: Unreachable ) ,
380
- )
367
+ ) -> impl Iterator < Item = BasicBlock > + Captures < ' a > + Captures < ' tcx > {
368
+ let terminator = body[ bb] . terminator ( ) ;
369
+
370
+ let take_n_successors = match terminator . kind {
371
+ // SwitchInt successors are never unwinds, so all of them should be traversed.
372
+ TerminatorKind :: SwitchInt { .. } => usize :: MAX ,
373
+ // For all other kinds, return only the first successor (if any), ignoring any
374
+ // unwind successors.
375
+ _ => 1 ,
376
+ } ;
377
+
378
+ terminator
379
+ . successors ( )
380
+ . take ( take_n_successors )
381
+ . filter ( move | & successor| body [ successor ] . terminator ( ) . kind != TerminatorKind :: Unreachable )
381
382
}
382
383
383
384
/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
@@ -556,9 +557,10 @@ struct ShortCircuitPreorder<'a, 'tcx, F> {
556
557
filtered_successors : F ,
557
558
}
558
559
559
- impl < ' a , ' tcx , F > ShortCircuitPreorder < ' a , ' tcx , F >
560
+ impl < ' a , ' tcx , F , Iter > ShortCircuitPreorder < ' a , ' tcx , F >
560
561
where
561
- F : Fn ( & ' a mir:: Body < ' tcx > , BasicBlock ) -> Box < dyn Iterator < Item = BasicBlock > + ' a > ,
562
+ F : Fn ( & ' a mir:: Body < ' tcx > , BasicBlock ) -> Iter ,
563
+ Iter : Iterator < Item = BasicBlock > ,
562
564
{
563
565
fn new ( body : & ' a mir:: Body < ' tcx > , filtered_successors : F ) -> Self {
564
566
Self {
@@ -570,9 +572,10 @@ where
570
572
}
571
573
}
572
574
573
- impl < ' a , ' tcx , F > Iterator for ShortCircuitPreorder < ' a , ' tcx , F >
575
+ impl < ' a , ' tcx , F , Iter > Iterator for ShortCircuitPreorder < ' a , ' tcx , F >
574
576
where
575
- F : Fn ( & ' a mir:: Body < ' tcx > , BasicBlock ) -> Box < dyn Iterator < Item = BasicBlock > + ' a > ,
577
+ F : Fn ( & ' a mir:: Body < ' tcx > , BasicBlock ) -> Iter ,
578
+ Iter : Iterator < Item = BasicBlock > ,
576
579
{
577
580
type Item = BasicBlock ;
578
581
0 commit comments