@@ -3,12 +3,12 @@ use std::collections::hash_map::Entry;
33
44use rustc_data_structures:: fx:: FxHashMap ;
55use rustc_middle:: mir:: coverage:: { BlockMarkerId , BranchSpan , CoverageKind } ;
6- use rustc_middle:: mir:: { self , BasicBlock , UnOp } ;
6+ use rustc_middle:: mir:: { self , BasicBlock , SourceInfo , UnOp } ;
77use rustc_middle:: thir:: { ExprId , ExprKind , Thir } ;
88use rustc_middle:: ty:: TyCtxt ;
99use rustc_span:: def_id:: LocalDefId ;
1010
11- use crate :: build:: Builder ;
11+ use crate :: build:: { Builder , CFG } ;
1212
1313pub ( crate ) struct BranchInfoBuilder {
1414 /// Maps condition expressions to their enclosing `!`, for better instrumentation.
@@ -79,12 +79,42 @@ impl BranchInfoBuilder {
7979 }
8080 }
8181
82+ fn add_two_way_branch (
83+ & mut self ,
84+ cfg : & mut CFG < ' _ > ,
85+ source_info : SourceInfo ,
86+ true_block : BasicBlock ,
87+ false_block : BasicBlock ,
88+ ) {
89+ let true_marker = self . inject_block_marker ( cfg, source_info, true_block) ;
90+ let false_marker = self . inject_block_marker ( cfg, source_info, false_block) ;
91+
92+ self . branch_spans . push ( BranchSpan { span : source_info. span , true_marker, false_marker } ) ;
93+ }
94+
8295 fn next_block_marker_id ( & mut self ) -> BlockMarkerId {
8396 let id = BlockMarkerId :: from_usize ( self . num_block_markers ) ;
8497 self . num_block_markers += 1 ;
8598 id
8699 }
87100
101+ fn inject_block_marker (
102+ & mut self ,
103+ cfg : & mut CFG < ' _ > ,
104+ source_info : SourceInfo ,
105+ block : BasicBlock ,
106+ ) -> BlockMarkerId {
107+ let id = self . next_block_marker_id ( ) ;
108+
109+ let marker_statement = mir:: Statement {
110+ source_info,
111+ kind : mir:: StatementKind :: Coverage ( CoverageKind :: BlockMarker { id } ) ,
112+ } ;
113+ cfg. push ( block, marker_statement) ;
114+
115+ id
116+ }
117+
88118 pub ( crate ) fn into_done ( self ) -> Option < Box < mir:: coverage:: BranchInfo > > {
89119 let Self { nots : _, num_block_markers, branch_spans } = self ;
90120
@@ -107,7 +137,7 @@ impl Builder<'_, '_> {
107137 mut else_block : BasicBlock ,
108138 ) {
109139 // Bail out if branch coverage is not enabled for this function.
110- let Some ( branch_info) = self . coverage_branch_info . as_ref ( ) else { return } ;
140+ let Some ( branch_info) = self . coverage_branch_info . as_mut ( ) else { return } ;
111141
112142 // If this condition expression is nested within one or more `!` expressions,
113143 // replace it with the enclosing `!` collected by `visit_unary_not`.
@@ -117,30 +147,9 @@ impl Builder<'_, '_> {
117147 std:: mem:: swap ( & mut then_block, & mut else_block) ;
118148 }
119149 }
120- let source_info = self . source_info ( self . thir [ expr_id] . span ) ;
121-
122- // Now that we have `source_info`, we can upgrade to a &mut reference.
123- let branch_info = self . coverage_branch_info . as_mut ( ) . expect ( "upgrading & to &mut" ) ;
124-
125- let mut inject_branch_marker = |block : BasicBlock | {
126- let id = branch_info. next_block_marker_id ( ) ;
127-
128- let marker_statement = mir:: Statement {
129- source_info,
130- kind : mir:: StatementKind :: Coverage ( CoverageKind :: BlockMarker { id } ) ,
131- } ;
132- self . cfg . push ( block, marker_statement) ;
133-
134- id
135- } ;
136150
137- let true_marker = inject_branch_marker ( then_block) ;
138- let false_marker = inject_branch_marker ( else_block) ;
151+ let source_info = SourceInfo { span : self . thir [ expr_id] . span , scope : self . source_scope } ;
139152
140- branch_info. branch_spans . push ( BranchSpan {
141- span : source_info. span ,
142- true_marker,
143- false_marker,
144- } ) ;
153+ branch_info. add_two_way_branch ( & mut self . cfg , source_info, then_block, else_block) ;
145154 }
146155}
0 commit comments