@@ -8,7 +8,7 @@ mod spans;
88mod tests;
99
1010use self :: counters:: { BcbCounter , CoverageCounters } ;
11- use self :: graph:: CoverageGraph ;
11+ use self :: graph:: { BasicCoverageBlock , CoverageGraph } ;
1212use self :: spans:: CoverageSpans ;
1313
1414use crate :: MirPass ;
@@ -106,7 +106,8 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
106106 self . coverage_counters
107107 . make_bcb_counters ( & self . basic_coverage_blocks , bcb_has_coverage_spans) ;
108108
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) ;
110111
111112 self . mir_body . function_coverage_info = Some ( Box :: new ( FunctionCoverageInfo {
112113 function_source_hash : self . hir_info . function_source_hash ,
@@ -116,13 +117,12 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
116117 } ) ) ;
117118 }
118119
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 > {
126126 let source_map = self . tcx . sess . source_map ( ) ;
127127 let body_span = self . hir_info . body_span ;
128128
@@ -131,30 +131,42 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
131131 let file_name =
132132 Symbol :: intern ( & source_file. name . for_codegen ( self . tcx . sess ) . to_string_lossy ( ) ) ;
133133
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+ }
135154
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.
137162 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-
151163 let do_inject = match counter_kind {
152164 // Counter-increment statements always need to be injected.
153165 BcbCounter :: Counter { .. } => true ,
154166 // The only purpose of expression-used statements is to detect
155167 // when a mapping is unreachable, so we only inject them for
156168 // expressions with one or more mappings.
157- BcbCounter :: Expression { .. } => has_mappings ,
169+ BcbCounter :: Expression { .. } => bcb_has_coverage_spans ( bcb ) ,
158170 } ;
159171 if do_inject {
160172 inject_statement (
@@ -192,8 +204,6 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
192204 // Inject a counter into the newly-created BB.
193205 inject_statement ( self . mir_body , self . make_mir_coverage_kind ( counter_kind) , new_bb) ;
194206 }
195-
196- mappings
197207 }
198208
199209 fn make_mir_coverage_kind ( & self , counter_kind : & BcbCounter ) -> CoverageKind {
0 commit comments