Skip to content

Commit c61ec71

Browse files
committed
Simplified body_span and filtered span code
Some code cleanup extracted from future (but unfinished) commit to fix coverage in attr macro functions.
1 parent 0c0d102 commit c61ec71

File tree

3 files changed

+77
-75
lines changed

3 files changed

+77
-75
lines changed

compiler/rustc_mir/src/transform/coverage/mod.rs

+40-28
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
9595

9696
trace!("InstrumentCoverage starting for {:?}", mir_source.def_id());
9797
Instrumentor::new(&self.name(), tcx, mir_body).inject_counters();
98-
trace!("InstrumentCoverage starting for {:?}", mir_source.def_id());
98+
trace!("InstrumentCoverage done for {:?}", mir_source.def_id());
9999
}
100100
}
101101

@@ -116,25 +116,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
116116
let def_id = mir_body.source.def_id();
117117
let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id);
118118

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-
}
119+
let body_span = get_body_span(tcx, hir_body, mir_body);
138120

139121
let source_file = source_map.lookup_source_file(body_span.lo());
140122
let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
@@ -144,6 +126,15 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
144126
Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
145127
None => body_span.shrink_to_lo(),
146128
};
129+
130+
debug!(
131+
"instrumenting {}: {:?}, fn sig span: {:?}, body span: {:?}",
132+
if tcx.is_closure(def_id) { "closure" } else { "function" },
133+
def_id,
134+
fn_sig_span,
135+
body_span
136+
);
137+
147138
let function_source_hash = hash_mir_source(tcx, hir_body);
148139
let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
149140
Self {
@@ -160,19 +151,11 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
160151

161152
fn inject_counters(&'a mut self) {
162153
let tcx = self.tcx;
163-
let source_map = tcx.sess.source_map();
164154
let mir_source = self.mir_body.source;
165155
let def_id = mir_source.def_id();
166156
let fn_sig_span = self.fn_sig_span;
167157
let body_span = self.body_span;
168158

169-
debug!(
170-
"instrumenting {:?}, fn sig span: {}, body span: {}",
171-
def_id,
172-
source_map.span_to_string(fn_sig_span),
173-
source_map.span_to_string(body_span)
174-
);
175-
176159
let mut graphviz_data = debug::GraphvizData::new();
177160
let mut debug_used_expressions = debug::UsedExpressions::new();
178161

@@ -561,6 +544,35 @@ fn fn_sig_and_body<'tcx>(
561544
(hir::map::fn_sig(hir_node), tcx.hir().body(fn_body_id))
562545
}
563546

547+
fn get_body_span<'tcx>(
548+
tcx: TyCtxt<'tcx>,
549+
hir_body: &rustc_hir::Body<'tcx>,
550+
mir_body: &mut mir::Body<'tcx>,
551+
) -> Span {
552+
let mut body_span = hir_body.value.span;
553+
let def_id = mir_body.source.def_id();
554+
555+
if tcx.is_closure(def_id) {
556+
// If the MIR function is a closure, and if the closure body span
557+
// starts from a macro, but it's content is not in that macro, try
558+
// to find a non-macro callsite, and instrument the spans there
559+
// instead.
560+
loop {
561+
let expn_data = body_span.ctxt().outer_expn_data();
562+
if expn_data.is_root() {
563+
break;
564+
}
565+
if let ExpnKind::Macro(..) = expn_data.kind {
566+
body_span = expn_data.call_site;
567+
} else {
568+
break;
569+
}
570+
}
571+
}
572+
573+
body_span
574+
}
575+
564576
fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 {
565577
let mut hcx = tcx.create_no_span_stable_hashing_context();
566578
hash(&mut hcx, &hir_body.value).to_smaller_hash()

compiler/rustc_mir/src/transform/coverage/spans.rs

+35-43
Original file line numberDiff line numberDiff line change
@@ -527,17 +527,25 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
527527
.iter()
528528
.enumerate()
529529
.filter_map(move |(index, statement)| {
530-
filtered_statement_span(statement, self.body_span).map(
531-
|(span, expn_span)| {
532-
CoverageSpan::for_statement(
533-
statement, span, expn_span, bcb, bb, index,
534-
)
535-
},
536-
)
530+
filtered_statement_span(statement).map(|span| {
531+
CoverageSpan::for_statement(
532+
statement,
533+
function_source_span(span, self.body_span),
534+
span,
535+
bcb,
536+
bb,
537+
index,
538+
)
539+
})
537540
})
538-
.chain(filtered_terminator_span(data.terminator(), self.body_span).map(
539-
|(span, expn_span)| CoverageSpan::for_terminator(span, expn_span, bcb, bb),
540-
))
541+
.chain(filtered_terminator_span(data.terminator()).map(|span| {
542+
CoverageSpan::for_terminator(
543+
function_source_span(span, self.body_span),
544+
span,
545+
bcb,
546+
bb,
547+
)
548+
}))
541549
})
542550
.collect()
543551
}
@@ -792,13 +800,9 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
792800
}
793801
}
794802

