Rollup merge of #120183 - Zalathar:test-closure, r=compiler-errors

Add `#[coverage(off)]` to closures introduced by `#[test]` and `#[bench]`

These closures are an internal implementation detail of the `#[test]` and `#[bench]` attribute macros, so from a user perspective there is no reason to instrument them for coverage.

Skipping them makes coverage reports slightly cleaner, and will also allow other changes to span processing during coverage instrumentation, without having to worry about how they affect the `#[test]` macro.

The `#[coverage(off)]` attribute has no effect when `-Cinstrument-coverage` is not used.

Fixes #120046.

---

Note that this PR has no effect on the user-written function that has the `#[test]` attribute attached to it. That function will still be instrumented as normal.
This commit is contained in:
León Orell Valerian Liehr 2024-01-23 21:53:58 +01:00 committed by GitHub
commit ecb8702308
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 52 additions and 18 deletions

View file

@ -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)]

View file

@ -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<ast::Expr>| {
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(
), // )
],
), // }
), // )
)), // )
],
)
};

View file

@ -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 */

View file

@ -0,0 +1,8 @@
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)

View file

@ -0,0 +1,9 @@
LL| |#![feature(test)]
LL| |// edition: 2021
LL| |// compile-flags: --test
LL| |
LL| |extern crate test;
LL| |
LL| |#[bench]
LL| 1|fn my_bench(_b: &mut test::Bencher) {}

8
tests/coverage/bench.rs Normal file
View file

@ -0,0 +1,8 @@
#![feature(test)]
// edition: 2021
// compile-flags: --test
extern crate test;
#[bench]
fn my_bench(_b: &mut test::Bencher) {}

View file

@ -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

View file

@ -6,6 +6,6 @@
LL| |#[allow(dead_code)]
LL| 0|fn unused() {}
LL| |
LL| 1|#[test]
LL| |#[test]
LL| 1|fn my_test() {}

View file

@ -28,7 +28,8 @@ pub const m_test: test::TestDescAndFn =
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 @@ pub const z_test: test::TestDescAndFn =
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 @@ pub const a_test: test::TestDescAndFn =
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]