Skip to content

Commit 7f37f8a

Browse files
committed
coverage: Allow #[coverage(..)] on impl and mod
These attributes apply to all enclosed functions/methods/closures, unless explicitly overridden by another coverage attribute.
1 parent 3262611 commit 7f37f8a

13 files changed

+253
-170
lines changed

compiler/rustc_passes/src/check_attr.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -369,13 +369,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
369369
}
370370
}
371371

372-
/// Checks that `#[coverage(..)]` is applied to a function or closure.
372+
/// Checks that `#[coverage(..)]` is applied to a function/closure/method,
373+
/// or to an impl block or module.
373374
fn check_coverage(&self, attr: &Attribute, span: Span, target: Target) -> bool {
374375
match target {
375-
// #[coverage(..)] on function is fine
376376
Target::Fn
377377
| Target::Closure
378-
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true,
378+
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent)
379+
| Target::Impl
380+
| Target::Mod => true,
381+
379382
_ => {
380383
self.dcx().emit_err(errors::CoverageNotFnOrClosure {
381384
attr_span: attr.span,

tests/coverage/attr/impl.cov-map

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Function name: <impl::MyStruct>::off_on (unused)
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 0e, 05, 00, 13]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 14, 5) to (start + 0, 19)
8+
9+
Function name: <impl::MyStruct>::on_inherit (unused)
10+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 16, 05, 00, 17]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 0
14+
Number of file 0 mappings: 1
15+
- Code(Zero) at (prev + 22, 5) to (start + 0, 23)
16+
17+
Function name: <impl::MyStruct>::on_on (unused)
18+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 19, 05, 00, 12]
19+
Number of files: 1
20+
- file 0 => global file 1
21+
Number of expressions: 0
22+
Number of file 0 mappings: 1
23+
- Code(Zero) at (prev + 25, 5) to (start + 0, 18)
24+

tests/coverage/attr/impl.coverage

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
LL| |#![feature(coverage_attribute)]
2+
LL| |//@ edition: 2021
3+
LL| |
4+
LL| |// Checks that `#[coverage(..)]` can be applied to impl and impl-trait blocks,
5+
LL| |// and is inherited by any enclosed functions.
6+
LL| |
7+
LL| |struct MyStruct;
8+
LL| |
9+
LL| |#[coverage(off)]
10+
LL| |impl MyStruct {
11+
LL| | fn off_inherit() {}
12+
LL| |
13+
LL| | #[coverage(on)]
14+
LL| 0| fn off_on() {}
15+
LL| |
16+
LL| | #[coverage(off)]
17+
LL| | fn off_off() {}
18+
LL| |}
19+
LL| |
20+
LL| |#[coverage(on)]
21+
LL| |impl MyStruct {
22+
LL| 0| fn on_inherit() {}
23+
LL| |
24+
LL| | #[coverage(on)]
25+
LL| 0| fn on_on() {}
26+
LL| |
27+
LL| | #[coverage(off)]
28+
LL| | fn on_off() {}
29+
LL| |}
30+
LL| |
31+
LL| |trait MyTrait {
32+
LL| | fn method();
33+
LL| |}
34+
LL| |
35+
LL| |#[coverage(off)]
36+
LL| |impl MyTrait for MyStruct {
37+
LL| | fn method() {}
38+
LL| |}
39+
LL| |
40+
LL| |#[coverage(off)]
41+
LL| |fn main() {}
42+

tests/coverage/attr/impl.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![feature(coverage_attribute)]
2+
//@ edition: 2021
3+
4+
// Checks that `#[coverage(..)]` can be applied to impl and impl-trait blocks,
5+
// and is inherited by any enclosed functions.
6+
7+
struct MyStruct;
8+
9+
#[coverage(off)]
10+
impl MyStruct {
11+
fn off_inherit() {}
12+
13+
#[coverage(on)]
14+
fn off_on() {}
15+
16+
#[coverage(off)]
17+
fn off_off() {}
18+
}
19+
20+
#[coverage(on)]
21+
impl MyStruct {
22+
fn on_inherit() {}
23+
24+
#[coverage(on)]
25+
fn on_on() {}
26+
27+
#[coverage(off)]
28+
fn on_off() {}
29+
}
30+
31+
trait MyTrait {
32+
fn method();
33+
}
34+
35+
#[coverage(off)]
36+
impl MyTrait for MyStruct {
37+
fn method() {}
38+
}
39+
40+
#[coverage(off)]
41+
fn main() {}

