@@ -8,7 +8,7 @@ mod spans;
8
8
mod tests;
9
9
10
10
use self :: counters:: { BcbCounter , CoverageCounters } ;
11
- use self :: graph:: CoverageGraph ;
11
+ use self :: graph:: { BasicCoverageBlock , CoverageGraph } ;
12
12
use self :: spans:: CoverageSpans ;
13
13
14
14
use crate :: MirPass ;
@@ -106,7 +106,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
106
106
self . coverage_counters
107
107
. make_bcb_counters ( & self . basic_coverage_blocks , bcb_has_coverage_spans) ;
108
108
109
- let mappings = self . create_mappings_and_inject_coverage_statements ( & coverage_spans) ;
109
+ let mappings = self . create_mappings ( & coverage_spans) ;
110
+ self . inject_coverage_statements ( bcb_has_coverage_spans) ;
110
111
111
112
self . mir_body . function_coverage_info = Some ( Box :: new ( FunctionCoverageInfo {
112
113
function_source_hash : self . hir_info . function_source_hash ,
@@ -116,13 +117,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
116
117
} ) ) ;
117
118
}
118
119
119
- /// For each [`BcbCounter`] associated with a BCB node or BCB edge, create
120
- /// any corresponding mappings (for BCB nodes only), and inject any necessary
121
- /// coverage statements into MIR.
122
- fn create_mappings_and_inject_coverage_statements (
123
- & mut self ,
124
- coverage_spans : & CoverageSpans ,
125
- ) -> Vec < Mapping > {
120
+ /// For each coverage span extracted from MIR, create a corresponding
121
+ /// mapping.
122
+ ///
123
+ /// Precondition: All BCBs corresponding to those spans have been given
124
+ /// coverage counters.
125
+ fn create_mappings ( & self , coverage_spans : & CoverageSpans ) -> Vec < Mapping > {
126
126
let source_map = self . tcx . sess . source_map ( ) ;
127
127
let body_span = self . hir_info . body_span ;
128
128
@@ -131,30 +131,42 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
131
131
let file_name =
132
132
Symbol :: intern ( & source_file. name . for_codegen ( self . tcx . sess ) . to_string_lossy ( ) ) ;
133
133
134
- let mut mappings = Vec :: new ( ) ;
134
+ coverage_spans
135
+ . bcbs_with_coverage_spans ( )
136
+ // For each BCB with spans, get a coverage term for its counter.
137
+ . map ( |( bcb, spans) | {
138
+ let term = self
139
+ . coverage_counters
140
+ . bcb_counter ( bcb)
141
+ . expect ( "all BCBs with spans were given counters" )
142
+ . as_term ( ) ;
143
+ ( term, spans)
144
+ } )
145
+ // Flatten the spans into individual term/span pairs.
146
+ . flat_map ( |( term, spans) | spans. iter ( ) . map ( move |& span| ( term, span) ) )
147
+ // Convert each span to a code region, and create the final mapping.
148
+ . map ( |( term, span) | {
149
+ let code_region = make_code_region ( source_map, file_name, span, body_span) ;
150
+ Mapping { term, code_region }
151
+ } )
152
+ . collect :: < Vec < _ > > ( )
153
+ }
135
154
136
- // Process the counters and spans associated with BCB nodes.
155
+ /// For each BCB node or BCB edge that has an associated coverage counter,
156
+ /// inject any necessary coverage statements into MIR.
157
+ fn inject_coverage_statements (
158
+ & mut self ,
159
+ bcb_has_coverage_spans : impl Fn ( BasicCoverageBlock ) -> bool ,
160
+ ) {
161
+ // Process the counters associated with BCB nodes.
137
162
for ( bcb, counter_kind) in self . coverage_counters . bcb_node_counters ( ) {
138
- let spans = coverage_spans. spans_for_bcb ( bcb) ;
139
- let has_mappings = !spans. is_empty ( ) ;
140
-
141
- // If this BCB has any coverage spans, add corresponding mappings to
142
- // the mappings table.
143
- if has_mappings {
144
- let term = counter_kind. as_term ( ) ;
145
- mappings. extend ( spans. iter ( ) . map ( |& span| {
146
- let code_region = make_code_region ( source_map, file_name, span, body_span) ;
147
- Mapping { code_region, term }
148
- } ) ) ;
149
- }
150
-
151
163
let do_inject = match counter_kind {
152
164
// Counter-increment statements always need to be injected.
153
165
BcbCounter :: Counter { .. } => true ,
154
166
// The only purpose of expression-used statements is to detect
155
167
// when a mapping is unreachable, so we only inject them for
156
168
// expressions with one or more mappings.
157
- BcbCounter :: Expression { .. } => has_mappings ,
169
+ BcbCounter :: Expression { .. } => bcb_has_coverage_spans ( bcb ) ,
158
170
} ;
159
171
if do_inject {
160
172
inject_statement (
@@ -192,8 +204,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
192
204
// Inject a counter into the newly-created BB.
193
205
inject_statement ( self . mir_body , self . make_mir_coverage_kind ( counter_kind) , new_bb) ;
194
206
}
195
-
196
- mappings
197
207
}
198
208
199
209
fn make_mir_coverage_kind ( & self , counter_kind : & BcbCounter ) -> CoverageKind {
0 commit comments