Skip to content

Commit e796516

Browse files
committed
coverage: Extract helper for getting HIR info for coverage
1 parent d50499a commit e796516

File tree

2 files changed

+43
-26
lines changed

2 files changed

+43
-26
lines changed

compiler/rustc_middle/src/mir/coverage.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc_index::IndexVec;
44
use rustc_macros::HashStable;
5-
use rustc_span::Symbol;
5+
use rustc_span::{Span, Symbol};
66

77
use std::fmt::{self, Debug, Formatter};
88

@@ -176,3 +176,15 @@ pub struct FunctionCoverageInfo {
176176
pub expressions: IndexVec<ExpressionId, Expression>,
177177
pub mappings: Vec<Mapping>,
178178
}
179+
180+
/// Coverage information captured from HIR/THIR during MIR building.
181+
///
182+
/// A MIR body that does not have this information cannot be instrumented for
183+
/// coverage.
184+
#[derive(Clone, Debug)]
185+
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)]
186+
pub struct HirInfo {
187+
pub function_source_hash: u64,
188+
pub fn_sig_span: Span,
189+
pub body_span: Span,
190+
}

compiler/rustc_mir_transform/src/coverage/mod.rs

+30-25
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_middle::mir::{
2222
TerminatorKind,
2323
};
2424
use rustc_middle::ty::TyCtxt;
25-
use rustc_span::def_id::{DefId, LocalDefId};
25+
use rustc_span::def_id::LocalDefId;
2626
use rustc_span::source_map::SourceMap;
2727
use rustc_span::{ExpnKind, SourceFile, Span, Symbol};
2828

@@ -77,29 +77,15 @@ struct Instrumentor<'a, 'tcx> {
7777
impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
7878
fn new(tcx: TyCtxt<'tcx>, mir_body: &'a mut mir::Body<'tcx>) -> Self {
7979
let source_map = tcx.sess.source_map();
80-
let def_id = mir_body.source.def_id();
81-
let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id);
8280

83-
let body_span = get_body_span(tcx, hir_body, mir_body);
81+
let def_id = mir_body.source.def_id().expect_local();
82+
let mir::coverage::HirInfo { function_source_hash, fn_sig_span, body_span, .. } =
83+
make_coverage_hir_info(tcx, def_id);
8484

8585
let source_file = source_map.lookup_source_file(body_span.lo());
86-
let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
87-
fn_sig.span.eq_ctxt(body_span)
88-
&& Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo()))
89-
}) {
90-
Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
91-
None => body_span.shrink_to_lo(),
92-
};
93-
94-
debug!(
95-
"instrumenting {}: {:?}, fn sig span: {:?}, body span: {:?}",
96-
if tcx.is_closure(def_id) { "closure" } else { "function" },
97-
def_id,
98-
fn_sig_span,
99-
body_span
100-
);
10186

102-
let function_source_hash = hash_mir_source(tcx, hir_body);
87+
debug!(?fn_sig_span, ?body_span, "instrumenting {def_id:?}",);
88+
10389
let basic_coverage_blocks = CoverageGraph::from_mir(mir_body);
10490
let coverage_counters = CoverageCounters::new(&basic_coverage_blocks);
10591

@@ -327,13 +313,33 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
327313
true
328314
}
329315

316+
fn make_coverage_hir_info(tcx: TyCtxt<'_>, def_id: LocalDefId) -> mir::coverage::HirInfo {
317+
let source_map = tcx.sess.source_map();
318+
let (some_fn_sig, hir_body) = fn_sig_and_body(tcx, def_id);
319+
320+
let body_span = get_body_span(tcx, hir_body, def_id);
321+
322+
let source_file = source_map.lookup_source_file(body_span.lo());
323+
let fn_sig_span = match some_fn_sig.filter(|fn_sig| {
324+
fn_sig.span.eq_ctxt(body_span)
325+
&& Lrc::ptr_eq(&source_file, &source_map.lookup_source_file(fn_sig.span.lo()))
326+
}) {
327+
Some(fn_sig) => fn_sig.span.with_hi(body_span.lo()),
328+
None => body_span.shrink_to_lo(),
329+
};
330+
331+
let function_source_hash = hash_mir_source(tcx, hir_body);
332+
333+
mir::coverage::HirInfo { function_source_hash, fn_sig_span, body_span }
334+
}
335+
330336
fn fn_sig_and_body(
331337
tcx: TyCtxt<'_>,
332-
def_id: DefId,
338+
def_id: LocalDefId,
333339
) -> (Option<&rustc_hir::FnSig<'_>>, &rustc_hir::Body<'_>) {
334340
// FIXME(#79625): Consider improving MIR to provide the information needed, to avoid going back
335341
// to HIR for it.
336-
let hir_node = tcx.hir().get_if_local(def_id).expect("expected DefId is local");
342+
let hir_node = tcx.hir().get_by_def_id(def_id);
337343
let (_, fn_body_id) =
338344
hir::map::associated_body(hir_node).expect("HIR node is a function with body");
339345
(hir_node.fn_sig(), tcx.hir().body(fn_body_id))
@@ -342,12 +348,11 @@ fn fn_sig_and_body(
342348
fn get_body_span<'tcx>(
343349
tcx: TyCtxt<'tcx>,
344350
hir_body: &rustc_hir::Body<'tcx>,
345-
mir_body: &mut mir::Body<'tcx>,
351+
def_id: LocalDefId,
346352
) -> Span {
347353
let mut body_span = hir_body.value.span;
348-
let def_id = mir_body.source.def_id();
349354

350-
if tcx.is_closure(def_id) {
355+
if tcx.is_closure(def_id.to_def_id()) {
351356
// If the MIR function is a closure, and if the closure body span
352357
// starts from a macro, but it's content is not in that macro, try
353358
// to find a non-macro callsite, and instrument the spans there

0 commit comments

Comments
 (0)