@@ -20,37 +20,31 @@ pub(super) fn extract_refined_covspans(
2020 basic_coverage_blocks : & CoverageGraph ,
2121 code_mappings : & mut impl Extend < mappings:: CodeMapping > ,
2222) {
23- let sorted_spans =
23+ let sorted_span_buckets =
2424 from_mir:: mir_to_initial_sorted_coverage_spans ( mir_body, hir_info, basic_coverage_blocks) ;
25- let coverage_spans = SpansRefiner :: refine_sorted_spans ( sorted_spans) ;
26- code_mappings. extend ( coverage_spans. into_iter ( ) . map ( |RefinedCovspan { bcb, span, .. } | {
27- // Each span produced by the generator represents an ordinary code region.
28- mappings:: CodeMapping { span, bcb }
29- } ) ) ;
25+ for bucket in sorted_span_buckets {
26+ let refined_spans = SpansRefiner :: refine_sorted_spans ( bucket) ;
27+ code_mappings. extend ( refined_spans. into_iter ( ) . map ( |RefinedCovspan { span, bcb } | {
28+ // Each span produced by the refiner represents an ordinary code region.
29+ mappings:: CodeMapping { span, bcb }
30+ } ) ) ;
31+ }
3032}
3133
3234#[ derive( Debug ) ]
3335struct CurrCovspan {
3436 span : Span ,
3537 bcb : BasicCoverageBlock ,
36- is_hole : bool ,
3738}
3839
3940impl CurrCovspan {
40- fn new ( span : Span , bcb : BasicCoverageBlock , is_hole : bool ) -> Self {
41- Self { span, bcb, is_hole }
41+ fn new ( span : Span , bcb : BasicCoverageBlock ) -> Self {
42+ Self { span, bcb }
4243 }
4344
4445 fn into_prev ( self ) -> PrevCovspan {
45- let Self { span, bcb, is_hole } = self ;
46- PrevCovspan { span, bcb, merged_spans : vec ! [ span] , is_hole }
47- }
48-
49- fn into_refined ( self ) -> RefinedCovspan {
50- // This is only called in cases where `curr` is a hole span that has
51- // been carved out of `prev`.
52- debug_assert ! ( self . is_hole) ;
53- self . into_prev ( ) . into_refined ( )
46+ let Self { span, bcb } = self ;
47+ PrevCovspan { span, bcb, merged_spans : vec ! [ span] }
5448 }
5549}
5650
@@ -61,12 +55,11 @@ struct PrevCovspan {
6155 /// List of all the original spans from MIR that have been merged into this
6256 /// span. Mainly used to precisely skip over gaps when truncating a span.
6357 merged_spans : Vec < Span > ,
64- is_hole : bool ,
6558}
6659
6760impl PrevCovspan {
6861 fn is_mergeable ( & self , other : & CurrCovspan ) -> bool {
69- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
62+ self . bcb == other. bcb
7063 }
7164
7265 fn merge_from ( & mut self , other : & CurrCovspan ) {
@@ -84,27 +77,21 @@ impl PrevCovspan {
8477 if self . merged_spans . is_empty ( ) { None } else { Some ( self . into_refined ( ) ) }
8578 }
8679
87- fn refined_copy ( & self ) -> RefinedCovspan {
88- let & Self { span, bcb, merged_spans : _, is_hole } = self ;
89- RefinedCovspan { span, bcb, is_hole }
90- }
91-
9280 fn into_refined ( self ) -> RefinedCovspan {
93- // Even though we consume self, we can just reuse the copying impl.
94- self . refined_copy ( )
81+ let Self { span , bcb , merged_spans : _ } = self ;
82+ RefinedCovspan { span , bcb }
9583 }
9684}
9785
9886#[ derive( Debug ) ]
9987struct RefinedCovspan {
10088 span : Span ,
10189 bcb : BasicCoverageBlock ,
102- is_hole : bool ,
10390}
10491
10592impl RefinedCovspan {
10693 fn is_mergeable ( & self , other : & Self ) -> bool {
107- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
94+ self . bcb == other. bcb
10895 }
10996
11097 fn merge_from ( & mut self , other : & Self ) {
@@ -119,8 +106,6 @@ impl RefinedCovspan {
119106/// * Remove duplicate source code coverage regions
120107/// * Merge spans that represent continuous (both in source code and control flow), non-branching
121108/// execution
122- /// * Carve out (leave uncovered) any "hole" spans that need to be left blank
123- /// (e.g. closures that will be counted by their own MIR body)
124109struct SpansRefiner {
125110 /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative
126111 /// dominance between the `BasicCoverageBlock`s of equal `Span`s.
@@ -181,13 +166,6 @@ impl SpansRefiner {
181166 ) ;
182167 let prev = self . take_prev ( ) . into_refined ( ) ;
183168 self . refined_spans . push ( prev) ;
184- } else if prev. is_hole {
185- // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the
186- // next iter
187- debug ! ( ?prev, "prev (a hole) overlaps curr, so discarding curr" ) ;
188- self . take_curr ( ) ; // Discards curr.
189- } else if curr. is_hole {
190- self . carve_out_span_for_hole ( ) ;
191169 } else {
192170 self . cutoff_prev_at_overlapping_curr ( ) ;
193171 }
@@ -211,9 +189,6 @@ impl SpansRefiner {
211189 }
212190 } ) ;
213191
214- // Discard hole spans, since their purpose was to carve out chunks from
215- // other spans, but we don't want the holes themselves in the final mappings.
216- self . refined_spans . retain ( |covspan| !covspan. is_hole ) ;
217192 self . refined_spans
218193 }
219194
@@ -249,50 +224,17 @@ impl SpansRefiner {
249224 if let Some ( curr) = self . some_curr . take ( ) {
250225 self . some_prev = Some ( curr. into_prev ( ) ) ;
251226 }
252- while let Some ( curr) = self . sorted_spans_iter . next ( ) {
253- debug ! ( "FOR curr={:?}" , curr) ;
254- if let Some ( prev) = & self . some_prev
255- && prev. span . lo ( ) > curr. span . lo ( )
256- {
257- // Skip curr because prev has already advanced beyond the end of curr.
258- // This can only happen if a prior iteration updated `prev` to skip past
259- // a region of code, such as skipping past a hole.
260- debug ! ( ?prev, "prev.span starts after curr.span, so curr will be dropped" ) ;
261- } else {
262- self . some_curr = Some ( CurrCovspan :: new ( curr. span , curr. bcb , curr. is_hole ) ) ;
263- return true ;
227+ if let Some ( SpanFromMir { span, bcb, .. } ) = self . sorted_spans_iter . next ( ) {
228+ // This code only sees sorted spans after hole-carving, so there should
229+ // be no way for `curr` to start before `prev`.
230+ if let Some ( prev) = & self . some_prev {
231+ debug_assert ! ( prev. span. lo( ) <= span. lo( ) ) ;
264232 }
265- }
266- false
267- }
268-
269- /// If `prev`s span extends left of the hole (`curr`), carve out the hole's span from
270- /// `prev`'s span. Add the portion of the span to the left of the hole; and if the span
271- /// extends to the right of the hole, update `prev` to that portion of the span.
272- fn carve_out_span_for_hole ( & mut self ) {
273- let prev = self . prev ( ) ;
274- let curr = self . curr ( ) ;
275-
276- let left_cutoff = curr. span . lo ( ) ;
277- let right_cutoff = curr. span . hi ( ) ;
278- let has_pre_hole_span = prev. span . lo ( ) < right_cutoff;
279- let has_post_hole_span = prev. span . hi ( ) > right_cutoff;
280-
281- if has_pre_hole_span {
282- let mut pre_hole = prev. refined_copy ( ) ;
283- pre_hole. span = pre_hole. span . with_hi ( left_cutoff) ;
284- debug ! ( ?pre_hole, "prev overlaps a hole; adding pre-hole span" ) ;
285- self . refined_spans . push ( pre_hole) ;
286- }
287-
288- if has_post_hole_span {
289- // Mutate `prev.span` to start after the hole (and discard curr).
290- self . prev_mut ( ) . span = self . prev ( ) . span . with_lo ( right_cutoff) ;
291- debug ! ( prev=?self . prev( ) , "mutated prev to start after the hole" ) ;
292-
293- // Prevent this curr from becoming prev.
294- let hole_covspan = self . take_curr ( ) . into_refined ( ) ;
295- self . refined_spans . push ( hole_covspan) ; // since self.prev() was already updated
233+ self . some_curr = Some ( CurrCovspan :: new ( span, bcb) ) ;
234+ debug ! ( ?self . some_prev, ?self . some_curr, "next_coverage_span" ) ;
235+ true
236+ } else {
237+ false
296238 }
297239 }
298240
0 commit comments