@@ -24,8 +24,7 @@ pub(super) fn extract_refined_covspans(
2424 from_mir:: mir_to_initial_sorted_coverage_spans ( mir_body, hir_info, basic_coverage_blocks) ;
2525 for bucket in sorted_span_buckets {
2626 let refined_spans = SpansRefiner :: refine_sorted_spans ( bucket) ;
27- code_mappings. extend ( refined_spans. into_iter ( ) . map ( |covspan| {
28- let RefinedCovspan { span, bcb, is_hole : _ } = covspan;
27+ code_mappings. extend ( refined_spans. into_iter ( ) . map ( |RefinedCovspan { span, bcb } | {
2928 // Each span produced by the refiner represents an ordinary code region.
3029 mappings:: CodeMapping { span, bcb }
3130 } ) ) ;
@@ -36,24 +35,16 @@ pub(super) fn extract_refined_covspans(
3635struct CurrCovspan {
3736 span : Span ,
3837 bcb : BasicCoverageBlock ,
39- is_hole : bool ,
4038}
4139
4240impl CurrCovspan {
43- fn new ( span : Span , bcb : BasicCoverageBlock , is_hole : bool ) -> Self {
44- Self { span, bcb, is_hole }
41+ fn new ( span : Span , bcb : BasicCoverageBlock ) -> Self {
42+ Self { span, bcb }
4543 }
4644
4745 fn into_prev ( self ) -> PrevCovspan {
48- let Self { span, bcb, is_hole } = self ;
49- PrevCovspan { span, bcb, merged_spans : vec ! [ span] , is_hole }
50- }
51-
52- fn into_refined ( self ) -> RefinedCovspan {
53- // This is only called in cases where `curr` is a hole span that has
54- // been carved out of `prev`.
55- debug_assert ! ( self . is_hole) ;
56- self . into_prev ( ) . into_refined ( )
46+ let Self { span, bcb } = self ;
47+ PrevCovspan { span, bcb, merged_spans : vec ! [ span] }
5748 }
5849}
5950
@@ -64,12 +55,11 @@ struct PrevCovspan {
6455 /// List of all the original spans from MIR that have been merged into this
6556 /// span. Mainly used to precisely skip over gaps when truncating a span.
6657 merged_spans : Vec < Span > ,
67- is_hole : bool ,
6858}
6959
7060impl PrevCovspan {
7161 fn is_mergeable ( & self , other : & CurrCovspan ) -> bool {
72- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
62+ self . bcb == other. bcb
7363 }
7464
7565 fn merge_from ( & mut self , other : & CurrCovspan ) {
@@ -87,27 +77,21 @@ impl PrevCovspan {
8777 if self . merged_spans . is_empty ( ) { None } else { Some ( self . into_refined ( ) ) }
8878 }
8979
90- fn refined_copy ( & self ) -> RefinedCovspan {
91- let & Self { span, bcb, merged_spans : _, is_hole } = self ;
92- RefinedCovspan { span, bcb, is_hole }
93- }
94-
9580 fn into_refined ( self ) -> RefinedCovspan {
96- // Even though we consume self, we can just reuse the copying impl.
97- self . refined_copy ( )
81+ let Self { span , bcb , merged_spans : _ } = self ;
82+ RefinedCovspan { span , bcb }
9883 }
9984}
10085
10186#[ derive( Debug ) ]
10287struct RefinedCovspan {
10388 span : Span ,
10489 bcb : BasicCoverageBlock ,
105- is_hole : bool ,
10690}
10791
10892impl RefinedCovspan {
10993 fn is_mergeable ( & self , other : & Self ) -> bool {
110- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
94+ self . bcb == other. bcb
11195 }
11296
11397 fn merge_from ( & mut self , other : & Self ) {
@@ -122,8 +106,6 @@ impl RefinedCovspan {
122106/// * Remove duplicate source code coverage regions
123107/// * Merge spans that represent continuous (both in source code and control flow), non-branching
124108/// execution
125- /// * Carve out (leave uncovered) any "hole" spans that need to be left blank
126- /// (e.g. closures that will be counted by their own MIR body)
127109struct SpansRefiner {
128110 /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative
129111 /// dominance between the `BasicCoverageBlock`s of equal `Span`s.
@@ -184,13 +166,6 @@ impl SpansRefiner {
184166 ) ;
185167 let prev = self . take_prev ( ) . into_refined ( ) ;
186168 self . refined_spans . push ( prev) ;
187- } else if prev. is_hole {
188- // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the
189- // next iter
190- debug ! ( ?prev, "prev (a hole) overlaps curr, so discarding curr" ) ;
191- self . take_curr ( ) ; // Discards curr.
192- } else if curr. is_hole {
193- self . carve_out_span_for_hole ( ) ;
194169 } else {
195170 self . cutoff_prev_at_overlapping_curr ( ) ;
196171 }
@@ -214,9 +189,6 @@ impl SpansRefiner {
214189 }
215190 } ) ;
216191
217- // Discard hole spans, since their purpose was to carve out chunks from
218- // other spans, but we don't want the holes themselves in the final mappings.
219- self . refined_spans . retain ( |covspan| !covspan. is_hole ) ;
220192 self . refined_spans
221193 }
222194
@@ -252,50 +224,17 @@ impl SpansRefiner {
252224 if let Some ( curr) = self . some_curr . take ( ) {
253225 self . some_prev = Some ( curr. into_prev ( ) ) ;
254226 }
255- while let Some ( curr) = self . sorted_spans_iter . next ( ) {
256- debug ! ( "FOR curr={:?}" , curr) ;
257- if let Some ( prev) = & self . some_prev
258- && prev. span . lo ( ) > curr. span . lo ( )
259- {
260- // Skip curr because prev has already advanced beyond the end of curr.
261- // This can only happen if a prior iteration updated `prev` to skip past
262- // a region of code, such as skipping past a hole.
263- debug ! ( ?prev, "prev.span starts after curr.span, so curr will be dropped" ) ;
264- } else {
265- self . some_curr = Some ( CurrCovspan :: new ( curr. span , curr. bcb , false ) ) ;
266- 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( ) ) ;
267232 }
268- }
269- false
270- }
271-
272- /// If `prev`s span extends left of the hole (`curr`), carve out the hole's span from
273- /// `prev`'s span. Add the portion of the span to the left of the hole; and if the span
274- /// extends to the right of the hole, update `prev` to that portion of the span.
275- fn carve_out_span_for_hole ( & mut self ) {
276- let prev = self . prev ( ) ;
277- let curr = self . curr ( ) ;
278-
279- let left_cutoff = curr. span . lo ( ) ;
280- let right_cutoff = curr. span . hi ( ) ;
281- let has_pre_hole_span = prev. span . lo ( ) < right_cutoff;
282- let has_post_hole_span = prev. span . hi ( ) > right_cutoff;
283-
284- if has_pre_hole_span {
285- let mut pre_hole = prev. refined_copy ( ) ;
286- pre_hole. span = pre_hole. span . with_hi ( left_cutoff) ;
287- debug ! ( ?pre_hole, "prev overlaps a hole; adding pre-hole span" ) ;
288- self . refined_spans . push ( pre_hole) ;
289- }
290-
291- if has_post_hole_span {
292- // Mutate `prev.span` to start after the hole (and discard curr).
293- self . prev_mut ( ) . span = self . prev ( ) . span . with_lo ( right_cutoff) ;
294- debug ! ( prev=?self . prev( ) , "mutated prev to start after the hole" ) ;
295-
296- // Prevent this curr from becoming prev.
297- let hole_covspan = self . take_curr ( ) . into_refined ( ) ;
298- 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
299238 }
300239 }
301240
0 commit comments