|
1 |
| -use super::*; |
2 |
| - |
3 | 1 | use rustc_data_structures::captures::Captures;
|
4 |
| -use rustc_middle::mir::coverage::*; |
5 |
| -use rustc_middle::mir::{Body, CoverageIdsInfo}; |
6 |
| -use rustc_middle::ty::{self}; |
| 2 | +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
| 3 | +use rustc_middle::mir::coverage::{CounterId, CoverageKind}; |
| 4 | +use rustc_middle::mir::{Body, Coverage, CoverageIdsInfo, Statement, StatementKind}; |
| 5 | +use rustc_middle::query::TyCtxtAt; |
| 6 | +use rustc_middle::ty::{self, TyCtxt}; |
7 | 7 | use rustc_middle::util::Providers;
|
| 8 | +use rustc_span::def_id::LocalDefId; |
8 | 9 |
|
9 | 10 | /// Registers query/hook implementations related to coverage.
|
10 | 11 | pub(crate) fn provide(providers: &mut Providers) {
|
| 12 | + providers.hooks.is_eligible_for_coverage = |
| 13 | + |TyCtxtAt { tcx, .. }, def_id| is_eligible_for_coverage(tcx, def_id); |
11 | 14 | providers.queries.coverage_ids_info = coverage_ids_info;
|
12 | 15 | }
|
13 | 16 |
|
| 17 | +/// Hook implementation for [`TyCtxt::is_eligible_for_coverage`]. |
| 18 | +fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { |
| 19 | + // Only instrument functions, methods, and closures (not constants since they are evaluated |
| 20 | + // at compile time by Miri). |
| 21 | + // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const |
| 22 | + // expressions get coverage spans, we will probably have to "carve out" space for const |
| 23 | + // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might |
| 24 | + // be tricky if const expressions have no corresponding statements in the enclosing MIR. |
| 25 | + // Closures are carved out by their initial `Assign` statement.) |
| 26 | + if !tcx.def_kind(def_id).is_fn_like() { |
| 27 | + trace!("InstrumentCoverage skipped for {def_id:?} (not an fn-like)"); |
| 28 | + return false; |
| 29 | + } |
| 30 | + |
| 31 | + // Don't instrument functions with `#[automatically_derived]` on their |
| 32 | + // enclosing impl block, on the assumption that most users won't care about |
| 33 | + // coverage for derived impls. |
| 34 | + if let Some(impl_of) = tcx.impl_of_method(def_id.to_def_id()) |
| 35 | + && tcx.is_automatically_derived(impl_of) |
| 36 | + { |
| 37 | + trace!("InstrumentCoverage skipped for {def_id:?} (automatically derived)"); |
| 38 | + return false; |
| 39 | + } |
| 40 | + |
| 41 | + if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NO_COVERAGE) { |
| 42 | + trace!("InstrumentCoverage skipped for {def_id:?} (`#[coverage(off)]`)"); |
| 43 | + return false; |
| 44 | + } |
| 45 | + |
| 46 | + true |
| 47 | +} |
| 48 | + |
14 | 49 | /// Query implementation for `coverage_ids_info`.
|
15 | 50 | fn coverage_ids_info<'tcx>(
|
16 | 51 | tcx: TyCtxt<'tcx>,
|
|
0 commit comments