@@ -6,7 +6,9 @@ use rustc_middle::mir::{
66} ;
77use rustc_span:: { ExpnKind , MacroKind , Span , Symbol } ;
88
9- use crate :: coverage:: graph:: { BasicCoverageBlock , BasicCoverageBlockData , CoverageGraph } ;
9+ use crate :: coverage:: graph:: {
10+ BasicCoverageBlock , BasicCoverageBlockData , CoverageGraph , START_BCB ,
11+ } ;
1012use crate :: coverage:: spans:: CoverageSpan ;
1113use crate :: coverage:: ExtractedHirInfo ;
1214
@@ -17,7 +19,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
1719) -> Vec < CoverageSpan > {
1820 let & ExtractedHirInfo { is_async_fn, fn_sig_span, body_span, .. } = hir_info;
1921
20- let mut initial_spans = vec ! [ CoverageSpan :: for_fn_sig( fn_sig_span) ] ;
22+ let mut initial_spans = vec ! [ SpanFromMir :: for_fn_sig( fn_sig_span) ] ;
2123
2224 if is_async_fn {
2325 // An async function desugars into a function that returns a future,
@@ -57,7 +59,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
5759 . then_with ( || Ord :: cmp ( & a. is_closure , & b. is_closure ) . reverse ( ) )
5860 } ) ;
5961
60- initial_spans
62+ initial_spans. into_iter ( ) . map ( SpanFromMir :: into_coverage_span ) . collect :: < Vec < _ > > ( )
6163}
6264
6365/// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
@@ -67,7 +69,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
6769///
6870/// (The input spans should be sorted in BCB dominator order, so that the
6971/// retained "first" span is likely to dominate the others.)
70- fn remove_unwanted_macro_spans ( initial_spans : & mut Vec < CoverageSpan > ) {
72+ fn remove_unwanted_macro_spans ( initial_spans : & mut Vec < SpanFromMir > ) {
7173 let mut seen_macro_spans = FxHashSet :: default ( ) ;
7274 initial_spans. retain ( |covspan| {
7375 // Ignore (retain) closure spans and non-macro-expansion spans.
@@ -84,7 +86,7 @@ fn remove_unwanted_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
8486/// function body, split it into two parts. The first part covers just the
8587/// macro name plus `!`, and the second part covers the rest of the macro
8688/// invocation. This seems to give better results for code that uses macros.
87- fn split_visible_macro_spans ( initial_spans : & mut Vec < CoverageSpan > ) {
89+ fn split_visible_macro_spans ( initial_spans : & mut Vec < SpanFromMir > ) {
8890 let mut extra_spans = vec ! [ ] ;
8991
9092 initial_spans. retain ( |covspan| {
@@ -105,8 +107,8 @@ fn split_visible_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
105107 }
106108
107109 assert ! ( !covspan. is_closure) ;
108- extra_spans. push ( CoverageSpan :: new ( before, covspan. visible_macro , covspan. bcb , false ) ) ;
109- extra_spans. push ( CoverageSpan :: new ( after, covspan. visible_macro , covspan. bcb , false ) ) ;
110+ extra_spans. push ( SpanFromMir :: new ( before, covspan. visible_macro , covspan. bcb , false ) ) ;
111+ extra_spans. push ( SpanFromMir :: new ( after, covspan. visible_macro , covspan. bcb , false ) ) ;
110112 false // Discard the original covspan that we just split.
111113 } ) ;
112114
@@ -125,7 +127,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
125127 body_span : Span ,
126128 bcb : BasicCoverageBlock ,
127129 bcb_data : & ' a BasicCoverageBlockData ,
128- ) -> impl Iterator < Item = CoverageSpan > + Captures < ' a > + Captures < ' tcx > {
130+ ) -> impl Iterator < Item = SpanFromMir > + Captures < ' a > + Captures < ' tcx > {
129131 bcb_data. basic_blocks . iter ( ) . flat_map ( move |& bb| {
130132 let data = & mir_body[ bb] ;
131133
@@ -134,15 +136,15 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
134136 let ( span, visible_macro) =
135137 unexpand_into_body_span_with_visible_macro ( expn_span, body_span) ?;
136138
137- Some ( CoverageSpan :: new ( span, visible_macro, bcb, is_closure_or_coroutine ( statement) ) )
139+ Some ( SpanFromMir :: new ( span, visible_macro, bcb, is_closure_or_coroutine ( statement) ) )
138140 } ) ;
139141
140142 let terminator_span = Some ( data. terminator ( ) ) . into_iter ( ) . filter_map ( move |terminator| {
141143 let expn_span = filtered_terminator_span ( terminator) ?;
142144 let ( span, visible_macro) =
143145 unexpand_into_body_span_with_visible_macro ( expn_span, body_span) ?;
144146
145- Some ( CoverageSpan :: new ( span, visible_macro, bcb, false ) )
147+ Some ( SpanFromMir :: new ( span, visible_macro, bcb, false ) )
146148 } ) ;
147149
148150 statement_spans. chain ( terminator_span)
@@ -308,3 +310,38 @@ fn unexpand_into_body_span_with_prev(
308310
309311 Some ( ( curr, prev) )
310312}
313+
314+ #[ derive( Debug ) ]
315+ struct SpanFromMir {
316+ /// A span that has been extracted from MIR and then "un-expanded" back to
317+ /// within the current function's `body_span`. After various intermediate
318+ /// processing steps, this span is emitted as part of the final coverage
319+ /// mappings.
320+ ///
321+ /// With the exception of `fn_sig_span`, this should always be contained
322+ /// within `body_span`.
323+ span : Span ,
324+ visible_macro : Option < Symbol > ,
325+ bcb : BasicCoverageBlock ,
326+ is_closure : bool ,
327+ }
328+
329+ impl SpanFromMir {
330+ fn for_fn_sig ( fn_sig_span : Span ) -> Self {
331+ Self :: new ( fn_sig_span, None , START_BCB , false )
332+ }
333+
334+ fn new (
335+ span : Span ,
336+ visible_macro : Option < Symbol > ,
337+ bcb : BasicCoverageBlock ,
338+ is_closure : bool ,
339+ ) -> Self {
340+ Self { span, visible_macro, bcb, is_closure }
341+ }
342+
343+ fn into_coverage_span ( self ) -> CoverageSpan {
344+ let Self { span, visible_macro : _, bcb, is_closure } = self ;
345+ CoverageSpan :: new ( span, bcb, is_closure)
346+ }
347+ }
0 commit comments