@@ -11,7 +11,7 @@ use rustc_middle::mir::{
1111use rustc_middle:: ty:: TyCtxt ;
1212
1313use rustc_span:: source_map:: original_sp;
14- use rustc_span:: { BytePos , Span } ;
14+ use rustc_span:: { BytePos , ExpnKind , MacroKind , Span } ;
1515
1616use std:: cmp:: Ordering ;
1717
@@ -67,19 +67,30 @@ impl CoverageStatement {
6767#[ derive( Debug , Clone ) ]
6868pub ( super ) struct CoverageSpan {
6969 pub span : Span ,
70+ pub is_macro_expansion : bool ,
7071 pub bcb : BasicCoverageBlock ,
7172 pub coverage_statements : Vec < CoverageStatement > ,
7273 pub is_closure : bool ,
7374}
7475
7576impl CoverageSpan {
7677 pub fn for_fn_sig ( fn_sig_span : Span ) -> Self {
77- Self { span : fn_sig_span, bcb : START_BCB , coverage_statements : vec ! [ ] , is_closure : false }
78+ // Whether the function signature is from a macro or not, it should not be treated like
79+ // macro-expanded statements and terminators.
80+ let is_macro_expansion = false ;
81+ Self {
82+ span : fn_sig_span,
83+ is_macro_expansion,
84+ bcb : START_BCB ,
85+ coverage_statements : vec ! [ ] ,
86+ is_closure : false ,
87+ }
7888 }
7989
8090 pub fn for_statement (
8191 statement : & Statement < ' tcx > ,
8292 span : Span ,
93+ is_macro_expansion : bool ,
8394 bcb : BasicCoverageBlock ,
8495 bb : BasicBlock ,
8596 stmt_index : usize ,
@@ -94,15 +105,22 @@ impl CoverageSpan {
94105
95106 Self {
96107 span,
108+ is_macro_expansion,
97109 bcb,
98110 coverage_statements : vec ! [ CoverageStatement :: Statement ( bb, span, stmt_index) ] ,
99111 is_closure,
100112 }
101113 }
102114
103- pub fn for_terminator ( span : Span , bcb : BasicCoverageBlock , bb : BasicBlock ) -> Self {
115+ pub fn for_terminator (
116+ span : Span ,
117+ is_macro_expansion : bool ,
118+ bcb : BasicCoverageBlock ,
119+ bb : BasicBlock ,
120+ ) -> Self {
104121 Self {
105122 span,
123+ is_macro_expansion,
106124 bcb,
107125 coverage_statements : vec ! [ CoverageStatement :: Terminator ( bb, span) ] ,
108126 is_closure : false ,
@@ -344,7 +362,27 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
344362 } else if self . prev_original_span == self . curr ( ) . span {
345363 // Note that this compares the new span to `prev_original_span`, which may not
346364 // be the full `prev.span` (if merged during the previous iteration).
347- self . hold_pending_dups_unless_dominated ( ) ;
365+ if self . prev ( ) . is_macro_expansion && self . curr ( ) . is_macro_expansion {
366+ // Macros that expand to include branching (such as
367+ // `assert_eq!()`, `assert_ne!()`, `info!()`, `debug!()`, or
368+ // `trace!()) typically generate callee spans with identical
369+ // ranges (typically the full span of the macro) for all
370+ // `BasicBlocks`. This makes it impossible to distinguish
371+ // the condition (`if val1 != val2`) from the optional
372+ // branched statements (such as the call to `panic!()` on
373+ // assert failure). In this case it is better (or less
374+ // worse) to drop the optional branch bcbs and keep the
375+ // non-conditional statements, to count when reached.
376+ debug ! (
377+ " curr and prev are part of a macro expansion, and curr has the same span \
378+ as prev, but is in a different bcb. Drop curr and keep prev for next iter. \
379+ prev={:?}",
380+ self . prev( )
381+ ) ;
382+ self . take_curr ( ) ;
383+ } else {
384+ self . hold_pending_dups_unless_dominated ( ) ;
385+ }
348386 } else {
349387 self . cutoff_prev_at_overlapping_curr ( ) ;
350388 }
@@ -401,14 +439,24 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
401439 . iter ( )
402440 . enumerate ( )
403441 . filter_map ( move |( index, statement) | {
404- filtered_statement_span ( statement, self . body_span ) . map ( |span| {
405- CoverageSpan :: for_statement ( statement, span, bcb, bb, index)
406- } )
442+ filtered_statement_span ( statement, self . body_span ) . map (
443+ |( span, is_macro_expansion) | {
444+ CoverageSpan :: for_statement (
445+ statement,
446+ span,
447+ is_macro_expansion,
448+ bcb,
449+ bb,
450+ index,
451+ )
452+ } ,
453+ )
407454 } )
408- . chain (
409- filtered_terminator_span ( data. terminator ( ) , self . body_span )
410- . map ( |span| CoverageSpan :: for_terminator ( span, bcb, bb) ) ,
411- )
455+ . chain ( filtered_terminator_span ( data. terminator ( ) , self . body_span ) . map (
456+ |( span, is_macro_expansion) | {
457+ CoverageSpan :: for_terminator ( span, is_macro_expansion, bcb, bb)
458+ } ,
459+ ) )
412460 } )
413461 . collect ( )
414462 }
@@ -656,7 +704,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
656704pub ( super ) fn filtered_statement_span (
657705 statement : & ' a Statement < ' tcx > ,
658706 body_span : Span ,
659- ) -> Option < Span > {
707+ ) -> Option < ( Span , bool ) > {
660708 match statement. kind {
661709 // These statements have spans that are often outside the scope of the executed source code
662710 // for their parent `BasicBlock`.
@@ -701,7 +749,7 @@ pub(super) fn filtered_statement_span(
701749pub ( super ) fn filtered_terminator_span (
702750 terminator : & ' a Terminator < ' tcx > ,
703751 body_span : Span ,
704- ) -> Option < Span > {
752+ ) -> Option < ( Span , bool ) > {
705753 match terminator. kind {
706754 // These terminators have spans that don't positively contribute to computing a reasonable
707755 // span of actually executed source code. (For example, SwitchInt terminators extracted from
@@ -732,7 +780,13 @@ pub(super) fn filtered_terminator_span(
732780}
733781
734782#[ inline]
735- fn function_source_span ( span : Span , body_span : Span ) -> Span {
783+ fn function_source_span ( span : Span , body_span : Span ) -> ( Span , bool ) {
784+ let is_macro_expansion = span. ctxt ( ) != body_span. ctxt ( )
785+ && if let ExpnKind :: Macro ( MacroKind :: Bang , _) = span. ctxt ( ) . outer_expn_data ( ) . kind {
786+ true
787+ } else {
788+ false
789+ } ;
736790 let span = original_sp ( span, body_span) . with_ctxt ( body_span. ctxt ( ) ) ;
737- if body_span. contains ( span) { span } else { body_span }
791+ ( if body_span. contains ( span) { span } else { body_span } , is_macro_expansion )
738792}
0 commit comments