@@ -10,7 +10,7 @@ use rustc_middle::ty::Instance;
1010/// Holds all of the coverage mapping data associated with a function instance,
1111/// collected during traversal of `Coverage` statements in the function's MIR.
1212#[ derive( Debug ) ]
13- pub struct FunctionCoverage < ' tcx > {
13+ pub struct FunctionCoverageCollector < ' tcx > {
1414 /// Coverage info that was attached to this function by the instrumentor.
1515 function_coverage_info : & ' tcx FunctionCoverageInfo ,
1616 is_used : bool ,
@@ -26,7 +26,7 @@ pub struct FunctionCoverage<'tcx> {
2626 expressions_seen : BitSet < ExpressionId > ,
2727}
2828
29- impl < ' tcx > FunctionCoverage < ' tcx > {
29+ impl < ' tcx > FunctionCoverageCollector < ' tcx > {
3030 /// Creates a new set of coverage data for a used (called) function.
3131 pub fn new (
3232 instance : Instance < ' tcx > ,
@@ -76,11 +76,6 @@ impl<'tcx> FunctionCoverage<'tcx> {
7676 }
7777 }
7878
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-
8479 /// Marks a counter ID as having been seen in a counter-increment statement.
8580 #[ instrument( level = "debug" , skip( self ) ) ]
8681 pub ( crate ) fn mark_counter_id_seen ( & mut self , id : CounterId ) {
@@ -165,6 +160,33 @@ impl<'tcx> FunctionCoverage<'tcx> {
165160 ZeroExpressions ( zero_expressions)
166161 }
167162
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+
168190 /// Return the source hash, generated from the HIR node structure, and used to indicate whether
169191 /// or not the source code structure changed between different compilations.
170192 pub fn source_hash ( & self ) -> u64 {
@@ -177,29 +199,27 @@ impl<'tcx> FunctionCoverage<'tcx> {
177199 pub fn get_expressions_and_counter_regions (
178200 & self ,
179201 ) -> ( 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 ( ) ;
183203 // Expression IDs are indices into `self.expressions`, and on the LLVM
184204 // side they will be treated as indices into `counter_expressions`, so
185205 // the two vectors should correspond 1:1.
186206 assert_eq ! ( self . function_coverage_info. expressions. len( ) , counter_expressions. len( ) ) ;
187207
188- let counter_regions = self . counter_regions ( zero_expressions ) ;
208+ let counter_regions = self . counter_regions ( ) ;
189209
190210 ( counter_expressions, counter_regions)
191211 }
192212
193213 /// Convert this function's coverage expression data into a form that can be
194214 /// passed through FFI to LLVM.
195- fn counter_expressions ( & self , zero_expressions : & ZeroExpressions ) -> Vec < CounterExpression > {
215+ fn counter_expressions ( & self ) -> Vec < CounterExpression > {
196216 // We know that LLVM will optimize out any unused expressions before
197217 // producing the final coverage map, so there's no need to do the same
198218 // thing on the Rust side unless we're confident we can do much better.
199219 // (See `CounterExpressionsMinimizer` in `CoverageMappingWriter.cpp`.)
200220
201221 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 ,
203223 _ => Counter :: from_term ( operand) ,
204224 } ;
205225
@@ -219,18 +239,15 @@ impl<'tcx> FunctionCoverage<'tcx> {
219239
220240 /// Converts this function's coverage mappings into an intermediate form
221241 /// 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 ) > {
226243 // Historically, mappings were stored directly in counter/expression
227244 // statements in MIR, and MIR optimizations would sometimes remove them.
228245 // That's mostly no longer true, so now we detect cases where that would
229246 // have happened, and zero out the corresponding mappings here instead.
230247 let counter_for_term = move |term : CovTerm | {
231248 let force_to_zero = match term {
232249 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) ,
234251 CovTerm :: Zero => false ,
235252 } ;
236253 if force_to_zero { Counter :: ZERO } else { Counter :: from_term ( term) }
0 commit comments