@@ -13,6 +13,7 @@ use rustc_middle::ty::TyCtxt;
13
13
use rustc_span:: source_map:: original_sp;
14
14
use rustc_span:: { BytePos , ExpnKind , MacroKind , Span , Symbol } ;
15
15
16
+ use std:: cell:: RefCell ;
16
17
use std:: cmp:: Ordering ;
17
18
18
19
#[ derive( Debug , Copy , Clone ) ]
@@ -68,6 +69,7 @@ impl CoverageStatement {
68
69
pub ( super ) struct CoverageSpan {
69
70
pub span : Span ,
70
71
pub expn_span : Span ,
72
+ pub current_macro_or_none : RefCell < Option < Option < Symbol > > > ,
71
73
pub bcb : BasicCoverageBlock ,
72
74
pub coverage_statements : Vec < CoverageStatement > ,
73
75
pub is_closure : bool ,
@@ -78,6 +80,7 @@ impl CoverageSpan {
78
80
Self {
79
81
span : fn_sig_span,
80
82
expn_span : fn_sig_span,
83
+ current_macro_or_none : Default :: default ( ) ,
81
84
bcb : START_BCB ,
82
85
coverage_statements : vec ! [ ] ,
83
86
is_closure : false ,
@@ -103,6 +106,7 @@ impl CoverageSpan {
103
106
Self {
104
107
span,
105
108
expn_span,
109
+ current_macro_or_none : Default :: default ( ) ,
106
110
bcb,
107
111
coverage_statements : vec ! [ CoverageStatement :: Statement ( bb, span, stmt_index) ] ,
108
112
is_closure,
@@ -118,6 +122,7 @@ impl CoverageSpan {
118
122
Self {
119
123
span,
120
124
expn_span,
125
+ current_macro_or_none : Default :: default ( ) ,
121
126
bcb,
122
127
coverage_statements : vec ! [ CoverageStatement :: Terminator ( bb, span) ] ,
123
128
is_closure : false ,
@@ -174,15 +179,19 @@ impl CoverageSpan {
174
179
. join ( "\n " )
175
180
}
176
181
177
- /// If the span is part of a macro, and the macro is visible (expands directly to the given
178
- /// body_span), returns the macro name symbol.
182
+ /// If the span is part of a macro, returns the macro name symbol.
179
183
pub fn current_macro ( & self ) -> Option < Symbol > {
180
- if let ExpnKind :: Macro ( MacroKind :: Bang , current_macro) =
181
- self . expn_span . ctxt ( ) . outer_expn_data ( ) . kind
182
- {
183
- return Some ( current_macro) ;
184
- }
185
- None
184
+ self . current_macro_or_none
185
+ . borrow_mut ( )
186
+ . get_or_insert_with ( || {
187
+ if let ExpnKind :: Macro ( MacroKind :: Bang , current_macro) =
188
+ self . expn_span . ctxt ( ) . outer_expn_data ( ) . kind
189
+ {
190
+ return Some ( current_macro) ;
191
+ }
192
+ None
193
+ } )
194
+ . map ( |symbol| symbol)
186
195
}
187
196
188
197
/// If the span is part of a macro, and the macro is visible (expands directly to the given
@@ -474,8 +483,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
474
483
self . curr ( ) . expn_span . ctxt ( ) != prev_expn_span. ctxt ( )
475
484
} ) {
476
485
let merged_prefix_len = self . curr_original_span . lo ( ) - self . curr ( ) . span . lo ( ) ;
477
- let after_macro_bang = merged_prefix_len
478
- + BytePos ( visible_macro. to_string ( ) . bytes ( ) . count ( ) as u32 + 1 ) ;
486
+ let after_macro_bang =
487
+ merged_prefix_len + BytePos ( visible_macro. as_str ( ) . bytes ( ) . count ( ) as u32 + 1 ) ;
479
488
let mut macro_name_cov = self . curr ( ) . clone ( ) ;
480
489
self . curr_mut ( ) . span =
481
490
self . curr ( ) . span . with_lo ( self . curr ( ) . span . lo ( ) + after_macro_bang) ;
@@ -766,6 +775,9 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
766
775
}
767
776
}
768
777
778
+ /// See `function_source_span()` for a description of the two returned spans.
779
+ /// If the MIR `Statement` is not contributive to computing coverage spans,
780
+ /// returns `None`.
769
781
pub ( super ) fn filtered_statement_span (
770
782
statement : & ' a Statement < ' tcx > ,
771
783
body_span : Span ,
@@ -811,6 +823,9 @@ pub(super) fn filtered_statement_span(
811
823
}
812
824
}
813
825
826
+ /// See `function_source_span()` for a description of the two returned spans.
827
+ /// If the MIR `Terminator` is not contributive to computing coverage spans,
828
+ /// returns `None`.
814
829
pub ( super ) fn filtered_terminator_span (
815
830
terminator : & ' a Terminator < ' tcx > ,
816
831
body_span : Span ,
@@ -844,8 +859,21 @@ pub(super) fn filtered_terminator_span(
844
859
}
845
860
}
846
861
847
- /// Returns the span within the function source body, and the given span, which will be different
848
- /// if the given span is an expansion (macro, syntactic sugar, etc.).
862
+ /// Returns two spans from the given span (the span associated with a
863
+ /// `Statement` or `Terminator`):
864
+ ///
865
+ /// 1. An extrapolated span (pre-expansion[^1]) corresponding to a range within
866
+ /// the function's body source. This span is guaranteed to be contained
867
+ /// within, or equal to, the `body_span`. If the extrapolated span is not
868
+ /// contained within the `body_span`, the `body_span` is returned.
869
+ /// 2. The actual `span` value from the `Statement`, before expansion.
870
+ ///
871
+ /// Only the first span is used when computing coverage code regions. The second
872
+ /// span is useful if additional expansion data is needed (such as to look up
873
+ /// the macro name for a composed span within that macro).)
874
+ ///
875
+ /// [^1]Expansions result from Rust syntax including macros, syntactic
876
+ /// sugar, etc.).
849
877
#[ inline]
850
878
fn function_source_span ( span : Span , body_span : Span ) -> ( Span , Span ) {
851
879
let original_span = original_sp ( span, body_span) . with_ctxt ( body_span. ctxt ( ) ) ;
0 commit comments