@@ -10,7 +10,7 @@ use rustc_middle::ty::Instance;
10
10
/// Holds all of the coverage mapping data associated with a function instance,
11
11
/// collected during traversal of `Coverage` statements in the function's MIR.
12
12
#[ derive( Debug ) ]
13
- pub struct FunctionCoverage < ' tcx > {
13
+ pub struct FunctionCoverageCollector < ' tcx > {
14
14
/// Coverage info that was attached to this function by the instrumentor.
15
15
function_coverage_info : & ' tcx FunctionCoverageInfo ,
16
16
is_used : bool ,
@@ -26,7 +26,7 @@ pub struct FunctionCoverage<'tcx> {
26
26
expressions_seen : BitSet < ExpressionId > ,
27
27
}
28
28
29
- impl < ' tcx > FunctionCoverage < ' tcx > {
29
+ impl < ' tcx > FunctionCoverageCollector < ' tcx > {
30
30
/// Creates a new set of coverage data for a used (called) function.
31
31
pub fn new (
32
32
instance : Instance < ' tcx > ,
@@ -76,11 +76,6 @@ impl<'tcx> FunctionCoverage<'tcx> {
76
76
}
77
77
}
78
78
79
- /// Returns true for a used (called) function, and false for an unused function.
80
- pub fn is_used ( & self ) -> bool {
81
- self . is_used
82
- }
83
-
84
79
/// Marks a counter ID as having been seen in a counter-increment statement.
85
80
#[ instrument( level = "debug" , skip( self ) ) ]
86
81
pub ( crate ) fn mark_counter_id_seen ( & mut self , id : CounterId ) {
@@ -165,6 +160,33 @@ impl<'tcx> FunctionCoverage<'tcx> {
165
160
ZeroExpressions ( zero_expressions)
166
161
}
167
162
163
+ pub ( crate ) fn into_finished ( self ) -> FunctionCoverage < ' tcx > {
164
+ FunctionCoverage :: new ( self )
165
+ }
166
+ }
167
+
168
+ pub ( crate ) struct FunctionCoverage < ' tcx > {
169
+ function_coverage_info : & ' tcx FunctionCoverageInfo ,
170
+ is_used : bool ,
171
+
172
+ counters_seen : BitSet < CounterId > ,
173
+ zero_expressions : ZeroExpressions ,
174
+ }
175
+
176
+ impl < ' tcx > FunctionCoverage < ' tcx > {
177
+ fn new ( collector : FunctionCoverageCollector < ' tcx > ) -> Self {
178
+ let zero_expressions = collector. identify_zero_expressions ( ) ;
179
+ let FunctionCoverageCollector { function_coverage_info, is_used, counters_seen, .. } =
180
+ collector;
181
+
182
+ Self { function_coverage_info, is_used, counters_seen, zero_expressions }
183
+ }
184
+
185
+ /// Returns true for a used (called) function, and false for an unused function.
186
+ pub ( crate ) fn is_used ( & self ) -> bool {
187
+ self . is_used
188
+ }
189
+
168
190
/// Return the source hash, generated from the HIR node structure, and used to indicate whether
169
191
/// or not the source code structure changed between different compilations.
170
192
pub fn source_hash ( & self ) -> u64 {
@@ -177,29 +199,27 @@ impl<'tcx> FunctionCoverage<'tcx> {
177
199
pub fn get_expressions_and_counter_regions (
178
200
& self ,
179
201
) -> ( Vec < CounterExpression > , impl Iterator < Item = ( Counter , & CodeRegion ) > ) {
180
- let zero_expressions = self . identify_zero_expressions ( ) ;
181
-
182
- let counter_expressions = self . counter_expressions ( & zero_expressions) ;
202
+ let counter_expressions = self . counter_expressions ( ) ;
183
203
// Expression IDs are indices into `self.expressions`, and on the LLVM
184
204
// side they will be treated as indices into `counter_expressions`, so
185
205
// the two vectors should correspond 1:1.
186
206
assert_eq ! ( self . function_coverage_info. expressions. len( ) , counter_expressions. len( ) ) ;
187
207
188
- let counter_regions = self . counter_regions ( zero_expressions ) ;
208
+ let counter_regions = self . counter_regions ( ) ;
189
209
190
210
( counter_expressions, counter_regions)
191
211
}
192
212
193
213
/// Convert this function's coverage expression data into a form that can be
194
214
/// passed through FFI to LLVM.
195
- fn counter_expressions ( & self , zero_expressions : & ZeroExpressions ) -> Vec < CounterExpression > {
215
+ fn counter_expressions ( & self ) -> Vec < CounterExpression > {
196
216
// We know that LLVM will optimize out any unused expressions before
197
217
// producing the final coverage map, so there's no need to do the same
198
218
// thing on the Rust side unless we're confident we can do much better.
199
219
// (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)
200
220
201
221
let counter_from_operand = |operand : CovTerm | match operand {
202
- CovTerm :: Expression ( id) if zero_expressions. contains ( id) => Counter :: ZERO ,
222
+ CovTerm :: Expression ( id) if self . zero_expressions . contains ( id) => Counter :: ZERO ,
203
223
_ => Counter :: from_term ( operand) ,
204
224
} ;
205
225
@@ -219,18 +239,15 @@ impl<'tcx> FunctionCoverage<'tcx> {
219
239
220
240
/// Converts this function's coverage mappings into an intermediate form
221
241
/// that will be used by `mapgen` when preparing for FFI.
222
- fn counter_regions (
223
- & self ,
224
- zero_expressions : ZeroExpressions ,
225
- ) -> impl Iterator < Item = ( Counter , & CodeRegion ) > {
242
+ fn counter_regions ( & self ) -> impl Iterator < Item = ( Counter , & CodeRegion ) > {
226
243
// Historically, mappings were stored directly in counter/expression
227
244
// statements in MIR, and MIR optimizations would sometimes remove them.
228
245
// That's mostly no longer true, so now we detect cases where that would
229
246
// have happened, and zero out the corresponding mappings here instead.
230
247
let counter_for_term = move |term : CovTerm | {
231
248
let force_to_zero = match term {
232
249
CovTerm :: Counter ( id) => !self . counters_seen . contains ( id) ,
233
- CovTerm :: Expression ( id) => zero_expressions. contains ( id) ,
250
+ CovTerm :: Expression ( id) => self . zero_expressions . contains ( id) ,
234
251
CovTerm :: Zero => false ,
235
252
} ;
236
253
if force_to_zero { Counter :: ZERO } else { Counter :: from_term ( term) }
0 commit comments