Skip to content

Commit 9f455d3

Browse files
Rollup merge of #126621 - Zalathar:test-coverage-attr, r=petrochenkov
More thorough status-quo tests for `#[coverage(..)]` In light of the stabilization push at #84605 (comment), I have written some tests to more thoroughly capture the current behaviour of the `#[coverage(..)]` attribute. These tests aim to capture the *current* behaviour, which is not necessarily the desired behaviour. For example, some of the error message are not great, some things that perhaps ought to cause an error do not, and recursive coverage attributes have not been implemented yet. `@rustbot` label +A-code-coverage
2 parents bbec736 + 5093658 commit 9f455d3

10 files changed

+604
-0
lines changed

tests/coverage/attr/nested.cov-map

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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+
33+
Function name: nested::closure_expr
34+
Raw bytes (14): 0x[01, 01, 00, 02, 01, 44, 01, 01, 0f, 01, 0b, 05, 01, 02]
35+
Number of files: 1
36+
- file 0 => global file 1
37+
Number of expressions: 0
38+
Number of file 0 mappings: 2
39+
- Code(Counter(0)) at (prev + 68, 1) to (start + 1, 15)
40+
- Code(Counter(0)) at (prev + 11, 5) to (start + 1, 2)
41+
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+
59+
Function name: nested::closure_tail
60+
Raw bytes (14): 0x[01, 01, 00, 02, 01, 53, 01, 01, 0f, 01, 11, 05, 01, 02]
61+
Number of files: 1
62+
- file 0 => global file 1
63+
Number of expressions: 0
64+
Number of file 0 mappings: 2
65+
- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 15)
66+
- Code(Counter(0)) at (prev + 17, 5) to (start + 1, 2)
67+
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

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
LL| |#![feature(coverage_attribute, stmt_expr_attributes)]
2+
LL| |//@ edition: 2021
3+
LL| |
4+
LL| |// Demonstrates the interaction between #[coverage(off)] and various kinds of
5+
LL| |// nested function.
6+
LL| |
7+
LL| |// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
8+
LL| |// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
9+
LL| |// its lines can still be marked with misleading execution counts from its enclosing
10+
LL| |// function.
11+
LL| |
12+
LL| |#[coverage(off)]
13+
LL| |fn do_stuff() {}
14+
LL| |
15+
LL| |#[coverage(off)]
16+
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| }
23+
LL| | do_stuff();
24+
LL| |}
25+
LL| |
26+
LL| |struct MyOuter;
27+
LL| |impl MyOuter {
28+
LL| | #[coverage(off)]
29+
LL| | fn outer_method(&self) {
30+
LL| | struct MyMiddle;
31+
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| }
41+
LL| | }
42+
LL| | do_stuff();
43+
LL| | }
44+
LL| |}
45+
LL| |
46+
LL| |trait MyTrait {
47+
LL| | fn trait_method(&self);
48+
LL| |}
49+
LL| |impl MyTrait for MyOuter {
50+
LL| | #[coverage(off)]
51+
LL| | fn trait_method(&self) {
52+
LL| | struct MyMiddle;
53+
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| }
63+
LL| | }
64+
LL| | do_stuff();
65+
LL| | }
66+
LL| |}
67+
LL| |
68+
LL| 1|fn closure_expr() {
69+
LL| 1| let _outer = #[coverage(off)]
70+
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| };
77+
LL| | do_stuff();
78+
LL| | };
79+
LL| 1| do_stuff();
80+
LL| 1|}
81+
LL| |
82+
LL| |// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
83+
LL| 1|fn closure_tail() {
84+
LL| 1| let _outer = {
85+
LL| | #[coverage(off)]
86+
LL| | || {
87+
LL| | let _middle = {
88+
LL| 0| || {
89+
LL| 0| let _inner = {
90+
LL| 0| || {
91+
LL| 0| do_stuff();
92+
LL| 0| }
93+
LL| | };
94+
LL| 0| do_stuff();
95+
LL| 0| }
96+
LL| | };
97+
LL| | do_stuff();
98+
LL| | }
99+
LL| | };
100+
LL| 1| do_stuff();
101+
LL| 1|}
102+
LL| |
103+
LL| |#[coverage(off)]
104+
LL| |fn main() {
105+
LL| | outer_fn();
106+
LL| | MyOuter.outer_method();
107+
LL| | MyOuter.trait_method();
108+
LL| | closure_expr();
109+
LL| | closure_tail();
110+
LL| |}
111+

