Skip to content

Commit 9a5ac56

Browse files
committed
Rework no_coverage to coverage(off)
1 parent 19a647d commit 9a5ac56

File tree

27 files changed

+183
-158
lines changed

27 files changed

+183
-158
lines changed

compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn expand_deriving_eq(
3434
attributes: thin_vec![
3535
cx.attr_word(sym::inline, span),
3636
cx.attr_nested_word(sym::doc, sym::hidden, span),
37-
cx.attr_word(sym::no_coverage, span)
37+
cx.attr_nested_word(sym::coverage, sym::off, span)
3838
],
3939
fieldless_variants_strategy: FieldlessVariantsStrategy::Unify,
4040
combine_substructure: combine_substructure(Box::new(|a, b, c| {

compiler/rustc_builtin_macros/src/test_harness.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ fn generate_test_harness(
251251
let expn_id = ext_cx.resolver.expansion_for_ast_pass(
252252
DUMMY_SP,
253253
AstPass::TestHarness,
254-
&[sym::test, sym::rustc_attrs, sym::no_coverage],
254+
&[sym::test, sym::rustc_attrs, sym::coverage],
255255
None,
256256
);
257257
let def_site = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
@@ -332,8 +332,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
332332

333333
// #[rustc_main]
334334
let main_attr = ecx.attr_word(sym::rustc_main, sp);
335-
// #[no_coverage]
336-
let no_coverage_attr = ecx.attr_word(sym::no_coverage, sp);
335+
// #[coverage(off)]
336+
let coverage_attr = ecx.attr_nested_word(sym::coverage, sym::off, sp);
337337

338338
// pub fn main() { ... }
339339
let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new()));
@@ -363,7 +363,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
363363

364364
let main = P(ast::Item {
365365
ident: main_id,
366-
attrs: thin_vec![main_attr, no_coverage_attr],
366+
attrs: thin_vec![main_attr, coverage_attr],
367367
id: ast::DUMMY_NODE_ID,
368368
kind: main,
369369
vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,10 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
318318
{
319319
let codegen_fn_attrs = tcx.codegen_fn_attrs(non_codegenned_def_id);
320320

321-
// If a function is marked `#[no_coverage]`, then skip generating a
321+
// If a function is marked `#[coverage(off)]`, then skip generating a
322322
// dead code stub for it.
323323
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_COVERAGE) {
324-
debug!("skipping unused fn marked #[no_coverage]: {:?}", non_codegenned_def_id);
324+
debug!("skipping unused fn marked #[coverage(off)]: {:?}", non_codegenned_def_id);
325325
continue;
326326
}
327327

compiler/rustc_codegen_ssa/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ codegen_ssa_erroneous_constant = erroneous constant encountered
2323
2424
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
2525
26+
codegen_ssa_expected_coverage_symbol = expected `coverage(off)` or `coverage(on)`
27+
2628
codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)`
2729
2830
codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ use rustc_target::spec::{abi, SanitizerSet};
1616

1717
use crate::errors;
1818
use crate::target_features::from_target_feature;
19-
use crate::{errors::ExpectedUsedSymbol, target_features::check_target_feature_trait_unsafe};
19+
use crate::{
20+
errors::{ExpectedCoverageSymbol, ExpectedUsedSymbol},
21+
target_features::check_target_feature_trait_unsafe,
22+
};
2023

2124
fn linkage_by_name(tcx: TyCtxt<'_>, def_id: LocalDefId, name: &str) -> Linkage {
2225
use rustc_middle::mir::mono::Linkage::*;
@@ -128,7 +131,21 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
128131
.emit();
129132
}
130133
}
131-
sym::no_coverage => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE,
134+
sym::coverage => {
135+
let inner = attr.meta_item_list();
136+
match inner.as_deref() {
137+
Some([item]) if item.has_name(sym::off) => {
138+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE;
139+
}
140+
Some([item]) if item.has_name(sym::on) => {
141+
// Allow #[coverage(on)] for being explicit, maybe also in future to enable
142+
// coverage on a smaller scope within an excluded larger scopy.
143+
}
144+
Some(_) | None => {
145+
tcx.sess.emit_err(ExpectedCoverageSymbol { span: attr.span });
146+
}
147+
}
148+
}
132149
sym::rustc_std_internal_symbol => {
133150
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
134151
}

compiler/rustc_codegen_ssa/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,13 @@ pub struct UnknownArchiveKind<'a> {
560560
pub kind: &'a str,
561561
}
562562

563+
#[derive(Diagnostic)]
564+
#[diag(codegen_ssa_expected_coverage_symbol)]
565+
pub struct ExpectedCoverageSymbol {
566+
#[primary_span]
567+
pub span: Span,
568+
}
569+
563570
#[derive(Diagnostic)]
564571
#[diag(codegen_ssa_expected_used_symbol)]
565572
pub struct ExpectedUsedSymbol {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
A `#[no_coverage]` attribute was applied to something which does not show up
1+
A `#[coverage]` attribute was applied to something which does not show up
22
in code coverage, or is too granular to be excluded from the coverage report.
33

44
For now, this attribute can only be applied to function, method, and closure
@@ -9,18 +9,18 @@ will just emit an `unused_attributes` lint instead of this error.
99
Example of erroneous code:
1010

1111
```compile_fail,E0788
12-
#[no_coverage]
12+
#[coverage(off)]
1313
struct Foo;
1414
15-
#[no_coverage]
15+
#[coverage(on)]
1616
const FOO: Foo = Foo;
1717
```
1818

19-
`#[no_coverage]` tells the compiler to not generate coverage instrumentation for
20-
a piece of code when the `-C instrument-coverage` flag is passed. Things like
21-
structs and consts are not coverable code, and thus cannot do anything with this
22-
attribute.
19+
`#[coverage(off)]` tells the compiler to not generate coverage instrumentation
20+
for a piece of code when the `-C instrument-coverage` flag is passed. Things
21+
like structs and consts are not coverable code, and thus cannot do anything
22+
with this attribute.
2323

2424
If you wish to apply this attribute to all methods in an impl or module,
2525
manually annotate each method; it is not possible to annotate the entire impl
26-
with a `#[no_coverage]` attribute.
26+
with a `#[coverage]` attribute.

compiler/rustc_feature/src/active.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ declare_features! (
393393
(active, const_trait_impl, "1.42.0", Some(67792), None),
394394
/// Allows the `?` operator in const contexts.
395395
(active, const_try, "1.56.0", Some(74935), None),
396+
/// Allows function attribute `#[coverage(on/off)]`, to control coverage
397+
/// instrumentation of that function.
398+
(active, coverage, "1.53.0", Some(84605), None),
396399
/// Allows non-builtin attributes in inner attribute position.
397400
(active, custom_inner_attributes, "1.30.0", Some(54726), None),
398401
/// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
@@ -504,9 +507,6 @@ declare_features! (
504507
(active, never_type_fallback, "1.41.0", Some(65992), None),
505508
/// Allows `#![no_core]`.
506509
(active, no_core, "1.3.0", Some(29639), None),
507-
/// Allows function attribute `#[no_coverage]`, to bypass coverage
508-
/// instrumentation of that function.
509-
(active, no_coverage, "1.53.0", Some(84605), None),
510510
/// Allows the use of `no_sanitize` attribute.
511511
(active, no_sanitize, "1.42.0", Some(39699), None),
512512
/// Allows using the `non_exhaustive_omitted_patterns` lint.

compiler/rustc_feature/src/builtin_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
394394
template!(List: "address, kcfi, memory, thread"), DuplicatesOk,
395395
experimental!(no_sanitize)
396396
),
397-
gated!(no_coverage, Normal, template!(Word), WarnFollowing, experimental!(no_coverage)),
397+
gated!(coverage, Normal, template!(Word, List: "on|off"), WarnFollowing, experimental!(coverage)),
398398

399399
ungated!(
400400
doc, Normal, template!(List: "hidden|inline|...", NameValueStr: "string"), DuplicatesOk

compiler/rustc_middle/src/middle/codegen_fn_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ bitflags! {
8787
/// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
8888
/// function as an entry function from Non-Secure code.
8989
const CMSE_NONSECURE_ENTRY = 1 << 14;
90-
/// `#[no_coverage]`: indicates that the function should be ignored by
90+
/// `#[coverage(off)]`: indicates that the function should be ignored by
9191
/// the MIR `InstrumentCoverage` pass and not added to the coverage map
9292
/// during codegen.
9393
const NO_COVERAGE = 1 << 15;

compiler/rustc_passes/messages.ftl

+13-13
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,19 @@ passes_continue_labeled_block =
110110
.label = labeled blocks cannot be `continue`'d
111111
.block_label = labeled block the `continue` points to
112112
113+
passes_coverage_fn_defn =
114+
`#[coverage]` may only be applied to function definitions
115+
116+
passes_coverage_ignored_function_prototype =
117+
`#[coverage]` is ignored on function prototypes
118+
119+
passes_coverage_not_coverable =
120+
`#[coverage]` must be applied to coverable code
121+
.label = not coverable code
122+
123+
passes_coverage_propagate =
124+
`#[coverage]` does not propagate into items and must be applied to the contained functions directly
125+
113126
passes_dead_codes =
114127
{ $multiple ->
115128
*[true] multiple {$descr}s are
@@ -494,19 +507,6 @@ passes_naked_functions_operands =
494507
passes_naked_tracked_caller =
495508
cannot use `#[track_caller]` with `#[naked]`
496509
497-
passes_no_coverage_fn_defn =
498-
`#[no_coverage]` may only be applied to function definitions
499-
500-
passes_no_coverage_ignored_function_prototype =
501-
`#[no_coverage]` is ignored on function prototypes
502-
503-
passes_no_coverage_not_coverable =
504-
`#[no_coverage]` must be applied to coverable code
505-
.label = not coverable code
506-
507-
passes_no_coverage_propagate =
508-
`#[no_coverage]` does not propagate into items and must be applied to the contained functions directly
509-
510510
passes_no_link =
511511
attribute should be applied to an `extern crate` item
512512
.label = not an `extern crate` item

compiler/rustc_passes/src/check_attr.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl CheckAttrVisitor<'_> {
107107
match attr.name_or_empty() {
108108
sym::do_not_recommend => self.check_do_not_recommend(attr.span, target),
109109
sym::inline => self.check_inline(hir_id, attr, span, target),
110-
sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target),
110+
sym::coverage => self.check_coverage(hir_id, attr, span, target),
111111
sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target),
112112
sym::marker => self.check_marker(hir_id, attr, span, target),
113113
sym::target_feature => self.check_target_feature(hir_id, attr, span, target),
@@ -327,16 +327,10 @@ impl CheckAttrVisitor<'_> {
327327
}
328328
}
329329

330-
/// Checks if a `#[no_coverage]` is applied directly to a function
331-
fn check_no_coverage(
332-
&self,
333-
hir_id: HirId,
334-
attr: &Attribute,
335-
span: Span,
336-
target: Target,
337-
) -> bool {
330+
/// Checks if a `#[coverage]` is applied directly to a function
331+
fn check_coverage(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
338332
match target {
339-
// no_coverage on function is fine
333+
// #[coverage] on function is fine
340334
Target::Fn
341335
| Target::Closure
342336
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
@@ -347,7 +341,7 @@ impl CheckAttrVisitor<'_> {
347341
UNUSED_ATTRIBUTES,
348342
hir_id,
349343
attr.span,
350-
errors::IgnoredNoCoverageFnProto,
344+
errors::IgnoredCoverageFnProto,
351345
);
352346
true
353347
}
@@ -357,7 +351,7 @@ impl CheckAttrVisitor<'_> {
357351
UNUSED_ATTRIBUTES,
358352
hir_id,
359353
attr.span,
360-
errors::IgnoredNoCoveragePropagate,
354+
errors::IgnoredCoveragePropagate,
361355
);
362356
true
363357
}
@@ -367,13 +361,13 @@ impl CheckAttrVisitor<'_> {
367361
UNUSED_ATTRIBUTES,
368362
hir_id,
369363
attr.span,
370-
errors::IgnoredNoCoverageFnDefn,
364+
errors::IgnoredCoverageFnDefn,
371365
);
372366
true
373367
}
374368

375369
_ => {
376-
self.tcx.sess.emit_err(errors::IgnoredNoCoverageNotCoverable {
370+
self.tcx.sess.emit_err(errors::IgnoredCoverageNotCoverable {
377371
attr_span: attr.span,
378372
defn_span: span,
379373
});

compiler/rustc_passes/src/errors.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,20 @@ pub struct InlineNotFnOrClosure {
6464
}
6565

6666
#[derive(LintDiagnostic)]
67-
#[diag(passes_no_coverage_ignored_function_prototype)]
68-
pub struct IgnoredNoCoverageFnProto;
67+
#[diag(passes_coverage_ignored_function_prototype)]
68+
pub struct IgnoredCoverageFnProto;
6969

7070
#[derive(LintDiagnostic)]
71-
#[diag(passes_no_coverage_propagate)]
72-
pub struct IgnoredNoCoveragePropagate;
71+
#[diag(passes_coverage_propagate)]
72+
pub struct IgnoredCoveragePropagate;
7373

7474
#[derive(LintDiagnostic)]
75-
#[diag(passes_no_coverage_fn_defn)]
76-
pub struct IgnoredNoCoverageFnDefn;
75+
#[diag(passes_coverage_fn_defn)]
76+
pub struct IgnoredCoverageFnDefn;
7777

7878
#[derive(Diagnostic)]
79-
#[diag(passes_no_coverage_not_coverable, code = "E0788")]
80-
pub struct IgnoredNoCoverageNotCoverable {
79+
#[diag(passes_coverage_not_coverable, code = "E0788")]
80+
pub struct IgnoredCoverageNotCoverable {
8181
#[primary_span]
8282
pub attr_span: Span,
8383
#[label]

compiler/rustc_span/src/symbol.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ symbols! {
565565
cosf32,
566566
cosf64,
567567
count,
568+
coverage,
568569
cr,
569570
crate_id,
570571
crate_in_paths,
@@ -1027,7 +1028,6 @@ symbols! {
10271028
no,
10281029
no_builtins,
10291030
no_core,
1030-
no_coverage,
10311031
no_crate_inject,
10321032
no_debug,
10331033
no_default_passes,
@@ -1058,6 +1058,7 @@ symbols! {
10581058
note,
10591059
object_safe_for_dispatch,
10601060
of,
1061+
off,
10611062
offset,
10621063
offset_of,
10631064
omit_gdb_pretty_printer_section,

library/core/src/cmp.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ pub trait Eq: PartialEq<Self> {
289289
//
290290
// This should never be implemented by hand.
291291
#[doc(hidden)]
292-
#[no_coverage] // rust-lang/rust#84605
292+
#[cfg_attr(bootstrap, no_coverage)] // rust-lang/rust#84605
293+
#[cfg_attr(not(bootstrap), coverage(off))] //
293294
#[inline]
294295
#[stable(feature = "rust1", since = "1.0.0")]
295296
fn assert_receiver_is_total_eq(&self) {}
@@ -298,7 +299,9 @@ pub trait Eq: PartialEq<Self> {
298299
/// Derive macro generating an impl of the trait [`Eq`].
299300
#[rustc_builtin_macro]
300301
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
301-
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match, no_coverage)]
302+
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
303+
#[cfg_attr(bootstrap, allow_internal_unstable(no_coverage))]
304+
#[cfg_attr(not(bootstrap), allow_internal_unstable(coverage))]
302305
pub macro Eq($item:item) {
303306
/* compiler built-in */
304307
}

library/core/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@
100100
//
101101
// Library features:
102102
// tidy-alphabetical-start
103+
#![cfg_attr(bootstrap, feature(no_coverage))] // rust-lang/rust#84605
104+
#![cfg_attr(not(bootstrap), feature(coverage))] // rust-lang/rust#84605
103105
#![feature(char_indices_offset)]
104106
#![feature(const_align_of_val)]
105107
#![feature(const_align_of_val_raw)]
@@ -226,7 +228,6 @@
226228
#![feature(negative_impls)]
227229
#![feature(never_type)]
228230
#![feature(no_core)]
229-
#![feature(no_coverage)] // rust-lang/rust#84605
230231
#![feature(platform_intrinsics)]
231232
#![feature(prelude_import)]
232233
#![feature(repr_simd)]

src/doc/rustc/src/instrument-coverage.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ Some of the more notable options in this example include:
173173
[`llvm-cov report`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report
174174
[`llvm-cov show`]: https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show
175175

176-
> **Note**: Coverage can also be disabled on an individual function by annotating the function with the [`no_coverage` attribute] (which requires the feature flag `#![feature(no_coverage)]`).
176+
> **Note**: Coverage can also be disabled on an individual function by annotating the function with the [`coverage(off)` attribute] (which requires the feature flag `#![feature(coverage)]`).
177177
178-
[`no_coverage` attribute]: ../unstable-book/language-features/no-coverage.html
178+
[`coverage` attribute]: ../unstable-book/language-features/coverage.html
179179

180180
## Interpreting reports
181181

0 commit comments

Comments
 (0)