@@ -26,45 +26,6 @@ pub(super) struct CoverageSpans {
2626}
2727
2828impl CoverageSpans {
29- /// Extracts coverage-relevant spans from MIR, and associates them with
30- /// their corresponding BCBs.
31- ///
32- /// Returns `None` if no coverage-relevant spans could be extracted.
33- pub ( super ) fn generate_coverage_spans (
34- mir_body : & mir:: Body < ' _ > ,
35- hir_info : & ExtractedHirInfo ,
36- basic_coverage_blocks : & CoverageGraph ,
37- ) -> Option < Self > {
38- let mut mappings = vec ! [ ] ;
39-
40- let coverage_spans = CoverageSpansGenerator :: generate_coverage_spans (
41- mir_body,
42- hir_info,
43- basic_coverage_blocks,
44- ) ;
45- mappings. extend ( coverage_spans. into_iter ( ) . map ( |CoverageSpan { bcb, span, .. } | {
46- // Each span produced by the generator represents an ordinary code region.
47- BcbMapping { kind : BcbMappingKind :: Code ( bcb) , span }
48- } ) ) ;
49-
50- if mappings. is_empty ( ) {
51- return None ;
52- }
53-
54- // Identify which BCBs have one or more mappings.
55- let mut bcb_has_mappings = BitSet :: new_empty ( basic_coverage_blocks. num_nodes ( ) ) ;
56- let mut insert = |bcb| {
57- bcb_has_mappings. insert ( bcb) ;
58- } ;
59- for & BcbMapping { kind, span : _ } in & mappings {
60- match kind {
61- BcbMappingKind :: Code ( bcb) => insert ( bcb) ,
62- }
63- }
64-
65- Some ( Self { bcb_has_mappings, mappings } )
66- }
67-
6829 pub ( super ) fn bcb_has_coverage_spans ( & self , bcb : BasicCoverageBlock ) -> bool {
6930 self . bcb_has_mappings . contains ( bcb)
7031 }
@@ -74,6 +35,43 @@ impl CoverageSpans {
7435 }
7536}
7637
38+ /// Extracts coverage-relevant spans from MIR, and associates them with
39+ /// their corresponding BCBs.
40+ ///
41+ /// Returns `None` if no coverage-relevant spans could be extracted.
42+ pub ( super ) fn generate_coverage_spans (
43+ mir_body : & mir:: Body < ' _ > ,
44+ hir_info : & ExtractedHirInfo ,
45+ basic_coverage_blocks : & CoverageGraph ,
46+ ) -> Option < CoverageSpans > {
47+ let mut mappings = vec ! [ ] ;
48+
49+ let sorted_spans =
50+ from_mir:: mir_to_initial_sorted_coverage_spans ( mir_body, hir_info, basic_coverage_blocks) ;
51+ let coverage_spans = SpansRefiner :: refine_sorted_spans ( basic_coverage_blocks, sorted_spans) ;
52+ mappings. extend ( coverage_spans. into_iter ( ) . map ( |CoverageSpan { bcb, span, .. } | {
53+ // Each span produced by the generator represents an ordinary code region.
54+ BcbMapping { kind : BcbMappingKind :: Code ( bcb) , span }
55+ } ) ) ;
56+
57+ if mappings. is_empty ( ) {
58+ return None ;
59+ }
60+
61+ // Identify which BCBs have one or more mappings.
62+ let mut bcb_has_mappings = BitSet :: new_empty ( basic_coverage_blocks. num_nodes ( ) ) ;
63+ let mut insert = |bcb| {
64+ bcb_has_mappings. insert ( bcb) ;
65+ } ;
66+ for & BcbMapping { kind, span : _ } in & mappings {
67+ match kind {
68+ BcbMappingKind :: Code ( bcb) => insert ( bcb) ,
69+ }
70+ }
71+
72+ Some ( CoverageSpans { bcb_has_mappings, mappings } )
73+ }
74+
7775/// A BCB is deconstructed into one or more `Span`s. Each `Span` maps to a `CoverageSpan` that
7876/// references the originating BCB and one or more MIR `Statement`s and/or `Terminator`s.
7977/// Initially, the `Span`s come from the `Statement`s and `Terminator`s, but subsequent
@@ -130,7 +128,7 @@ impl CoverageSpan {
130128/// * Merge spans that represent continuous (both in source code and control flow), non-branching
131129/// execution
132130/// * Carve out (leave uncovered) any span that will be counted by another MIR (notably, closures)
133- struct CoverageSpansGenerator < ' a > {
131+ struct SpansRefiner < ' a > {
134132 /// The BasicCoverageBlock Control Flow Graph (BCB CFG).
135133 basic_coverage_blocks : & ' a CoverageGraph ,
136134
@@ -173,40 +171,15 @@ struct CoverageSpansGenerator<'a> {
173171 refined_spans : Vec < CoverageSpan > ,
174172}
175173
176- impl < ' a > CoverageSpansGenerator < ' a > {
177- /// Generate a minimal set of `CoverageSpan`s, each representing a contiguous code region to be
178- /// counted.
179- ///
180- /// The basic steps are:
181- ///
182- /// 1. Extract an initial set of spans from the `Statement`s and `Terminator`s of each
183- /// `BasicCoverageBlockData`.
184- /// 2. Sort the spans by span.lo() (starting position). Spans that start at the same position
185- /// are sorted with longer spans before shorter spans; and equal spans are sorted
186- /// (deterministically) based on "dominator" relationship (if any).
187- /// 3. Traverse the spans in sorted order to identify spans that can be dropped (for instance,
188- /// if another span or spans are already counting the same code region), or should be merged
189- /// into a broader combined span (because it represents a contiguous, non-branching, and
190- /// uninterrupted region of source code).
191- ///
192- /// Closures are exposed in their enclosing functions as `Assign` `Rvalue`s, and since
193- /// closures have their own MIR, their `Span` in their enclosing function should be left
194- /// "uncovered".
195- ///
196- /// Note the resulting vector of `CoverageSpan`s may not be fully sorted (and does not need
197- /// to be).
198- pub ( super ) fn generate_coverage_spans (
199- mir_body : & mir:: Body < ' _ > ,
200- hir_info : & ExtractedHirInfo ,
174+ impl < ' a > SpansRefiner < ' a > {
175+ /// Takes the initial list of (sorted) spans extracted from MIR, and "refines"
176+ /// them by merging compatible adjacent spans, removing redundant spans,
177+ /// and carving holes in spans when they overlap in unwanted ways.
178+ fn refine_sorted_spans (
201179 basic_coverage_blocks : & ' a CoverageGraph ,
180+ sorted_spans : Vec < CoverageSpan > ,
202181 ) -> Vec < CoverageSpan > {
203- let sorted_spans = from_mir:: mir_to_initial_sorted_coverage_spans (
204- mir_body,
205- hir_info,
206- basic_coverage_blocks,
207- ) ;
208-
209- let coverage_spans = Self {
182+ let this = Self {
210183 basic_coverage_blocks,
211184 sorted_spans_iter : sorted_spans. into_iter ( ) ,
212185 some_curr : None ,
@@ -217,7 +190,7 @@ impl<'a> CoverageSpansGenerator<'a> {
217190 refined_spans : Vec :: with_capacity ( basic_coverage_blocks. num_nodes ( ) * 2 ) ,
218191 } ;
219192
220- coverage_spans . to_refined_spans ( )
193+ this . to_refined_spans ( )
221194 }
222195
223196 /// Iterate through the sorted `CoverageSpan`s, and return the refined list of merged and
0 commit comments