@@ -3,12 +3,12 @@ use std::collections::hash_map::Entry;
3
3
4
4
use rustc_data_structures:: fx:: FxHashMap ;
5
5
use rustc_middle:: mir:: coverage:: { BlockMarkerId , BranchSpan , CoverageKind } ;
6
- use rustc_middle:: mir:: { self , BasicBlock , UnOp } ;
6
+ use rustc_middle:: mir:: { self , BasicBlock , SourceInfo , UnOp } ;
7
7
use rustc_middle:: thir:: { ExprId , ExprKind , Thir } ;
8
8
use rustc_middle:: ty:: TyCtxt ;
9
9
use rustc_span:: def_id:: LocalDefId ;
10
10
11
- use crate :: build:: Builder ;
11
+ use crate :: build:: { Builder , CFG } ;
12
12
13
13
pub ( crate ) struct BranchInfoBuilder {
14
14
/// Maps condition expressions to their enclosing `!`, for better instrumentation.
@@ -79,12 +79,42 @@ impl BranchInfoBuilder {
79
79
}
80
80
}
81
81
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
+
82
95
fn next_block_marker_id ( & mut self ) -> BlockMarkerId {
83
96
let id = BlockMarkerId :: from_usize ( self . num_block_markers ) ;
84
97
self . num_block_markers += 1 ;
85
98
id
86
99
}
87
100
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
+
88
118
pub ( crate ) fn into_done ( self ) -> Option < Box < mir:: coverage:: BranchInfo > > {
89
119
let Self { nots : _, num_block_markers, branch_spans } = self ;
90
120
@@ -107,7 +137,7 @@ impl Builder<'_, '_> {
107
137
mut else_block : BasicBlock ,
108
138
) {
109
139
// 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 } ;
111
141
112
142
// If this condition expression is nested within one or more `!` expressions,
113
143
// replace it with the enclosing `!` collected by `visit_unary_not`.
@@ -117,30 +147,9 @@ impl Builder<'_, '_> {
117
147
std:: mem:: swap ( & mut then_block, & mut else_block) ;
118
148
}
119
149
}
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
- } ;
136
150
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 } ;
139
152
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) ;
145
154
}
146
155
}
0 commit comments