From 682f744f89e1c014e91b2fd7058c75f2056ac870 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 28 Jul 2025 12:25:05 +1000 Subject: [PATCH] coverage: Treat `#[automatically_derived]` as `#[coverage(off)]` --- .../rustc_mir_transform/src/coverage/query.rs | 19 +++++++-------- tests/coverage/auto-derived.auto.cov-map | 24 ------------------- tests/coverage/auto-derived.auto.coverage | 12 +++++----- tests/coverage/auto-derived.on.cov-map | 14 +++++++++++ tests/coverage/auto-derived.on.coverage | 10 ++++---- 5 files changed, 34 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 02e433e53c92..73795e47d2e9 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -32,16 +32,6 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { return false; } - // Don't instrument functions with `#[automatically_derived]` on their - // enclosing impl block, on the assumption that most users won't care about - // coverage for derived impls. - if let Some(impl_of) = tcx.impl_of_assoc(def_id.to_def_id()) - && tcx.is_automatically_derived(impl_of) - { - trace!("InstrumentCoverage skipped for {def_id:?} (automatically derived)"); - return false; - } - if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::NAKED) { trace!("InstrumentCoverage skipped for {def_id:?} (`#[naked]`)"); return false; @@ -67,6 +57,15 @@ fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { } }; + // Treat `#[automatically_derived]` as an implied `#[coverage(off)]`, on + // the assumption that most users won't want coverage for derived impls. + // + // This affects not just the associated items of an impl block, but also + // any closures and other nested functions within those associated items. + if tcx.is_automatically_derived(def_id.to_def_id()) { + return false; + } + // Check the parent def (and so on recursively) until we find an // enclosing attribute or reach the crate root. match tcx.opt_local_parent(def_id) { diff --git a/tests/coverage/auto-derived.auto.cov-map b/tests/coverage/auto-derived.auto.cov-map index a0aa1206de42..e3d411d895aa 100644 --- a/tests/coverage/auto-derived.auto.cov-map +++ b/tests/coverage/auto-derived.auto.cov-map @@ -1,15 +1,3 @@ -Function name: ::my_assoc_fn::inner_fn -Raw bytes (24): 0x[01, 01, 00, 04, 01, 1a, 09, 00, 16, 01, 01, 0d, 00, 10, 01, 00, 11, 00, 1e, 01, 01, 09, 00, 0a] -Number of files: 1 -- file 0 => $DIR/auto-derived.rs -Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 26, 9) to (start + 0, 22) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 16) -- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 30) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -Highest counter ID seen: c0 - Function name: ::my_assoc_fn::inner_fn_on Raw bytes (24): 0x[01, 01, 00, 04, 01, 1f, 09, 00, 19, 01, 01, 0d, 00, 10, 01, 00, 11, 00, 23, 01, 01, 09, 00, 0a] Number of files: 1 @@ -22,18 +10,6 @@ Number of file 0 mappings: 4 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) Highest counter ID seen: c0 -Function name: ::my_assoc_fn::{closure#0} -Raw bytes (24): 0x[01, 01, 00, 04, 01, 23, 1a, 00, 1b, 01, 01, 0d, 00, 10, 01, 00, 11, 00, 1d, 01, 01, 09, 00, 0a] -Number of files: 1 -- file 0 => $DIR/auto-derived.rs -Number of expressions: 0 -Number of file 0 mappings: 4 -- Code(Counter(0)) at (prev + 35, 26) to (start + 0, 27) -- Code(Counter(0)) at (prev + 1, 13) to (start + 0, 16) -- Code(Counter(0)) at (prev + 0, 17) to (start + 0, 29) -- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 10) -Highest counter ID seen: c0 - Function name: auto_derived::main Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 00, 0a, 01, 01, 05, 00, 1a, 01, 01, 01, 00, 02] Number of files: 1 diff --git a/tests/coverage/auto-derived.auto.coverage b/tests/coverage/auto-derived.auto.coverage index 960bd11ec3a1..242abbf80318 100644 --- a/tests/coverage/auto-derived.auto.coverage +++ b/tests/coverage/auto-derived.auto.coverage @@ -23,18 +23,18 @@ LL| |#[cfg_attr(on, coverage(on))] LL| |impl MyTrait for MyStruct { LL| | fn my_assoc_fn() { - LL| 1| fn inner_fn() { - LL| 1| say("in inner fn"); - LL| 1| } + LL| | fn inner_fn() { + LL| | say("in inner fn"); + LL| | } LL| | LL| | #[coverage(on)] LL| 1| fn inner_fn_on() { LL| 1| say("in inner fn (on)"); LL| 1| } LL| | - LL| 1| let closure = || { - LL| 1| say("in closure"); - LL| 1| }; + LL| | let closure = || { + LL| | say("in closure"); + LL| | }; LL| | LL| | closure(); LL| | inner_fn(); diff --git a/tests/coverage/auto-derived.on.cov-map b/tests/coverage/auto-derived.on.cov-map index a0aa1206de42..2dcd616300d9 100644 --- a/tests/coverage/auto-derived.on.cov-map +++ b/tests/coverage/auto-derived.on.cov-map @@ -1,3 +1,17 @@ +Function name: ::my_assoc_fn +Raw bytes (34): 0x[01, 01, 00, 06, 01, 19, 05, 00, 15, 01, 0a, 0d, 00, 14, 01, 04, 09, 00, 12, 01, 01, 09, 00, 11, 01, 01, 09, 00, 14, 01, 01, 05, 00, 06] +Number of files: 1 +- file 0 => $DIR/auto-derived.rs +Number of expressions: 0 +Number of file 0 mappings: 6 +- Code(Counter(0)) at (prev + 25, 5) to (start + 0, 21) +- Code(Counter(0)) at (prev + 10, 13) to (start + 0, 20) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 18) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 17) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6) +Highest counter ID seen: c0 + Function name: ::my_assoc_fn::inner_fn Raw bytes (24): 0x[01, 01, 00, 04, 01, 1a, 09, 00, 16, 01, 01, 0d, 00, 10, 01, 00, 11, 00, 1e, 01, 01, 09, 00, 0a] Number of files: 1 diff --git a/tests/coverage/auto-derived.on.coverage b/tests/coverage/auto-derived.on.coverage index 960bd11ec3a1..6ab6aa5c4dfc 100644 --- a/tests/coverage/auto-derived.on.coverage +++ b/tests/coverage/auto-derived.on.coverage @@ -22,7 +22,7 @@ LL| |#[cfg_attr(on, automatically_derived)] LL| |#[cfg_attr(on, coverage(on))] LL| |impl MyTrait for MyStruct { - LL| | fn my_assoc_fn() { + LL| 1| fn my_assoc_fn() { LL| 1| fn inner_fn() { LL| 1| say("in inner fn"); LL| 1| } @@ -36,10 +36,10 @@ LL| 1| say("in closure"); LL| 1| }; LL| | - LL| | closure(); - LL| | inner_fn(); - LL| | inner_fn_on(); - LL| | } + LL| 1| closure(); + LL| 1| inner_fn(); + LL| 1| inner_fn_on(); + LL| 1| } LL| |} LL| | LL| |#[coverage(off)]