Skip to content

Commit 3262611

Browse files
committed
coverage: Apply #[coverage(..)] recursively to nested functions
1 parent 457fda1 commit 3262611

File tree

8 files changed

+60
-156
lines changed

8 files changed

+60
-156
lines changed

compiler/rustc_middle/src/query/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,8 @@ rustc_queries! {
572572
separate_provide_extern
573573
}
574574

575-
/// Checks for `#[coverage(off)]` or `#[coverage(on)]`.
575+
/// Checks for the nearest `#[coverage(off)]` or `#[coverage(on)]` on
576+
/// this def and any enclosing defs, up to the crate root.
576577
///
577578
/// Returns `false` if `#[coverage(off)]` was found, or `true` if
578579
/// either `#[coverage(on)]` or no coverage attribute was found.

compiler/rustc_mir_transform/src/coverage/query.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn is_eligible_for_coverage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
5555

5656
/// Query implementation for `coverage_attr_on`.
5757
fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
58+
// Check for annotations directly on this def.
5859
if let Some(attr) = tcx.get_attr(def_id, sym::coverage) {
5960
match attr.meta_item_list().as_deref() {
6061
Some([item]) if item.has_name(sym::off) => return false,
@@ -66,9 +67,14 @@ fn coverage_attr_on(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
6667
}
6768
}
6869

69-
// We didn't see an explicit coverage attribute, so
70-
// allow coverage instrumentation by default.
71-
true
70+
match tcx.opt_local_parent(def_id) {
71+
// Check the parent def (and so on recursively) until we find an
72+
// enclosing attribute or reach the crate root.
73+
Some(parent) => tcx.coverage_attr_on(parent),
74+
// We reached the crate root without seeing a coverage attribute, so
75+
// allow coverage instrumentation by default.
76+
None => true,
77+
}
7278
}
7379

7480
/// Query implementation for `coverage_ids_info`.

tests/coverage/attr/nested.cov-map

-82
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,3 @@
1-
Function name: <<<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method::MyInner as nested::MyTrait>::trait_method (unused)
2-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 39, 15, 02, 16]
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 + 57, 21) to (start + 2, 22)
8-
9-
Function name: <<<nested::MyOuter>::outer_method::MyMiddle>::middle_method::MyInner>::inner_method (unused)
10-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 23, 15, 02, 16]
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 + 35, 21) to (start + 2, 22)
16-
17-
Function name: <<nested::MyOuter as nested::MyTrait>::trait_method::MyMiddle as nested::MyTrait>::trait_method (unused)
18-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 36, 0d, 08, 0e]
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 + 54, 13) to (start + 8, 14)
24-
25-
Function name: <<nested::MyOuter>::outer_method::MyMiddle>::middle_method (unused)
26-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 20, 0d, 08, 0e]
27-
Number of files: 1
28-
- file 0 => global file 1
29-
Number of expressions: 0
30-
Number of file 0 mappings: 1
31-
- Code(Zero) at (prev + 32, 13) to (start + 8, 14)
32-
331
Function name: nested::closure_expr
342
Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02]
353
Number of files: 1
@@ -39,23 +7,6 @@ Number of file 0 mappings: 2
397
- Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15)
408
- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
419

42-
Function name: nested::closure_expr::{closure#0}::{closure#0} (unused)
43-
Raw bytes (14): 0x[01, 01, 00, 02, 00, 47, 1a, 01, 17, 00, 04, 0d, 01, 0a]
44-
Number of files: 1
45-
- file 0 => global file 1
46-
Number of expressions: 0
47-
Number of file 0 mappings: 2
48-
- Code(Zero) at (prev + 71, 26) to (start + 1, 23)
49-
- Code(Zero) at (prev + 4, 13) to (start + 1, 10)
50-
51-
Function name: nested::closure_expr::{closure#0}::{closure#0}::{closure#0} (unused)
52-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 48, 1d, 02, 0e]
53-
Number of files: 1
54-
- file 0 => global file 1
55-
Number of expressions: 0
56-
Number of file 0 mappings: 1
57-
- Code(Zero) at (prev + 72, 29) to (start + 2, 14)
58-
5910
Function name: nested::closure_tail
6011
Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02]
6112
Number of files: 1
@@ -65,36 +16,3 @@ Number of file 0 mappings: 2
6516
- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15)
6617
- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
6718