tests/coverage/attr/nested.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#![feature(coverage_attribute, stmt_expr_attributes)]
2+
//@ edition: 2021
3+
4+
// Demonstrates the interaction between #[coverage(off)] and various kinds of
5+
// nested function.
6+
7+
// FIXME(#126625): Coverage attributes should apply recursively to nested functions.
8+
// FIXME(#126626): When an inner (non-closure) function has `#[coverage(off)]`,
9+
// its lines can still be marked with misleading execution counts from its enclosing
10+
// function.
11+
12+
#[coverage(off)]
13+
fn do_stuff() {}
14+
15+
#[coverage(off)]
16+
fn outer_fn() {
17+
fn middle_fn() {
18+
fn inner_fn() {
19+
do_stuff();
20+
}
21+
do_stuff();
22+
}
23+
do_stuff();
24+
}
25+
26+
struct MyOuter;
27+
impl MyOuter {
28+
#[coverage(off)]
29+
fn outer_method(&self) {
30+
struct MyMiddle;
31+
impl MyMiddle {
32+
fn middle_method(&self) {
33+
struct MyInner;
34+
impl MyInner {
35+
fn inner_method(&self) {
36+
do_stuff();
37+
}
38+
}
39+
do_stuff();
40+
}
41+
}
42+
do_stuff();
43+
}
44+
}
45+
46+
trait MyTrait {
47+
fn trait_method(&self);
48+
}
49+
impl MyTrait for MyOuter {
50+
#[coverage(off)]
51+
fn trait_method(&self) {
52+
struct MyMiddle;
53+
impl MyTrait for MyMiddle {
54+
fn trait_method(&self) {
55+
struct MyInner;
56+
impl MyTrait for MyInner {
57+
fn trait_method(&self) {
58+
do_stuff();
59+
}
60+
}
61+
do_stuff();
62+
}
63+
}
64+
do_stuff();
65+
}
66+
}
67+
68+
fn closure_expr() {
69+
let _outer = #[coverage(off)]
70+
|| {
71+
let _middle = || {
72+
let _inner = || {
73+
do_stuff();
74+
};
75+
do_stuff();
76+
};
77+
do_stuff();
78+
};
79+
do_stuff();
80+
}
81+
82+
// This syntax is allowed, even without #![feature(stmt_expr_attributes)].
83+
fn closure_tail() {
84+
let _outer = {
85+
#[coverage(off)]
86+
|| {
87+
let _middle = {
88+
|| {
89+
let _inner = {
90+
|| {
91+
do_stuff();
92+
}
93+
};
94+
do_stuff();
95+
}
96+
};
97+
do_stuff();
98+
}
99+
};
100+
do_stuff();
101+
}
102+
103+
#[coverage(off)]
104+
fn main() {
105+
outer_fn();
106+
MyOuter.outer_method();
107+
MyOuter.trait_method();
108+
closure_expr();
109+
closure_tail();
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Function name: off_on_sandwich::dense_a::dense_b
2+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 14, 05, 07, 06]
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(Counter(0)) at (prev + 20, 5) to (start + 7, 6)
8+
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+
17+
Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c
18+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 09, 0b, 0a]
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(Counter(0)) at (prev + 38, 9) to (start + 11, 10)
24+
25+
Function name: off_on_sandwich::sparse_a::sparse_b::sparse_c::sparse_d
26+
Raw bytes (9): 0x[01, 01, 00, 01, 01, 29, 0d, 07, 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(Counter(0)) at (prev + 41, 13) to (start + 7, 14)
32+

0 commit comments

Comments
 (0)