Skip to content

Commit cc298cd

Browse files
committed
coverage: Split out SpanFromMir from CoverageSpan
This draws a clear distinction between the fields/methods that are needed by initial span extraction and preprocessing, and those that are needed by the main "refinement" loop.
1 parent 84c4b16 commit cc298cd

File tree

2 files changed

+51
-24
lines changed

2 files changed

+51
-24
lines changed

compiler/rustc_mir_transform/src/coverage/spans.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use rustc_data_structures::graph::WithNumNodes;
22
use rustc_index::IndexVec;
33
use rustc_middle::mir;
4-
use rustc_span::{BytePos, Span, Symbol, DUMMY_SP};
4+
use rustc_span::{BytePos, Span, DUMMY_SP};
55

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

99
mod from_mir;
@@ -64,7 +64,6 @@ impl CoverageSpans {
6464
#[derive(Debug, Clone)]
6565
struct CoverageSpan {
6666
pub span: Span,
67-
pub visible_macro: Option<Symbol>,
6867
pub bcb: BasicCoverageBlock,
6968
/// List of all the original spans from MIR that have been merged into this
7069
/// span. Mainly used to precisely skip over gaps when truncating a span.
@@ -73,17 +72,8 @@ struct CoverageSpan {
7372
}
7473

7574
impl CoverageSpan {
76-
pub fn for_fn_sig(fn_sig_span: Span) -> Self {
77-
Self::new(fn_sig_span, None, START_BCB, false)
78-
}
79-
80-
pub(super) fn new(
81-
span: Span,
82-
visible_macro: Option<Symbol>,
83-
bcb: BasicCoverageBlock,
84-
is_closure: bool,
85-
) -> Self {
86-
Self { span, visible_macro, bcb, merged_spans: vec![span], is_closure }
75+
fn new(span: Span, bcb: BasicCoverageBlock, is_closure: bool) -> Self {
76+
Self { span, bcb, merged_spans: vec![span], is_closure }
8777
}
8878

8979
pub fn merge_from(&mut self, other: &Self) {

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

+47-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use rustc_middle::mir::{
66
};
77
use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
88

9-
use crate::coverage::graph::{BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph};
9+
use crate::coverage::graph::{
10+
BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
11+
};
1012
use crate::coverage::spans::CoverageSpan;
1113
use crate::coverage::ExtractedHirInfo;
1214

@@ -17,7 +19,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
1719
) -> Vec<CoverageSpan> {
1820
let &ExtractedHirInfo { is_async_fn, fn_sig_span, body_span, .. } = hir_info;
1921

20-
let mut initial_spans = vec![CoverageSpan::for_fn_sig(fn_sig_span)];
22+
let mut initial_spans = vec![SpanFromMir::for_fn_sig(fn_sig_span)];
2123

2224
if is_async_fn {
2325
// An async function desugars into a function that returns a future,
@@ -57,7 +59,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
5759
.then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse())
5860
});
5961

60-
initial_spans
62+
initial_spans.into_iter().map(SpanFromMir::into_coverage_span).collect::<Vec<_>>()
6163
}
6264

6365
/// Macros that expand into branches (e.g. `assert!`, `trace!`) tend to generate
@@ -67,7 +69,7 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
6769
///
6870
/// (The input spans should be sorted in BCB dominator order, so that the
6971
/// retained "first" span is likely to dominate the others.)
70-
fn remove_unwanted_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
72+
fn remove_unwanted_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
7173
let mut seen_macro_spans = FxHashSet::default();
7274
initial_spans.retain(|covspan| {
7375
// Ignore (retain) closure spans and non-macro-expansion spans.
@@ -84,7 +86,7 @@ fn remove_unwanted_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
8486
/// function body, split it into two parts. The first part covers just the
8587
/// macro name plus `!`, and the second part covers the rest of the macro
8688
/// invocation. This seems to give better results for code that uses macros.
87-
fn split_visible_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
89+
fn split_visible_macro_spans(initial_spans: &mut Vec<SpanFromMir>) {
8890
let mut extra_spans = vec![];
8991

9092
initial_spans.retain(|covspan| {
@@ -105,8 +107,8 @@ fn split_visible_macro_spans(initial_spans: &mut Vec<CoverageSpan>) {
105107
}
106108

107109
assert!(!covspan.is_closure);
108-
extra_spans.push(CoverageSpan::new(before, covspan.visible_macro, covspan.bcb, false));
109-
extra_spans.push(CoverageSpan::new(after, covspan.visible_macro, covspan.bcb, false));
110+
extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb, false));
111+
extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb, false));
110112
false // Discard the original covspan that we just split.
111113
});
112114

@@ -125,7 +127,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
125127
body_span: Span,
126128
bcb: BasicCoverageBlock,
127129
bcb_data: &'a BasicCoverageBlockData,
128-
) -> impl Iterator<Item = CoverageSpan> + Captures<'a> + Captures<'tcx> {
130+
) -> impl Iterator<Item = SpanFromMir> + Captures<'a> + Captures<'tcx> {
129131
bcb_data.basic_blocks.iter().flat_map(move |&bb| {
130132
let data = &mir_body[bb];
131133

@@ -134,15 +136,15 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
134136
let (span, visible_macro) =
135137
unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
136138

137-
Some(CoverageSpan::new(span, visible_macro, bcb, is_closure(statement)))
139+
Some(SpanFromMir::new(span, visible_macro, bcb, is_closure(statement)))
138140
});
139141

140142
let terminator_span = Some(data.terminator()).into_iter().filter_map(move |terminator| {
141143
let expn_span = filtered_terminator_span(terminator)?;
142144
let (span, visible_macro) =
143145
unexpand_into_body_span_with_visible_macro(expn_span, body_span)?;
144146

145-
Some(CoverageSpan::new(span, visible_macro, bcb, false))
147+
Some(SpanFromMir::new(span, visible_macro, bcb, false))
146148
});
147149

148150
statement_spans.chain(terminator_span)
@@ -300,3 +302,38 @@ fn unexpand_into_body_span_with_prev(
300302

301303
Some((curr, prev))
302304
}
305+
306+
#[derive(Debug)]
307+
struct SpanFromMir {
308+
/// A span that has been extracted from MIR and then "un-expanded" back to
309+
/// within the current function's `body_span`. After various intermediate
310+
/// processing steps, this span is emitted as part of the final coverage
311+
/// mappings.
312+
///
313+
/// With the exception of `fn_sig_span`, this should always be contained
314+
/// within `body_span`.
315+
span: Span,
316+
visible_macro: Option<Symbol>,
317+
bcb: BasicCoverageBlock,
318+
is_closure: bool,
319+
}
320+
321+
impl SpanFromMir {
322+
fn for_fn_sig(fn_sig_span: Span) -> Self {
323+
Self::new(fn_sig_span, None, START_BCB, false)
324+
}
325+
326+
fn new(
327+
span: Span,
328+
visible_macro: Option<Symbol>,
329+
bcb: BasicCoverageBlock,
330+
is_closure: bool,
331+
) -> Self {
332+
Self { span, visible_macro, bcb, is_closure }
333+
}
334+
335+
fn into_coverage_span(self) -> CoverageSpan {
336+
let Self { span, visible_macro: _, bcb, is_closure } = self;
337+
CoverageSpan::new(span, bcb, is_closure)
338+
}
339+
}

0 commit comments

Comments
 (0)