@@ -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,45 @@ 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 : _, pre_guard_bcb, arm_taken_bcb } ) = arms_rev. next ( )
179
+ else {
180
+ continue ;
181
+ } ;
182
+ debug_assert_eq ! ( pre_guard_bcb, arm_taken_bcb, "last arm should not have a guard" ) ;
183
+ coverage_counters. bcb_counter ( pre_guard_bcb) . expect ( "all relevant BCBs have counters" )
184
+ } ;
185
+
186
+ // All relevant BCBs should have counters, so we can `.unwrap()` them.
187
+ for & BcbBranchArm { span, pre_guard_bcb, arm_taken_bcb } in arms_rev {
188
+ // Number of times the pattern matched.
189
+ let matched_counter = coverage_counters. bcb_counter ( pre_guard_bcb) . unwrap ( ) ;
190
+ // Number of times the pattern matched and the guard succeeded.
191
+ let arm_taken_counter = coverage_counters. bcb_counter ( arm_taken_bcb) . unwrap ( ) ;
192
+ // Total number of times execution logically reached this pattern.
193
+ let reached_counter =
194
+ coverage_counters. make_expression ( rest_counter, Op :: Add , arm_taken_counter) ;
195
+ // Number of times execution reached this pattern, but didn't match it.
196
+ let unmatched_counter =
197
+ coverage_counters. make_expression ( reached_counter, Op :: Subtract , matched_counter) ;
198
+
199
+ let kind = MappingKind :: Branch {
200
+ true_term : matched_counter. as_term ( ) ,
201
+ false_term : unmatched_counter. as_term ( ) ,
202
+ } ;
203
+
204
+ if let Some ( code_region) = make_code_region ( source_map, file_name, span, body_span) {
205
+ mappings. push ( Mapping { kind, code_region } ) ;
206
+ }
207
+
208
+ rest_counter = reached_counter;
209
+ }
210
+ }
181
211
182
212
mappings
183
213
}
0 commit comments