rustc_mir_transform/coverage/
from_mir.rs1use rustc_middle::mir::coverage::{CoverageKind, PointKind};
2use rustc_middle::mir::{self, Statement, StatementKind};
3use rustc_span::Span;
4
5use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
6use crate::coverage::hir_info::ExtractedHirInfo;
7
8#[derive(Debug)]
9pub(crate) struct RawSpanFromMir {
10 pub(crate) raw_span: Span,
14 pub(crate) bcb: BasicCoverageBlock,
15}
16
17pub(crate) fn extract_raw_spans_from_mir<'tcx>(
24 mir_body: &mir::Body<'tcx>,
25 hir_info: &ExtractedHirInfo,
26 graph: &CoverageGraph,
27) -> Vec<RawSpanFromMir> {
28 let mut raw_spans = vec![];
29
30 for (bcb, bcb_data) in graph.iter_enumerated() {
32 for &bb in &bcb_data.basic_blocks {
34 let statements = mir_body[bb].statements.iter();
35 raw_spans.extend(
36 statements
37 .filter_map(|stmt| filtered_statement_span(hir_info, stmt))
38 .map(|raw_span: Span| RawSpanFromMir { raw_span, bcb }),
39 );
40 }
41 }
42
43 raw_spans
44}
45
46fn filtered_statement_span<'tcx>(
49 hir_info: &ExtractedHirInfo,
50 statement: &Statement<'tcx>,
51) -> Option<Span> {
52 let StatementKind::Coverage(CoverageKind::Point { point_kind, hir_id }) = statement.kind else {
53 return None;
54 };
55 match point_kind {
56 PointKind::Expr | PointKind::ImplicitElse | PointKind::FunctionEnd => {}
59 }
60 if hir_info.nodes_to_ignore.contains(&hir_id) {
61 return None;
62 }
63
64 Some(statement.source_info.span)
65}