@@ -32,7 +32,7 @@ use rustc_middle::mir::{
32
32
use rustc_middle:: ty:: TyCtxt ;
33
33
use rustc_span:: def_id:: DefId ;
34
34
use rustc_span:: source_map:: SourceMap ;
35
- use rustc_span:: { CharPos , Pos , SourceFile , Span , Symbol } ;
35
+ use rustc_span:: { CharPos , ExpnKind , Pos , SourceFile , Span , Symbol } ;
36
36
37
37
/// A simple error message wrapper for `coverage::Error`s.
38
38
#[ derive( Debug ) ]
@@ -113,8 +113,29 @@ struct Instrumentor<'a, 'tcx> {
113
113
impl < ' a , ' tcx > Instrumentor < ' a , ' tcx > {
114
114
fn new ( pass_name : & ' a str , tcx : TyCtxt < ' tcx > , mir_body : & ' a mut mir:: Body < ' tcx > ) -> Self {
115
115
let source_map = tcx. sess . source_map ( ) ;
116
- let ( some_fn_sig, hir_body) = fn_sig_and_body ( tcx, mir_body. source . def_id ( ) ) ;
117
- let body_span = hir_body. value . span ;
116
+ let def_id = mir_body. source . def_id ( ) ;
117
+ let ( some_fn_sig, hir_body) = fn_sig_and_body ( tcx, def_id) ;
118
+
119
+ let mut body_span = hir_body. value . span ;
120
+
121
+ if tcx. is_closure ( def_id) {
122
+ // If the MIR function is a closure, and if the closure body span
123
+ // starts from a macro, but it's content is not in that macro, try
124
+ // to find a non-macro callsite, and instrument the spans there
125
+ // instead.
126
+ loop {
127
+ let expn_data = body_span. ctxt ( ) . outer_expn_data ( ) ;
128
+ if expn_data. is_root ( ) {
129
+ break ;
130
+ }
131
+ if let ExpnKind :: Macro ( ..) = expn_data. kind {
132
+ body_span = expn_data. call_site ;
133
+ } else {
134
+ break ;
135
+ }
136
+ }
137
+ }
138
+
118
139
let source_file = source_map. lookup_source_file ( body_span. lo ( ) ) ;
119
140
let fn_sig_span = match some_fn_sig. filter ( |fn_sig| {
120
141
fn_sig. span . ctxt ( ) == body_span. ctxt ( )
0 commit comments