@@ -24,8 +24,7 @@ pub(super) fn extract_refined_covspans(
24
24
from_mir:: mir_to_initial_sorted_coverage_spans ( mir_body, hir_info, basic_coverage_blocks) ;
25
25
for bucket in sorted_span_buckets {
26
26
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 } | {
29
28
// Each span produced by the refiner represents an ordinary code region.
30
29
mappings:: CodeMapping { span, bcb }
31
30
} ) ) ;
@@ -36,24 +35,16 @@ pub(super) fn extract_refined_covspans(
36
35
struct CurrCovspan {
37
36
span : Span ,
38
37
bcb : BasicCoverageBlock ,
39
- is_hole : bool ,
40
38
}
41
39
42
40
impl 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 }
45
43
}
46
44
47
45
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] }
57
48
}
58
49
}
59
50
@@ -64,12 +55,11 @@ struct PrevCovspan {
64
55
/// List of all the original spans from MIR that have been merged into this
65
56
/// span. Mainly used to precisely skip over gaps when truncating a span.
66
57
merged_spans : Vec < Span > ,
67
- is_hole : bool ,
68
58
}
69
59
70
60
impl PrevCovspan {
71
61
fn is_mergeable ( & self , other : & CurrCovspan ) -> bool {
72
- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
62
+ self . bcb == other. bcb
73
63
}
74
64
75
65
fn merge_from ( & mut self , other : & CurrCovspan ) {
@@ -87,27 +77,21 @@ impl PrevCovspan {
87
77
if self . merged_spans . is_empty ( ) { None } else { Some ( self . into_refined ( ) ) }
88
78
}
89
79
90
- fn refined_copy ( & self ) -> RefinedCovspan {
91
- let & Self { span, bcb, merged_spans : _, is_hole } = self ;
92
- RefinedCovspan { span, bcb, is_hole }
93
- }
94
-
95
80
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 }
98
83
}
99
84
}
100
85
101
86
#[ derive( Debug ) ]
102
87
struct RefinedCovspan {
103
88
span : Span ,
104
89
bcb : BasicCoverageBlock ,
105
- is_hole : bool ,
106
90
}
107
91
108
92
impl RefinedCovspan {
109
93
fn is_mergeable ( & self , other : & Self ) -> bool {
110
- self . bcb == other. bcb && ! self . is_hole && !other . is_hole
94
+ self . bcb == other. bcb
111
95
}
112
96
113
97
fn merge_from ( & mut self , other : & Self ) {
@@ -122,8 +106,6 @@ impl RefinedCovspan {
122
106
/// * Remove duplicate source code coverage regions
123
107
/// * Merge spans that represent continuous (both in source code and control flow), non-branching
124
108
/// 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)
127
109
struct SpansRefiner {
128
110
/// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative
129
111
/// dominance between the `BasicCoverageBlock`s of equal `Span`s.
@@ -184,13 +166,6 @@ impl SpansRefiner {
184
166
) ;
185
167
let prev = self . take_prev ( ) . into_refined ( ) ;
186
168
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 ( ) ;
194
169
} else {
195
170
self . cutoff_prev_at_overlapping_curr ( ) ;
196
171
}
@@ -214,9 +189,6 @@ impl SpansRefiner {
214
189
}
215
190
} ) ;
216
191
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 ) ;
220
192
self . refined_spans
221
193
}
222
194
@@ -252,50 +224,17 @@ impl SpansRefiner {
252
224
if let Some ( curr) = self . some_curr . take ( ) {
253
225
self . some_prev = Some ( curr. into_prev ( ) ) ;
254
226
}
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( ) ) ;
267
232
}
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
299
238
}
300
239
}
301
240
0 commit comments