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:
commit
ecb8702308
9 changed files with 52 additions and 18 deletions
|
@ -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)]
|
||||
|
|
|
@ -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(
|
|||
), // )
|
||||
],
|
||||
), // }
|
||||
), // )
|
||||
)), // )
|
||||
],
|
||||
)
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
8
tests/coverage/bench.cov-map
Normal file
8
tests/coverage/bench.cov-map
Normal 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)
|
||||
|
9
tests/coverage/bench.coverage
Normal file
9
tests/coverage/bench.coverage
Normal 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
8
tests/coverage/bench.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
#![feature(test)]
|
||||
// edition: 2021
|
||||
// compile-flags: --test
|
||||
|
||||
extern crate test;
|
||||
|
||||
#[bench]
|
||||
fn my_bench(_b: &mut test::Bencher) {}
|
|
@ -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
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
LL| |#[allow(dead_code)]
|
||||
LL| 0|fn unused() {}
|
||||
LL| |
|
||||
LL| 1|#[test]
|
||||
LL| |#[test]
|
||||
LL| 1|fn my_test() {}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Add table
Reference in a new issue