1
1
pub use super :: ffi:: * ;
2
2
3
+ use rustc_data_structures:: fx:: FxHashSet ;
3
4
use rustc_index:: vec:: IndexVec ;
4
5
use rustc_middle:: mir:: coverage:: {
5
6
CodeRegion , CounterValueReference , ExpressionOperandId , InjectedExpressionId ,
6
7
InjectedExpressionIndex , MappedExpressionIndex , Op ,
7
8
} ;
8
9
use rustc_middle:: ty:: Instance ;
9
10
use rustc_middle:: ty:: TyCtxt ;
11
+ use rustc_span:: def_id:: DefId ;
10
12
11
13
#[ derive( Clone , Debug ) ]
12
14
pub struct Expression {
@@ -16,6 +18,12 @@ pub struct Expression {
16
18
region : Option < CodeRegion > ,
17
19
}
18
20
21
+ #[ derive( Debug ) ]
22
+ struct Unreachable {
23
+ closure_def_id : Option < DefId > ,
24
+ region : CodeRegion ,
25
+ }
26
+
19
27
/// Collects all of the coverage regions associated with (a) injected counters, (b) counter
20
28
/// expressions (additions or subtraction), and (c) unreachable regions (always counted as zero),
21
29
/// for a given Function. Counters and counter expressions have non-overlapping `id`s because they
@@ -33,7 +41,7 @@ pub struct FunctionCoverage<'tcx> {
33
41
source_hash : u64 ,
34
42
counters : IndexVec < CounterValueReference , Option < CodeRegion > > ,
35
43
expressions : IndexVec < InjectedExpressionIndex , Option < Expression > > ,
36
- unreachable_regions : Vec < CodeRegion > ,
44
+ unreachables : Vec < Unreachable > ,
37
45
}
38
46
39
47
impl < ' tcx > FunctionCoverage < ' tcx > {
@@ -48,7 +56,7 @@ impl<'tcx> FunctionCoverage<'tcx> {
48
56
source_hash : 0 , // will be set with the first `add_counter()`
49
57
counters : IndexVec :: from_elem_n ( None , coverageinfo. num_counters as usize ) ,
50
58
expressions : IndexVec :: from_elem_n ( None , coverageinfo. num_expressions as usize ) ,
51
- unreachable_regions : Vec :: new ( ) ,
59
+ unreachables : Vec :: new ( ) ,
52
60
}
53
61
}
54
62
@@ -100,8 +108,8 @@ impl<'tcx> FunctionCoverage<'tcx> {
100
108
}
101
109
102
110
/// Add a region that will be marked as "unreachable", with a constant "zero counter".
103
- pub fn add_unreachable_region ( & mut self , region : CodeRegion ) {
104
- self . unreachable_regions . push ( region)
111
+ pub fn add_unreachable ( & mut self , closure_def_id : Option < DefId > , region : CodeRegion ) {
112
+ self . unreachables . push ( Unreachable { closure_def_id , region } )
105
113
}
106
114
107
115
/// Return the source hash, generated from the HIR node structure, and used to indicate whether
@@ -113,8 +121,9 @@ impl<'tcx> FunctionCoverage<'tcx> {
113
121
/// Generate an array of CounterExpressions, and an iterator over all `Counter`s and their
114
122
/// associated `Regions` (from which the LLVM-specific `CoverageMapGenerator` will create
115
123
/// `CounterMappingRegion`s.
116
- pub fn get_expressions_and_counter_regions < ' a > (
124
+ pub fn get_expressions_and_counter_regions < ' a , ' b : ' a > (
117
125
& ' a self ,
126
+ covered_def_ids : & ' b FxHashSet < DefId > ,
118
127
) -> ( Vec < CounterExpression > , impl Iterator < Item = ( Counter , & ' a CodeRegion ) > ) {
119
128
assert ! (
120
129
self . source_hash != 0 ,
@@ -124,10 +133,10 @@ impl<'tcx> FunctionCoverage<'tcx> {
124
133
125
134
let counter_regions = self . counter_regions ( ) ;
126
135
let ( counter_expressions, expression_regions) = self . expressions_with_regions ( ) ;
127
- let unreachable_regions = self . unreachable_regions ( ) ;
136
+ let unreachables = self . unreachables ( covered_def_ids ) ;
128
137
129
138
let counter_regions =
130
- counter_regions. chain ( expression_regions. into_iter ( ) . chain ( unreachable_regions ) ) ;
139
+ counter_regions. chain ( expression_regions. into_iter ( ) . chain ( unreachables ) ) ;
131
140
( counter_expressions, counter_regions)
132
141
}
133
142
@@ -250,8 +259,20 @@ impl<'tcx> FunctionCoverage<'tcx> {
250
259
( counter_expressions, expression_regions. into_iter ( ) )
251
260
}
252
261
253
- fn unreachable_regions < ' a > ( & ' a self ) -> impl Iterator < Item = ( Counter , & ' a CodeRegion ) > {
254
- self . unreachable_regions . iter ( ) . map ( |region| ( Counter :: zero ( ) , region) )
262
+ fn unreachables < ' a , ' b : ' a > (
263
+ & ' a self ,
264
+ covered_def_ids : & ' b FxHashSet < DefId > ,
265
+ ) -> impl Iterator < Item = ( Counter , & ' a CodeRegion ) > {
266
+ self . unreachables . iter ( ) . filter_map ( move |unreachable| {
267
+ if let Some ( closure_def_id) = unreachable. closure_def_id {
268
+ if covered_def_ids. contains ( & closure_def_id) {
269
+ debug ! ( "unreachable {:?} IS COVERED AND WILL BE FILTERED" , unreachable) ;
270
+ return None ;
271
+ }
272
+ }
273
+ debug ! ( "unreachable {:?} IS NOT COVERED... ADDING Counter::zero()" , unreachable) ;
274
+ Some ( ( Counter :: zero ( ) , & unreachable. region ) )
275
+ } )
255
276
}
256
277
257
278
fn expression_index ( & self , id_descending_from_max : u32 ) -> InjectedExpressionIndex {
0 commit comments