@@ -9,7 +9,7 @@ mod tests;
9
9
10
10
use self :: counters:: { CounterIncrementSite , CoverageCounters } ;
11
11
use self :: graph:: { BasicCoverageBlock , CoverageGraph } ;
12
- use self :: spans:: { BcbBranchPair , BcbMapping , BcbMappingKind , CoverageSpans } ;
12
+ use self :: spans:: { BcbBranchArm , BcbMapping , BcbMappingKind , CoverageSpans } ;
13
13
14
14
use crate :: MirPass ;
15
15
@@ -83,10 +83,10 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
83
83
// and all `Expression` dependencies (operands) are also generated, for any other
84
84
// `BasicCoverageBlock`s not already associated with a coverage span.
85
85
let bcb_has_coverage_spans = |bcb| coverage_spans. bcb_has_coverage_spans ( bcb) ;
86
- let coverage_counters =
86
+ let mut coverage_counters =
87
87
CoverageCounters :: make_bcb_counters ( & basic_coverage_blocks, bcb_has_coverage_spans) ;
88
88
89
- let mappings = create_mappings ( tcx, & hir_info, & coverage_spans, & coverage_counters) ;
89
+ let mappings = create_mappings ( tcx, & hir_info, & coverage_spans, & mut coverage_counters) ;
90
90
if mappings. is_empty ( ) {
91
91
// No spans could be converted into valid mappings, so skip this function.
92
92
debug ! ( "no spans could be converted into valid mappings; skipping" ) ;
@@ -120,7 +120,7 @@ fn create_mappings<'tcx>(
120
120
tcx : TyCtxt < ' tcx > ,
121
121
hir_info : & ExtractedHirInfo ,
122
122
coverage_spans : & CoverageSpans ,
123
- coverage_counters : & CoverageCounters ,
123
+ coverage_counters : & mut CoverageCounters ,
124
124
) -> Vec < Mapping > {
125
125
let source_map = tcx. sess . source_map ( ) ;
126
126
let body_span = hir_info. body_span ;
@@ -169,15 +169,32 @@ fn create_mappings<'tcx>(
169
169
} ,
170
170
) ) ;
171
171
172
- mappings. extend ( coverage_spans. branch_pairs . iter ( ) . filter_map (
173
- |& BcbBranchPair { span, true_bcb, false_bcb } | {
174
- let true_term = term_for_bcb ( true_bcb) ;
175
- let false_term = term_for_bcb ( false_bcb) ;
176
- let kind = MappingKind :: Branch { true_term, false_term } ;
177
- let code_region = make_code_region ( source_map, file_name, span, body_span) ?;
178
- Some ( Mapping { kind, code_region } )
179
- } ,
180
- ) ) ;
172
+ for arm_list in & coverage_spans. branch_arm_lists {
173
+ let mut arms_rev = arm_list. iter ( ) . rev ( ) ;
174
+
175
+ let mut rest_counter = {
176
+ // The last arm's span is ignored, because its BCB is only used as the
177
+ // false branch of the second-last arm; it's not a branch of its own.
178
+ let Some ( & BcbBranchArm { span : _, bcb } ) = arms_rev. next ( ) else { continue } ;
179
+ coverage_counters. bcb_counter ( bcb) . expect ( "all relevant BCBs have counters" )
180
+ } ;
181
+
182
+ for & BcbBranchArm { span, bcb } in arms_rev {
183
+ let true_counter =
184
+ coverage_counters. bcb_counter ( bcb) . expect ( "all relevant BCBs have counters" ) ;
185
+ let kind = MappingKind :: Branch {
186
+ true_term : true_counter. as_term ( ) ,
187
+ false_term : rest_counter. as_term ( ) ,
188
+ } ;
189
+
190
+ if let Some ( code_region) = make_code_region ( source_map, file_name, span, body_span) {
191
+ mappings. push ( Mapping { kind, code_region } ) ;
192
+ }
193
+
194
+ // FIXME: Avoid creating an unused expression on the last iteration.
195
+ rest_counter = coverage_counters. make_expression ( true_counter, Op :: Add , rest_counter) ;
196
+ }
197
+ }
181
198
182
199
mappings
183
200
}
0 commit comments