795-
/// See `function_source_span()` for a description of the two returned spans.
796-
/// If the MIR `Statement` is not contributive to computing coverage spans,
797-
/// returns `None`.
798-
pub(super) fn filtered_statement_span(
799-
statement: &'a Statement<'tcx>,
800-
body_span: Span,
801-
) -> Option<(Span, Span)> {
803+
/// If the MIR `Statement` has a span contributive to computing coverage spans,
804+
/// return it; otherwise return `None`.
805+
pub(super) fn filtered_statement_span(statement: &'a Statement<'tcx>) -> Option<Span> {
802806
match statement.kind {
803807
// These statements have spans that are often outside the scope of the executed source code
804808
// for their parent `BasicBlock`.
@@ -835,18 +839,14 @@ pub(super) fn filtered_statement_span(
835839
| StatementKind::LlvmInlineAsm(_)
836840
| StatementKind::Retag(_, _)
837841
| StatementKind::AscribeUserType(_, _) => {
838-
Some(function_source_span(statement.source_info.span, body_span))
842+
Some(statement.source_info.span)
839843
}
840844
}
841845
}
842846

843-
/// See `function_source_span()` for a description of the two returned spans.
844-
/// If the MIR `Terminator` is not contributive to computing coverage spans,
845-
/// returns `None`.
846-
pub(super) fn filtered_terminator_span(
847-
terminator: &'a Terminator<'tcx>,
848-
body_span: Span,
849-
) -> Option<(Span, Span)> {
847+
/// If the MIR `Terminator` has a span contributive to computing coverage spans,
848+
/// return it; otherwise return `None`.
849+
pub(super) fn filtered_terminator_span(terminator: &'a Terminator<'tcx>) -> Option<Span> {
850850
match terminator.kind {
851851
// These terminators have spans that don't positively contribute to computing a reasonable
852852
// span of actually executed source code. (For example, SwitchInt terminators extracted from
@@ -870,7 +870,7 @@ pub(super) fn filtered_terminator_span(
870870
span = span.with_lo(constant.span.lo());
871871
}
872872
}
873-
Some(function_source_span(span, body_span))
873+
Some(span)
874874
}
875875

876876
// Retain spans from all other terminators
@@ -881,28 +881,20 @@ pub(super) fn filtered_terminator_span(
881881
| TerminatorKind::GeneratorDrop
882882
| TerminatorKind::FalseUnwind { .. }
883883
| TerminatorKind::InlineAsm { .. } => {
884-
Some(function_source_span(terminator.source_info.span, body_span))
884+
Some(terminator.source_info.span)
885885
}
886886
}
887887
}
888888

889-
/// Returns two spans from the given span (the span associated with a
890-
/// `Statement` or `Terminator`):
891-
///
892-
/// 1. An extrapolated span (pre-expansion[^1]) corresponding to a range within
893-
/// the function's body source. This span is guaranteed to be contained
894-
/// within, or equal to, the `body_span`. If the extrapolated span is not
895-
/// contained within the `body_span`, the `body_span` is returned.
896-
/// 2. The actual `span` value from the `Statement`, before expansion.
897-
///
898-
/// Only the first span is used when computing coverage code regions. The second
899-
/// span is useful if additional expansion data is needed (such as to look up
900-
/// the macro name for a composed span within that macro).)
889+
/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range
890+
/// within the function's body source. This span is guaranteed to be contained
891+
/// within, or equal to, the `body_span`. If the extrapolated span is not
892+
/// contained within the `body_span`, the `body_span` is returned.
901893
///
902-
/// [^1]Expansions result from Rust syntax including macros, syntactic
903-
/// sugar, etc.).
894+
/// [^1]Expansions result from Rust syntax including macros, syntactic sugar,
895+
/// etc.).
904896
#[inline]
905-
fn function_source_span(span: Span, body_span: Span) -> (Span, Span) {
897+
pub(super) fn function_source_span(span: Span, body_span: Span) -> Span {
906898
let original_span = original_sp(span, body_span).with_ctxt(body_span.ctxt());
907-
(if body_span.contains(original_span) { original_span } else { body_span }, span)
899+
if body_span.contains(original_span) { original_span } else { body_span }
908900
}

compiler/rustc_mir/src/transform/coverage/tests.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -683,12 +683,10 @@ fn test_make_bcb_counters() {
683683
let mut basic_coverage_blocks = graph::CoverageGraph::from_mir(&mir_body);
684684
let mut coverage_spans = Vec::new();
685685
for (bcb, data) in basic_coverage_blocks.iter_enumerated() {
686-
if let Some((span, expn_span)) =
687-
spans::filtered_terminator_span(data.terminator(&mir_body), body_span)
688-
{
686+
if let Some(span) = spans::filtered_terminator_span(data.terminator(&mir_body)) {
689687
coverage_spans.push(spans::CoverageSpan::for_terminator(
688+
spans::function_source_span(span, body_span),
690689
span,
691-
expn_span,
692690
bcb,
693691
data.last_bb(),
694692
));

0 commit comments

Comments
 (0)