tests/coverage/attr/module.cov-map

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Function name: module::off::on (unused)
2+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 0c, 05, 00, 0f]
3+
Number of files: 1
4+
- file 0 => global file 1
5+
Number of expressions: 0
6+
Number of file 0 mappings: 1
7+
- Code(Zero) at (prev + 12, 5) to (start + 0, 15)
8+
9+
Function name: module::on::inherit (unused)
10+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 14, 05, 00, 14]
11+
Number of files: 1
12+
- file 0 => global file 1
13+
Number of expressions: 0
14+
Number of file 0 mappings: 1
15+
- Code(Zero) at (prev + 20, 5) to (start + 0, 20)
16+
17+
Function name: module::on::on (unused)
18+
Raw bytes (9): 0x[01, 01, 00, 01, 00, 17, 05, 00, 0f]
19+
Number of files: 1
20+
- file 0 => global file 1
21+
Number of expressions: 0
22+
Number of file 0 mappings: 1
23+
- Code(Zero) at (prev + 23, 5) to (start + 0, 15)
24+

tests/coverage/attr/module.coverage

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
LL| |#![feature(coverage_attribute)]
2+
LL| |//@ edition: 2021
3+
LL| |
4+
LL| |// Checks that `#[coverage(..)]` can be applied to modules, and is inherited
5+
LL| |// by any enclosed functions.
6+
LL| |
7+
LL| |#[coverage(off)]
8+
LL| |mod off {
9+
LL| | fn inherit() {}
10+
LL| |
11+
LL| | #[coverage(on)]
12+
LL| 0| fn on() {}
13+
LL| |
14+
LL| | #[coverage(off)]
15+
LL| | fn off() {}
16+
LL| |}
17+
LL| |
18+
LL| |#[coverage(on)]
19+
LL| |mod on {
20+
LL| 0| fn inherit() {}
21+
LL| |
22+
LL| | #[coverage(on)]
23+
LL| 0| fn on() {}
24+
LL| |
25+
LL| | #[coverage(off)]
26+
LL| | fn off() {}
27+
LL| |}
28+
LL| |
29+
LL| |#[coverage(off)]
30+
LL| |mod nested_a {
31+
LL| | mod nested_b {
32+
LL| | fn inner() {}
33+
LL| | }
34+
LL| |}
35+
LL| |
36+
LL| |#[coverage(off)]
37+
LL| |fn main() {}
38+

tests/coverage/attr/module.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#![feature(coverage_attribute)]
2+
//@ edition: 2021
3+
4+
// Checks that `#[coverage(..)]` can be applied to modules, and is inherited
5+
// by any enclosed functions.
6+
7+
#[coverage(off)]
8+
mod off {
9+
fn inherit() {}
10+
11+
#[coverage(on)]
12+
fn on() {}
13+
14+
#[coverage(off)]
15+
fn off() {}
16+
}
17+
18+
#[coverage(on)]
19+
mod on {
20+
fn inherit() {}
21+
22+
#[coverage(on)]
23+
fn on() {}
24+
25+
#[coverage(off)]
26+
fn off() {}
27+
}
28+
29+
#[coverage(off)]
30+
mod nested_a {
31+
mod nested_b {
32+
fn inner() {}
33+
}
34+
}
35+
36+
#[coverage(off)]
37+
fn main() {}

tests/ui/coverage-attr/name-value.rs

-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@
1010

1111
#[coverage = "off"]
1212
//~^ ERROR malformed `coverage` attribute input
13-
//~| ERROR attribute should be applied to a function definition or closure
1413
mod my_mod {}
1514

1615
mod my_mod_inner {
1716
#![coverage = "off"]
1817
//~^ ERROR malformed `coverage` attribute input
19-
//~| ERROR attribute should be applied to a function definition or closure
2018
}
2119

2220
#[coverage = "off"]
@@ -26,7 +24,6 @@ struct MyStruct;
2624

2725
#[coverage = "off"]
2826
//~^ ERROR malformed `coverage` attribute input
29-
//~| ERROR attribute should be applied to a function definition or closure
3027
impl MyStruct {
3128
#[coverage = "off"]
3229
//~^ ERROR malformed `coverage` attribute input
@@ -51,7 +48,6 @@ trait MyTrait {
5148

5249
#[coverage = "off"]
5350
//~^ ERROR malformed `coverage` attribute input
54-
//~| ERROR attribute should be applied to a function definition or closure
5551
impl MyTrait for MyStruct {
5652
#[coverage = "off"]
5753
//~^ ERROR malformed `coverage` attribute input

0 commit comments

Comments
 (0)