1
1
use rustc_data_structures:: graph:: WithNumNodes ;
2
- use rustc_index:: IndexVec ;
2
+ use rustc_index:: bit_set :: BitSet ;
3
3
use rustc_middle:: mir;
4
4
use rustc_span:: { BytePos , Span , DUMMY_SP } ;
5
5
@@ -8,9 +8,15 @@ use crate::coverage::ExtractedHirInfo;
8
8
9
9
mod from_mir;
10
10
11
+ #[ derive( Debug ) ]
12
+ pub ( super ) struct BcbMapping {
13
+ pub ( super ) bcb : BasicCoverageBlock ,
14
+ pub ( super ) span : Span ,
15
+ }
16
+
11
17
pub ( super ) struct CoverageSpans {
12
- /// Map from BCBs to their list of coverage spans.
13
- bcb_to_spans : IndexVec < BasicCoverageBlock , Vec < Span > > ,
18
+ bcb_has_mappings : BitSet < BasicCoverageBlock > ,
19
+ mappings : Vec < BcbMapping > ,
14
20
}
15
21
16
22
impl CoverageSpans {
@@ -23,36 +29,37 @@ impl CoverageSpans {
23
29
hir_info : & ExtractedHirInfo ,
24
30
basic_coverage_blocks : & CoverageGraph ,
25
31
) -> Option < Self > {
32
+ let mut mappings = vec ! [ ] ;
33
+
26
34
let coverage_spans = CoverageSpansGenerator :: generate_coverage_spans (
27
35
mir_body,
28
36
hir_info,
29
37
basic_coverage_blocks,
30
38
) ;
39
+ mappings. extend ( coverage_spans. into_iter ( ) . map ( |CoverageSpan { bcb, span, .. } | {
40
+ // Each span produced by the generator represents an ordinary code region.
41
+ BcbMapping { bcb, span }
42
+ } ) ) ;
31
43
32
- if coverage_spans . is_empty ( ) {
44
+ if mappings . is_empty ( ) {
33
45
return None ;
34
46
}
35
47
36
- // Group the coverage spans by BCB, with the BCBs in sorted order .
37
- let mut bcb_to_spans = IndexVec :: from_elem_n ( Vec :: new ( ) , basic_coverage_blocks. num_nodes ( ) ) ;
38
- for CoverageSpan { bcb, span, .. } in coverage_spans {
39
- bcb_to_spans [ bcb ] . push ( span ) ;
48
+ // Identify which BCBs have one or more mappings .
49
+ let mut bcb_has_mappings = BitSet :: new_empty ( basic_coverage_blocks. num_nodes ( ) ) ;
50
+ for & BcbMapping { bcb, span : _ } in & mappings {
51
+ bcb_has_mappings . insert ( bcb ) ;
40
52
}
41
53
42
- Some ( Self { bcb_to_spans } )
54
+ Some ( Self { bcb_has_mappings , mappings } )
43
55
}
44
56
45
57
pub ( super ) fn bcb_has_coverage_spans ( & self , bcb : BasicCoverageBlock ) -> bool {
46
- ! self . bcb_to_spans [ bcb ] . is_empty ( )
58
+ self . bcb_has_mappings . contains ( bcb )
47
59
}
48
60
49
- pub ( super ) fn bcbs_with_coverage_spans (
50
- & self ,
51
- ) -> impl Iterator < Item = ( BasicCoverageBlock , & [ Span ] ) > {
52
- self . bcb_to_spans . iter_enumerated ( ) . filter_map ( |( bcb, spans) | {
53
- // Only yield BCBs that have at least one coverage span.
54
- ( !spans. is_empty ( ) ) . then_some ( ( bcb, spans. as_slice ( ) ) )
55
- } )
61
+ pub ( super ) fn all_bcb_mappings ( & self ) -> impl Iterator < Item = & BcbMapping > {
62
+ self . mappings . iter ( )
56
63
}
57
64
}
58
65
0 commit comments