From bdfc64ac984e892f6061deebaee5a9301b8d271f Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 21 Jan 2024 12:18:48 +1100 Subject: [PATCH 1/2] coverage: Add a test that uses `#[bench]` --- tests/coverage/bench.cov-map | 16 ++++++++++++++++ tests/coverage/bench.coverage | 9 +++++++++ tests/coverage/bench.rs | 8 ++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/coverage/bench.cov-map create mode 100644 tests/coverage/bench.coverage create mode 100644 tests/coverage/bench.rs diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map new file mode 100644 index 0000000000000..7cdb1b641bf3d --- /dev/null +++ b/tests/coverage/bench.cov-map @@ -0,0 +1,16 @@ +Function name: bench::my_bench +Raw bytes (9): 0x[01, 01, 00, 01, 01, 08, 01, 00, 27] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39) + +Function name: bench::my_bench::{closure#0} +Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 09] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 1 +- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 9) + diff --git a/tests/coverage/bench.coverage b/tests/coverage/bench.coverage new file mode 100644 index 0000000000000..4642d92cc1911 --- /dev/null +++ b/tests/coverage/bench.coverage @@ -0,0 +1,9 @@ + LL| |#![feature(test)] + LL| |// edition: 2021 + LL| |// compile-flags: --test + LL| | + LL| |extern crate test; + LL| | + LL| 1|#[bench] + LL| 1|fn my_bench(_b: &mut test::Bencher) {} + diff --git a/tests/coverage/bench.rs b/tests/coverage/bench.rs new file mode 100644 index 0000000000000..2dcd7355b2f79 --- /dev/null +++ b/tests/coverage/bench.rs @@ -0,0 +1,8 @@ +#![feature(test)] +// edition: 2021 +// compile-flags: --test + +extern crate test; + +#[bench] +fn my_bench(_b: &mut test::Bencher) {} From 6d7e80c5bc3cc3b176834322afc50dc8dd100599 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 21 Jan 2024 11:26:28 +1100 Subject: [PATCH 2/2] Add `#[coverage(off)]` to closures introduced by `#[test]`/`#[bench]` --- compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_builtin_macros/src/test.rs | 21 +++++++++++++++++---- library/core/src/macros/mod.rs | 4 ++-- tests/coverage/bench.cov-map | 8 -------- tests/coverage/bench.coverage | 2 +- tests/coverage/test_harness.cov-map | 8 -------- tests/coverage/test_harness.coverage | 2 +- tests/pretty/tests-are-sorted.pp | 9 ++++++--- 8 files changed, 28 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index f60b73fbe9b13..3e9b06a5b054b 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -6,6 +6,7 @@ #![doc(rust_logo)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(array_windows)] +#![feature(assert_matches)] #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 4d44e340ae149..0631f796894b1 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -9,6 +9,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, Level}; use rustc_expand::base::*; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Span}; +use std::assert_matches::assert_matches; use std::iter; use thin_vec::{thin_vec, ThinVec}; @@ -182,6 +183,16 @@ pub fn expand_test_or_bench( // creates $name: $expr let field = |name, expr| cx.field_imm(sp, Ident::from_str_and_span(name, sp), expr); + // Adds `#[coverage(off)]` to a closure, so it won't be instrumented in + // `-Cinstrument-coverage` builds. + // This requires `#[allow_internal_unstable(coverage_attribute)]` on the + // corresponding macro declaration in `core::macros`. + let coverage_off = |mut expr: P| { + assert_matches!(expr.kind, ast::ExprKind::Closure(_)); + expr.attrs.push(cx.attr_nested_word(sym::coverage, sym::off, sp)); + expr + }; + let test_fn = if is_bench { // A simple ident for a lambda let b = Ident::from_str_and_span("b", attr_sp); @@ -190,8 +201,9 @@ pub fn expand_test_or_bench( sp, cx.expr_path(test_path("StaticBenchFn")), thin_vec![ + // #[coverage(off)] // |b| self::test::assert_test_result( - cx.lambda1( + coverage_off(cx.lambda1( sp, cx.expr_call( sp, @@ -206,7 +218,7 @@ pub fn expand_test_or_bench( ], ), b, - ), // ) + )), // ) ], ) } else { @@ -214,8 +226,9 @@ pub fn expand_test_or_bench( sp, cx.expr_path(test_path("StaticTestFn")), thin_vec![ + // #[coverage(off)] // || { - cx.lambda0( + coverage_off(cx.lambda0( sp, // test::assert_test_result( cx.expr_call( @@ -230,7 +243,7 @@ pub fn expand_test_or_bench( ), // ) ], ), // } - ), // ) + )), // ) ], ) }; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index a2437feeeb9cf..9bbaf62a5caaf 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1596,7 +1596,7 @@ pub(crate) mod builtin { /// /// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute #[stable(feature = "rust1", since = "1.0.0")] - #[allow_internal_unstable(test, rustc_attrs)] + #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)] #[rustc_builtin_macro] pub macro test($item:item) { /* compiler built-in */ @@ -1609,7 +1609,7 @@ pub(crate) mod builtin { soft, reason = "`bench` is a part of custom test frameworks which are unstable" )] - #[allow_internal_unstable(test, rustc_attrs)] + #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)] #[rustc_builtin_macro] pub macro bench($item:item) { /* compiler built-in */ diff --git a/tests/coverage/bench.cov-map b/tests/coverage/bench.cov-map index 7cdb1b641bf3d..aa702a4868185 100644 --- a/tests/coverage/bench.cov-map +++ b/tests/coverage/bench.cov-map @@ -6,11 +6,3 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 8, 1) to (start + 0, 39) -Function name: bench::my_bench::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 09] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 9) - diff --git a/tests/coverage/bench.coverage b/tests/coverage/bench.coverage index 4642d92cc1911..64945dc641502 100644 --- a/tests/coverage/bench.coverage +++ b/tests/coverage/bench.coverage @@ -4,6 +4,6 @@ LL| | LL| |extern crate test; LL| | - LL| 1|#[bench] + LL| |#[bench] LL| 1|fn my_bench(_b: &mut test::Bencher) {} diff --git a/tests/coverage/test_harness.cov-map b/tests/coverage/test_harness.cov-map index 6940d2e282430..f75328b11c9ab 100644 --- a/tests/coverage/test_harness.cov-map +++ b/tests/coverage/test_harness.cov-map @@ -6,14 +6,6 @@ Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 10, 1) to (start + 0, 16) -Function name: test_harness::my_test::{closure#0} -Raw bytes (9): 0x[01, 01, 00, 01, 01, 09, 01, 00, 08] -Number of files: 1 -- file 0 => global file 1 -Number of expressions: 0 -Number of file 0 mappings: 1 -- Code(Counter(0)) at (prev + 9, 1) to (start + 0, 8) - Function name: test_harness::unused (unused) Raw bytes (9): 0x[01, 01, 00, 01, 00, 07, 01, 00, 0f] Number of files: 1 diff --git a/tests/coverage/test_harness.coverage b/tests/coverage/test_harness.coverage index ff6009f6fce43..c3f660506fbd8 100644 --- a/tests/coverage/test_harness.coverage +++ b/tests/coverage/test_harness.coverage @@ -6,6 +6,6 @@ LL| |#[allow(dead_code)] LL| 0|fn unused() {} LL| | - LL| 1|#[test] + LL| |#[test] LL| 1|fn my_test() {} diff --git a/tests/pretty/tests-are-sorted.pp b/tests/pretty/tests-are-sorted.pp index fd9386be8f3c3..fbdad0c323f34 100644 --- a/tests/pretty/tests-are-sorted.pp +++ b/tests/pretty/tests-are-sorted.pp @@ -28,7 +28,8 @@ should_panic: test::ShouldPanic::No, test_type: test::TestType::Unknown, }, - testfn: test::StaticTestFn(|| test::assert_test_result(m_test())), + testfn: test::StaticTestFn(#[coverage(off)] || + test::assert_test_result(m_test())), }; fn m_test() {} @@ -51,7 +52,8 @@ should_panic: test::ShouldPanic::No, test_type: test::TestType::Unknown, }, - testfn: test::StaticTestFn(|| test::assert_test_result(z_test())), + testfn: test::StaticTestFn(#[coverage(off)] || + test::assert_test_result(z_test())), }; #[ignore = "not yet implemented"] fn z_test() {} @@ -75,7 +77,8 @@ should_panic: test::ShouldPanic::No, test_type: test::TestType::Unknown, }, - testfn: test::StaticTestFn(|| test::assert_test_result(a_test())), + testfn: test::StaticTestFn(#[coverage(off)] || + test::assert_test_result(a_test())), }; fn a_test() {} #[rustc_main]