Skip to content

Commit 87d50d2

Browse files
committed
coverage: Hoist special handling of async function spans
This sidesteps the normal span refinement code in cases where we know that we are only dealing with the special signature span that represents having called an async function.
1 parent 008724b commit 87d50d2

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

compiler/rustc_mir_transform/src/coverage/spans.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_index::bit_set::BitSet;
33
use rustc_middle::mir;
44
use rustc_span::{BytePos, Span, DUMMY_SP};
55

6-
use super::graph::{BasicCoverageBlock, CoverageGraph};
6+
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
77
use crate::coverage::ExtractedHirInfo;
88

99
mod from_mir;
@@ -46,13 +46,25 @@ pub(super) fn generate_coverage_spans(
4646
) -> Option<CoverageSpans> {
4747
let mut mappings = vec![];
4848

49-
let sorted_spans =
50-
from_mir::mir_to_initial_sorted_coverage_spans(mir_body, hir_info, basic_coverage_blocks);
51-
let coverage_spans = SpansRefiner::refine_sorted_spans(basic_coverage_blocks, sorted_spans);
52-
mappings.extend(coverage_spans.into_iter().map(|CoverageSpan { bcb, span, .. }| {
53-
// Each span produced by the generator represents an ordinary code region.
54-
BcbMapping { kind: BcbMappingKind::Code(bcb), span }
55-
}));
49+
if hir_info.is_async_fn {
50+
// An async function desugars into a function that returns a future,
51+
// with the user code wrapped in a closure. Any spans in the desugared
52+
// outer function will be unhelpful, so just keep the signature span
53+
// and ignore all of the spans in the MIR body.
54+
let span = hir_info.fn_sig_span;
55+
mappings.push(BcbMapping { kind: BcbMappingKind::Code(START_BCB), span });
56+
} else {
57+
let sorted_spans = from_mir::mir_to_initial_sorted_coverage_spans(
58+
mir_body,
59+
hir_info,
60+
basic_coverage_blocks,
61+
);
62+
let coverage_spans = SpansRefiner::refine_sorted_spans(basic_coverage_blocks, sorted_spans);
63+
mappings.extend(coverage_spans.into_iter().map(|CoverageSpan { bcb, span, .. }| {
64+
// Each span produced by the generator represents an ordinary code region.
65+
BcbMapping { kind: BcbMappingKind::Code(bcb), span }
66+
}));
67+
}
5668

5769
if mappings.is_empty() {
5870
return None;

compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs

+10-18
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,17 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
2323
hir_info: &ExtractedHirInfo,
2424
basic_coverage_blocks: &CoverageGraph,
2525
) -> Vec<CoverageSpan> {
26-
let &ExtractedHirInfo { is_async_fn, fn_sig_span, body_span, .. } = hir_info;
27-
28-
let mut initial_spans = vec![SpanFromMir::for_fn_sig(fn_sig_span)];
29-
30-
if is_async_fn {
31-
// An async function desugars into a function that returns a future,
32-
// with the user code wrapped in a closure. Any spans in the desugared
33-
// outer function will be unhelpful, so just keep the signature span
34-
// and ignore all of the spans in the MIR body.
35-
} else {
36-
for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() {
37-
initial_spans.extend(bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data));
38-
}
26+
let &ExtractedHirInfo { fn_sig_span, body_span, .. } = hir_info;
3927

40-
// If no spans were extracted from the body, discard the signature span.
41-
// FIXME: This preserves existing behavior; consider getting rid of it.
42-
if initial_spans.len() == 1 {
43-
initial_spans.clear();
44-
}
28+
let mut initial_spans = vec![];
29+
30+
for (bcb, bcb_data) in basic_coverage_blocks.iter_enumerated() {
31+
initial_spans.extend(bcb_to_initial_coverage_spans(mir_body, body_span, bcb, bcb_data));
32+
}
33+
34+
// Only add the signature span if we found at least one span in the body.
35+
if !initial_spans.is_empty() {
36+
initial_spans.push(SpanFromMir::for_fn_sig(fn_sig_span));
4537
}
4638

4739
initial_spans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb));

0 commit comments

Comments
 (0)