@@ -145,18 +145,17 @@ impl CoverageGraph {
145145 bcbs. push ( bcb_data) ;
146146 } ;
147147
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.
154152
155153 // Accumulates a chain of blocks that will be combined into one BCB.
156154 let mut current_chain = Vec :: new ( ) ;
157155
158156 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 )
160159 . filter ( |& bb| mir_body[ bb] . terminator ( ) . kind != TerminatorKind :: Unreachable )
161160 {
162161 if let Some ( & prev) = current_chain. last ( ) {
@@ -596,28 +595,27 @@ impl<'a> TraverseCoverageGraphWithLoops<'a> {
596595 }
597596}
598597
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 ;
620612
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+ }
623621}
0 commit comments