68-
Function name: nested::closure_tail::{closure#0}::{closure#0} (unused)
69-
Raw bytes (14): 0x[01, 01, 00, 02, 00, 58, 14, 01, 1f, 00, 06, 15, 01, 12]
70-
Number of files: 1
71-
- file 0 => global file 1
72-
Number of expressions: 0
73-
Number of file 0 mappings: 2
74-
- Code(Zero) at (prev + 88, 20) to (start + 1, 31)
75-
- Code(Zero) at (prev + 6, 21) to (start + 1, 18)
76-
77-
Function name: nested::closure_tail::{closure#0}::{closure#0}::{closure#0} (unused)
78-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 5a, 1c, 02, 1a]
79-
Number of files: 1
80-
- file 0 => global file 1
81-
Number of expressions: 0
82-
Number of file 0 mappings: 1
83-
- Code(Zero) at (prev + 90, 28) to (start + 2, 26)
84-
85-
Function name: nested::outer_fn::middle_fn (unused)
86-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 11, 05, 05, 06]
87-
Number of files: 1
88-
- file 0 => global file 1
89-
Number of expressions: 0
90-
Number of file 0 mappings: 1
91-
- Code(Zero) at (prev + 17, 5) to (start + 5, 6)
92-
93-
Function name: nested::outer_fn::middle_fn::inner_fn (unused)
94-
Raw bytes (9): 0x[01, 01, 00, 01, 00, 12, 09, 02, 0a]
95-
Number of files: 1
96-
- file 0 => global file 1
97-
Number of expressions: 0
98-
Number of file 0 mappings: 1
99-
- Code(Zero) at (prev + 18, 9) to (start + 2, 10)
100-

tests/coverage/attr/nested.coverage

+37-37
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
LL| |
1515
LL| |#[coverage(off)]
1616
LL| |fn outer_fn() {
17-
LL| 0| fn middle_fn() {
18-
LL| 0| fn inner_fn() {
19-
LL| 0| do_stuff();
20-
LL| 0| }
21-
LL| 0| do_stuff();
22-
LL| 0| }
17+
LL| | fn middle_fn() {
18+
LL| | fn inner_fn() {
19+
LL| | do_stuff();
20+
LL| | }
21+
LL| | do_stuff();
22+
LL| | }
2323
LL| | do_stuff();
2424
LL| |}
2525
LL| |
@@ -29,15 +29,15 @@
2929
LL| | fn outer_method(&self) {
3030
LL| | struct MyMiddle;
3131
LL| | impl MyMiddle {
32-
LL| 0| fn middle_method(&self) {
33-
LL| 0| struct MyInner;
34-
LL| 0| impl MyInner {
35-
LL| 0| fn inner_method(&self) {
36-
LL| 0| do_stuff();
37-
LL| 0| }
38-
LL| 0| }
39-
LL| 0| do_stuff();
40-
LL| 0| }
32+
LL| | fn middle_method(&self) {
33+
LL| | struct MyInner;
34+
LL| | impl MyInner {
35+
LL| | fn inner_method(&self) {
36+
LL| | do_stuff();
37+
LL| | }
38+
LL| | }
39+
LL| | do_stuff();
40+
LL| | }
4141
LL| | }
4242
LL| | do_stuff();
4343
LL| | }
@@ -51,15 +51,15 @@
5151
LL| | fn trait_method(&self) {
5252
LL| | struct MyMiddle;
5353
LL| | impl MyTrait for MyMiddle {
54-
LL| 0| fn trait_method(&self) {
55-
LL| 0| struct MyInner;
56-
LL| 0| impl MyTrait for MyInner {
57-
LL| 0| fn trait_method(&self) {
58-
LL| 0| do_stuff();
59-
LL| 0| }
60-
LL| 0| }
61-
LL| 0| do_stuff();
62-
LL| 0| }
54+
LL| | fn trait_method(&self) {
55+
LL| | struct MyInner;
56+
LL| | impl MyTrait for MyInner {
57+
LL| | fn trait_method(&self) {
58+
LL| | do_stuff();
59+
LL| | }
60+
LL| | }
61+
LL| | do_stuff();
62+
LL| | }
6363
LL| | }
6464
LL| | do_stuff();
6565
LL| | }
@@ -68,12 +68,12 @@
6868
LL| 1|fn closure_expr() {
6969
LL| 1| let _outer = #[coverage(off)]
7070
LL| | || {
71-
LL| 0| let _middle = || {
72-
LL| 0| let _inner = || {
73-
LL| 0| do_stuff();
74-
LL| 0| };
75-
LL| 0| do_stuff();
76-
LL| 0| };
71+
LL| | let _middle = || {
72+
LL| | let _inner = || {
73+
LL| | do_stuff();
74+
LL| | };
75+
LL| | do_stuff();
76+
LL| | };
7777
LL| | do_stuff();
7878
LL| | };
7979
LL| 1| do_stuff();
@@ -85,14 +85,14 @@
8585
LL| | #[coverage(off)]
8686
LL| | || {
8787
LL| | let _middle = {
88-
LL| 0| || {
89-
LL| 0| let _inner = {
90-
LL| 0| || {
91-
LL| 0| do_stuff();
92-
LL| 0| }
88+
LL| | || {
89+
LL| | let _inner = {
90+
LL| | || {
91+
LL| | do_stuff();
92+
LL| | }
9393
LL| | };
94-
LL| 0| do_stuff();
95-
LL| 0| }
94+
LL| | do_stuff();
95+
LL| | }
9696
LL| | };
9797
LL| | do_stuff();
9898
LL| | }

tests/coverage/attr/off-on-sandwich.cov-map

-8
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,6 @@ Number of expressions: 0
66
Number of file 0 mappings: 1
77
- Code(Counter(0)) at (prev + 20, 5) to (start + 7, 6)
88

9-
Function name: off_on_sandwich::sparse_a::sparse_b
10-
Raw bytes (9): 0x[01, 01, 00, 01, 01, 22, 05, 10, 06]
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(Counter(0)) at (prev + 34, 5) to (start + 16, 6)
16-
179
Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
1810
Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 09, 0b, 0a]
1911
Number of files: 1

tests/coverage/attr/off-on-sandwich.coverage

+5-5
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
LL| |fn sparse_a() {
3232
LL| | sparse_b();
3333
LL| | sparse_b();
34-
LL| 2| fn sparse_b() {
35-
LL| 2| sparse_c();
36-
LL| 2| sparse_c();
37-
LL| 2| #[coverage(on)]
34+
LL| | fn sparse_b() {
35+
LL| | sparse_c();
36+
LL| | sparse_c();
37+
LL| | #[coverage(on)]
3838
LL| 4| fn sparse_c() {
3939
LL| 4| sparse_d();
4040
LL| 4| sparse_d();
@@ -47,7 +47,7 @@
4747
LL| 8| }
4848
LL| 8| }
4949
LL| 4| }
50-
LL| 2| }
50+
LL| | }
5151
LL| |}
5252
LL| |
5353
LL| |#[coverage(off)]

tests/coverage/no_cov_crate.cov-map

-13
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,3 @@ Number of file 0 mappings: 4
5959
= (c0 - c1)
6060
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
6161

62-
Function name: no_cov_crate::nested_fns::outer_not_covered::inner
63-
Raw bytes (26): 0x[01, 01, 01, 01, 05, 04, 01, 26, 09, 01, 17, 05, 01, 18, 02, 0e, 02, 02, 14, 02, 0e, 01, 03, 09, 00, 0a]
64-
Number of files: 1
65-
- file 0 => global file 1
66-
Number of expressions: 1
67-
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
68-
Number of file 0 mappings: 4
69-
- Code(Counter(0)) at (prev + 38, 9) to (start + 1, 23)
70-
- Code(Counter(1)) at (prev + 1, 24) to (start + 2, 14)
71-
- Code(Expression(0, Sub)) at (prev + 2, 20) to (start + 2, 14)
72-
= (c0 - c1)
73-
- Code(Counter(0)) at (prev + 3, 9) to (start + 0, 10)
74-

tests/coverage/no_cov_crate.coverage

+7-7
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@
3535
LL| |mod nested_fns {
3636
LL| | #[coverage(off)]
3737
LL| | pub fn outer_not_covered(is_true: bool) {
38-
LL| 1| fn inner(is_true: bool) {
39-
LL| 1| if is_true {
40-
LL| 1| println!("called and covered");
41-
LL| 1| } else {
42-
LL| 0| println!("absolutely not covered");
43-
LL| 0| }
44-
LL| 1| }
38+
LL| | fn inner(is_true: bool) {
39+
LL| | if is_true {
40+
LL| | println!("called and covered");
41+
LL| | } else {
42+
LL| | println!("absolutely not covered");
43+
LL| | }
44+
LL| | }
4545
LL| | println!("called but not covered");
4646
LL| | inner(is_true);
4747
LL| | }

0 commit comments

Comments
 (0)