11use rustc_data_structures:: graph:: WithNumNodes ;
2- use rustc_index:: IndexVec ;
2+ use rustc_index:: bit_set :: BitSet ;
33use rustc_middle:: mir;
44use rustc_span:: { BytePos , Span , DUMMY_SP } ;
55
@@ -8,9 +8,15 @@ use crate::coverage::ExtractedHirInfo;
88
99mod from_mir;
1010
11+ #[ derive( Debug ) ]
12+ pub ( super ) struct BcbMapping {
13+ pub ( super ) bcb : BasicCoverageBlock ,
14+ pub ( super ) span : Span ,
15+ }
16+
1117pub ( 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 > ,
1420}
1521
1622impl CoverageSpans {
@@ -23,36 +29,37 @@ impl CoverageSpans {
2329 hir_info : & ExtractedHirInfo ,
2430 basic_coverage_blocks : & CoverageGraph ,
2531 ) -> Option < Self > {
32+ let mut mappings = vec ! [ ] ;
33+
2634 let coverage_spans = CoverageSpansGenerator :: generate_coverage_spans (
2735 mir_body,
2836 hir_info,
2937 basic_coverage_blocks,
3038 ) ;
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+ } ) ) ;
3143
32- if coverage_spans . is_empty ( ) {
44+ if mappings . is_empty ( ) {
3345 return None ;
3446 }
3547
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 ) ;
4052 }
4153
42- Some ( Self { bcb_to_spans } )
54+ Some ( Self { bcb_has_mappings , mappings } )
4355 }
4456
4557 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 )
4759 }
4860
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 ( )
5663 }
5764}
5865
0 commit comments