coverage: Move span unexpansion into its own submodule
This commit is contained in:
parent
716752ebe6
commit
617de8cfb5
5 changed files with 59 additions and 62 deletions
|
@ -9,9 +9,8 @@ use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
|
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, START_BCB};
|
||||||
use crate::coverage::spans::{
|
use crate::coverage::spans::extract_refined_covspans;
|
||||||
extract_refined_covspans, unexpand_into_body_span_with_visible_macro,
|
use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro;
|
||||||
};
|
|
||||||
use crate::coverage::ExtractedHirInfo;
|
use crate::coverage::ExtractedHirInfo;
|
||||||
|
|
||||||
/// Associates an ordinary executable code span with its corresponding BCB.
|
/// Associates an ordinary executable code span with its corresponding BCB.
|
||||||
|
|
|
@ -6,6 +6,7 @@ mod mappings;
|
||||||
mod spans;
|
mod spans;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
mod unexpand;
|
||||||
|
|
||||||
use rustc_middle::mir::coverage::{
|
use rustc_middle::mir::coverage::{
|
||||||
CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind,
|
CodeRegion, CoverageKind, DecisionInfo, FunctionCoverageInfo, Mapping, MappingKind,
|
||||||
|
|
|
@ -14,11 +14,6 @@ use crate::coverage::ExtractedHirInfo;
|
||||||
|
|
||||||
mod from_mir;
|
mod from_mir;
|
||||||
|
|
||||||
// FIXME(#124545) It's awkward that we have to re-export this, because it's an
|
|
||||||
// internal detail of `from_mir` that is also needed when handling branch and
|
|
||||||
// MC/DC spans. Ideally we would find a more natural home for it.
|
|
||||||
pub(super) use from_mir::unexpand_into_body_span_with_visible_macro;
|
|
||||||
|
|
||||||
pub(super) fn extract_refined_covspans(
|
pub(super) fn extract_refined_covspans(
|
||||||
mir_body: &mir::Body<'_>,
|
mir_body: &mir::Body<'_>,
|
||||||
hir_info: &ExtractedHirInfo,
|
hir_info: &ExtractedHirInfo,
|
||||||
|
|
|
@ -4,12 +4,13 @@ use rustc_middle::mir::{
|
||||||
self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
|
self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator,
|
||||||
TerminatorKind,
|
TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
use crate::coverage::graph::{
|
use crate::coverage::graph::{
|
||||||
BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
|
BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
|
||||||
};
|
};
|
||||||
use crate::coverage::spans::Covspan;
|
use crate::coverage::spans::Covspan;
|
||||||
|
use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro;
|
||||||
use crate::coverage::ExtractedHirInfo;
|
use crate::coverage::ExtractedHirInfo;
|
||||||
|
|
||||||
pub(crate) struct ExtractedCovspans {
|
pub(crate) struct ExtractedCovspans {
|
||||||
|
@ -215,59 +216,6 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range
|
|
||||||
/// within the function's body source. This span is guaranteed to be contained
|
|
||||||
/// within, or equal to, the `body_span`. If the extrapolated span is not
|
|
||||||
/// contained within the `body_span`, `None` is returned.
|
|
||||||
///
|
|
||||||
/// [^1]Expansions result from Rust syntax including macros, syntactic sugar,
|
|
||||||
/// etc.).
|
|
||||||
pub(crate) fn unexpand_into_body_span_with_visible_macro(
|
|
||||||
original_span: Span,
|
|
||||||
body_span: Span,
|
|
||||||
) -> Option<(Span, Option<Symbol>)> {
|
|
||||||
let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?;
|
|
||||||
|
|
||||||
let visible_macro = prev
|
|
||||||
.map(|prev| match prev.ctxt().outer_expn_data().kind {
|
|
||||||
ExpnKind::Macro(MacroKind::Bang, name) => Some(name),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.flatten();
|
|
||||||
|
|
||||||
Some((span, visible_macro))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Walks through the expansion ancestors of `original_span` to find a span that
|
|
||||||
/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`.
|
|
||||||
/// The ancestor that was traversed just before the matching span (if any) is
|
|
||||||
/// also returned.
|
|
||||||
///
|
|
||||||
/// For example, a return value of `Some((ancestor, Some(prev))` means that:
|
|
||||||
/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)`
|
|
||||||
/// - `ancestor == prev.parent_callsite()`
|
|
||||||
///
|
|
||||||
/// [`SyntaxContext`]: rustc_span::SyntaxContext
|
|
||||||
fn unexpand_into_body_span_with_prev(
|
|
||||||
original_span: Span,
|
|
||||||
body_span: Span,
|
|
||||||
) -> Option<(Span, Option<Span>)> {
|
|
||||||
let mut prev = None;
|
|
||||||
let mut curr = original_span;
|
|
||||||
|
|
||||||
while !body_span.contains(curr) || !curr.eq_ctxt(body_span) {
|
|
||||||
prev = Some(curr);
|
|
||||||
curr = curr.parent_callsite()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span));
|
|
||||||
if let Some(prev) = prev {
|
|
||||||
debug_assert_eq!(Some(curr), prev.parent_callsite());
|
|
||||||
}
|
|
||||||
|
|
||||||
Some((curr, prev))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Hole {
|
pub(crate) struct Hole {
|
||||||
pub(crate) span: Span,
|
pub(crate) span: Span,
|
||||||
|
|
54
compiler/rustc_mir_transform/src/coverage/unexpand.rs
Normal file
54
compiler/rustc_mir_transform/src/coverage/unexpand.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
|
||||||
|
|
||||||
|
/// Returns an extrapolated span (pre-expansion[^1]) corresponding to a range
|
||||||
|
/// within the function's body source. This span is guaranteed to be contained
|
||||||
|
/// within, or equal to, the `body_span`. If the extrapolated span is not
|
||||||
|
/// contained within the `body_span`, `None` is returned.
|
||||||
|
///
|
||||||
|
/// [^1]Expansions result from Rust syntax including macros, syntactic sugar,
|
||||||
|
/// etc.).
|
||||||
|
pub(crate) fn unexpand_into_body_span_with_visible_macro(
|
||||||
|
original_span: Span,
|
||||||
|
body_span: Span,
|
||||||
|
) -> Option<(Span, Option<Symbol>)> {
|
||||||
|
let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?;
|
||||||
|
|
||||||
|
let visible_macro = prev
|
||||||
|
.map(|prev| match prev.ctxt().outer_expn_data().kind {
|
||||||
|
ExpnKind::Macro(MacroKind::Bang, name) => Some(name),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
Some((span, visible_macro))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Walks through the expansion ancestors of `original_span` to find a span that
|
||||||
|
/// is contained in `body_span` and has the same [`SyntaxContext`] as `body_span`.
|
||||||
|
/// The ancestor that was traversed just before the matching span (if any) is
|
||||||
|
/// also returned.
|
||||||
|
///
|
||||||
|
/// For example, a return value of `Some((ancestor, Some(prev))` means that:
|
||||||
|
/// - `ancestor == original_span.find_ancestor_inside_same_ctxt(body_span)`
|
||||||
|
/// - `ancestor == prev.parent_callsite()`
|
||||||
|
///
|
||||||
|
/// [`SyntaxContext`]: rustc_span::SyntaxContext
|
||||||
|
fn unexpand_into_body_span_with_prev(
|
||||||
|
original_span: Span,
|
||||||
|
body_span: Span,
|
||||||
|
) -> Option<(Span, Option<Span>)> {
|
||||||
|
let mut prev = None;
|
||||||
|
let mut curr = original_span;
|
||||||
|
|
||||||
|
while !body_span.contains(curr) || !curr.eq_ctxt(body_span) {
|
||||||
|
prev = Some(curr);
|
||||||
|
curr = curr.parent_callsite()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(Some(curr), original_span.find_ancestor_in_same_ctxt(body_span));
|
||||||
|
if let Some(prev) = prev {
|
||||||
|
debug_assert_eq!(Some(curr), prev.parent_callsite());
|
||||||
|
}
|
||||||
|
|
||||||
|
Some((curr, prev))
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue