1+ use std:: cmp:: Ordering ;
2+ use std:: ops:: { Index , IndexMut } ;
3+
4+ use rustc_data_structures:: captures:: Captures ;
15use rustc_data_structures:: graph:: dominators:: { self , Dominators } ;
26use rustc_data_structures:: graph:: { self , GraphSuccessors , WithNumNodes , WithStartNode } ;
37use rustc_index:: bit_set:: BitSet ;
48use rustc_index:: { IndexSlice , IndexVec } ;
59use rustc_middle:: mir:: { self , BasicBlock , TerminatorKind } ;
610
7- use std:: cmp:: Ordering ;
8- use std:: ops:: { Index , IndexMut } ;
9-
1011/// A coverage-specific simplification of the MIR control flow graph (CFG). The `CoverageGraph`s
1112/// nodes are `BasicCoverageBlock`s, which encompass one or more MIR `BasicBlock`s.
1213#[ derive( Debug ) ]
@@ -363,21 +364,21 @@ impl std::fmt::Debug for BcbBranch {
363364fn bcb_filtered_successors < ' a , ' tcx > (
364365 body : & ' a mir:: Body < ' tcx > ,
365366 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 )
381382}
382383
383384/// Maintains separate worklists for each loop in the BasicCoverageBlock CFG, plus one for the
@@ -556,9 +557,10 @@ struct ShortCircuitPreorder<'a, 'tcx, F> {
556557 filtered_successors : F ,
557558}
558559
559- impl < ' a , ' tcx , F > ShortCircuitPreorder < ' a , ' tcx , F >
560+ impl < ' a , ' tcx , F , Iter > ShortCircuitPreorder < ' a , ' tcx , F >
560561where
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 > ,
562564{
563565 fn new ( body : & ' a mir:: Body < ' tcx > , filtered_successors : F ) -> Self {
564566 Self {
@@ -570,9 +572,10 @@ where
570572 }
571573}
572574
573- impl < ' a , ' tcx , F > Iterator for ShortCircuitPreorder < ' a , ' tcx , F >
575+ impl < ' a , ' tcx , F , Iter > Iterator for ShortCircuitPreorder < ' a , ' tcx , F >
574576where
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 > ,
576579{
577580 type Item = BasicBlock ;
578581
0 commit comments