@@ -32,7 +32,7 @@ use rustc_middle::mir::{
3232use rustc_middle:: ty:: TyCtxt ;
3333use rustc_span:: def_id:: DefId ;
3434use rustc_span:: source_map:: SourceMap ;
35- use rustc_span:: { CharPos , Pos , SourceFile , Span , Symbol } ;
35+ use rustc_span:: { CharPos , ExpnKind , Pos , SourceFile , Span , Symbol } ;
3636
3737/// A simple error message wrapper for `coverage::Error`s.
3838#[ derive( Debug ) ]
@@ -113,8 +113,29 @@ struct Instrumentor<'a, 'tcx> {
113113impl < ' a , ' tcx > Instrumentor < ' a , ' tcx > {
114114 fn new ( pass_name : & ' a str , tcx : TyCtxt < ' tcx > , mir_body : & ' a mut mir:: Body < ' tcx > ) -> Self {
115115 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+
118139 let source_file = source_map. lookup_source_file ( body_span. lo ( ) ) ;
119140 let fn_sig_span = match some_fn_sig. filter ( |fn_sig| {
120141 fn_sig. span . ctxt ( ) == body_span. ctxt ( )
0 commit comments