@@ -145,18 +145,17 @@ impl CoverageGraph {
145
145
bcbs. push ( bcb_data) ;
146
146
} ;
147
147
148
- // Walk the MIR CFG using a Preorder traversal, which starts from `START_BLOCK` and follows
149
- // each block terminator's `successors()`. Coverage spans must map to actual source code,
150
- // so compiler generated blocks and paths can be ignored. To that end, the CFG traversal
151
- // intentionally omits unwind paths.
152
- // FIXME(#78544): MIR InstrumentCoverage: Improve coverage of `#[should_panic]` tests and
153
- // `catch_unwind()` handlers.
148
+ // Traverse the MIR control-flow graph, accumulating chains of blocks
149
+ // that can be combined into a single node in the coverage graph.
150
+ // A depth-first search ensures that if two nodes can be chained
151
+ // together, they will be adjacent in the traversal order.
154
152
155
153
// Accumulates a chain of blocks that will be combined into one BCB.
156
154
let mut current_chain = Vec :: new ( ) ;
157
155
158
156
let filtered_successors = |bb| bcb_filtered_successors ( mir_body[ bb] . terminator ( ) ) ;
159
- for bb in short_circuit_preorder ( mir_body, filtered_successors)
157
+ let subgraph = CoverageRelevantSubgraph :: new ( & mir_body. basic_blocks ) ;
158
+ for bb in graph:: depth_first_search ( subgraph, mir:: START_BLOCK )
160
159
. filter ( |& bb| mir_body[ bb] . terminator ( ) . kind != TerminatorKind :: Unreachable )
161
160
{
162
161
if let Some ( & prev) = current_chain. last ( ) {
@@ -596,28 +595,27 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
596
595
}
597
596
}
598
597
599
- fn short_circuit_preorder < ' a , ' tcx , F , Iter > (
600
- body : & ' a mir:: Body < ' tcx > ,
601
- filtered_successors : F ,
602
- ) -> impl Iterator < Item = BasicBlock > + Captures < ' a > + Captures < ' tcx >
603
- where
604
- F : Fn ( BasicBlock ) -> Iter ,
605
- Iter : IntoIterator < Item = BasicBlock > ,
606
- {
607
- let mut visited = BitSet :: new_empty ( body. basic_blocks . len ( ) ) ;
608
- let mut worklist = vec ! [ mir:: START_BLOCK ] ;
609
-
610
- std:: iter:: from_fn ( move || {
611
- while let Some ( bb) = worklist. pop ( ) {
612
- if !visited. insert ( bb) {
613
- continue ;
614
- }
615
-
616
- worklist. extend ( filtered_successors ( bb) ) ;
617
-
618
- return Some ( bb) ;
619
- }
598
+ /// Wrapper around a [`mir::BasicBlocks`] graph that restricts each node's
599
+ /// successors to only the ones considered "relevant" when building a coverage
600
+ /// graph.
601
+ #[ derive( Clone , Copy ) ]
602
+ struct CoverageRelevantSubgraph < ' a , ' tcx > {
603
+ basic_blocks : & ' a mir:: BasicBlocks < ' tcx > ,
604
+ }
605
+ impl < ' a , ' tcx > CoverageRelevantSubgraph < ' a , ' tcx > {
606
+ fn new ( basic_blocks : & ' a mir:: BasicBlocks < ' tcx > ) -> Self {
607
+ Self { basic_blocks }
608
+ }
609
+ }
610
+ impl < ' a , ' tcx > graph:: DirectedGraph for CoverageRelevantSubgraph < ' a , ' tcx > {
611
+ type Node = BasicBlock ;
620
612
621
- None
622
- } )
613
+ fn num_nodes ( & self ) -> usize {
614
+ self . basic_blocks . num_nodes ( )
615
+ }
616
+ }
617
+ impl < ' a , ' tcx > graph:: Successors for CoverageRelevantSubgraph < ' a , ' tcx > {
618
+ fn successors ( & self , node : Self :: Node ) -> impl Iterator < Item = Self :: Node > {
619
+ bcb_filtered_successors ( self . basic_blocks [ node] . terminator ( ) ) . into_iter ( )
620
+ }
623
621
}
0 commit comments