forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#84582 - richkadel:issue-84561, r=tmandry
Vastly improves coverage spans for macros Fixes: rust-lang#84561 This resolves problems where macros like `trace!(...)` would show zero coverage if tracing was disabled, and `assert_eq!(...)` would show zero coverage if the assertion did not fail, because only one coverage span was generated, for the branch. This PR started with an idea that I could just drop branching blocks with same span as expanded macro. (See the fixed issue for more details.) That did help, but it didn't resolve everything. I also needed to add a span specifically for the macro name (plus `!`) to ensure the macro gets coverage even if it's internal expansion adds conditional branching blocks that are retained, and would otherwise drop the outer span. Now that outer span is _only_ the `(argument, list)`, which can safely be dropped now), because the macro name has its own span. While testing, I also noticed the spanview debug output can cause an ICE on a function with no body. The workaround for this is included in this PR (separate commit). r? `````@tmandry````` cc? `````@wesleywiser`````
- Loading branch information
Showing
8 changed files
with
587 additions
and
56 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 3 additions & 3 deletions
6
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.inner_items.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
196 changes: 196 additions & 0 deletions
196
src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-84561.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
1| |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results. | ||
2| | | ||
3| |// expect-exit-status-101 | ||
4| 21|#[derive(PartialEq, Eq)] | ||
^0 | ||
------------------ | ||
| <issue_84561::Foo as core::cmp::PartialEq>::eq: | ||
| 4| 21|#[derive(PartialEq, Eq)] | ||
------------------ | ||
| Unexecuted instantiation: <issue_84561::Foo as core::cmp::PartialEq>::ne | ||
------------------ | ||
5| |struct Foo(u32); | ||
6| 1|fn test3() { | ||
7| 1| let is_true = std::env::args().len() == 1; | ||
8| 1| let bar = Foo(1); | ||
9| 1| assert_eq!(bar, Foo(1)); | ||
10| 1| let baz = Foo(0); | ||
11| 1| assert_ne!(baz, Foo(1)); | ||
12| 1| println!("{:?}", Foo(1)); | ||
13| 1| println!("{:?}", bar); | ||
14| 1| println!("{:?}", baz); | ||
15| 1| | ||
16| 1| assert_eq!(Foo(1), Foo(1)); | ||
17| 1| assert_ne!(Foo(0), Foo(1)); | ||
18| 1| assert_eq!(Foo(2), Foo(2)); | ||
19| 1| let bar = Foo(0); | ||
20| 1| assert_ne!(bar, Foo(3)); | ||
21| 1| assert_ne!(Foo(0), Foo(4)); | ||
22| 1| assert_eq!(Foo(3), Foo(3), "with a message"); | ||
^0 | ||
23| 1| println!("{:?}", bar); | ||
24| 1| println!("{:?}", Foo(1)); | ||
25| 1| | ||
26| 1| assert_ne!(Foo(0), Foo(5), "{}", if is_true { "true message" } else { "false message" }); | ||
^0 ^0 ^0 | ||
27| 1| assert_ne!( | ||
28| | Foo(0) | ||
29| | , | ||
30| | Foo(5) | ||
31| | , | ||
32| 0| "{}" | ||
33| 0| , | ||
34| 0| if | ||
35| 0| is_true | ||
36| | { | ||
37| 0| "true message" | ||
38| | } else { | ||
39| 0| "false message" | ||
40| | } | ||
41| | ); | ||
42| | | ||
43| 1| let is_true = std::env::args().len() == 1; | ||
44| 1| | ||
45| 1| assert_eq!( | ||
46| 1| Foo(1), | ||
47| 1| Foo(1) | ||
48| 1| ); | ||
49| 1| assert_ne!( | ||
50| 1| Foo(0), | ||
51| 1| Foo(1) | ||
52| 1| ); | ||
53| 1| assert_eq!( | ||
54| 1| Foo(2), | ||
55| 1| Foo(2) | ||
56| 1| ); | ||
57| 1| let bar = Foo(1); | ||
58| 1| assert_ne!( | ||
59| 1| bar, | ||
60| 1| Foo(3) | ||
61| 1| ); | ||
62| 1| if is_true { | ||
63| 1| assert_ne!( | ||
64| 1| Foo(0), | ||
65| 1| Foo(4) | ||
66| 1| ); | ||
67| | } else { | ||
68| 0| assert_eq!( | ||
69| 0| Foo(3), | ||
70| 0| Foo(3) | ||
71| 0| ); | ||
72| | } | ||
73| 1| if is_true { | ||
74| 1| assert_ne!( | ||
75| | Foo(0), | ||
76| | Foo(4), | ||
77| 0| "with a message" | ||
78| | ); | ||
79| | } else { | ||
80| 0| assert_eq!( | ||
81| | Foo(3), | ||
82| | Foo(3), | ||
83| 0| "with a message" | ||
84| | ); | ||
85| | } | ||
86| 1| assert_ne!( | ||
87| 1| if is_true { | ||
88| 1| Foo(0) | ||
89| | } else { | ||
90| 0| Foo(1) | ||
91| | }, | ||
92| | Foo(5) | ||
93| | ); | ||
94| 1| assert_ne!( | ||
95| 1| Foo(5), | ||
96| 1| if is_true { | ||
97| 1| Foo(0) | ||
98| | } else { | ||
99| 0| Foo(1) | ||
100| | } | ||
101| | ); | ||
102| 1| assert_ne!( | ||
103| 1| if is_true { | ||
104| 1| assert_eq!( | ||
105| 1| Foo(3), | ||
106| 1| Foo(3) | ||
107| 1| ); | ||
108| 1| Foo(0) | ||
109| | } else { | ||
110| 0| assert_ne!( | ||
111| 0| if is_true { | ||
112| 0| Foo(0) | ||
113| | } else { | ||
114| 0| Foo(1) | ||
115| | }, | ||
116| | Foo(5) | ||
117| | ); | ||
118| 0| Foo(1) | ||
119| | }, | ||
120| | Foo(5), | ||
121| 0| "with a message" | ||
122| | ); | ||
123| 1| assert_eq!( | ||
124| | Foo(1), | ||
125| | Foo(3), | ||
126| 1| "this assert should fail" | ||
127| | ); | ||
128| 0| assert_eq!( | ||
129| | Foo(3), | ||
130| | Foo(3), | ||
131| 0| "this assert should not be reached" | ||
132| | ); | ||
133| 0|} | ||
134| | | ||
135| |impl std::fmt::Debug for Foo { | ||
136| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
137| 7| write!(f, "try and succeed")?; | ||
^0 | ||
138| 7| Ok(()) | ||
139| 7| } | ||
140| |} | ||
141| | | ||
142| |static mut DEBUG_LEVEL_ENABLED: bool = false; | ||
143| | | ||
144| |macro_rules! debug { | ||
145| | ($($arg:tt)+) => ( | ||
146| | if unsafe { DEBUG_LEVEL_ENABLED } { | ||
147| | println!($($arg)+); | ||
148| | } | ||
149| | ); | ||
150| |} | ||
151| | | ||
152| 1|fn test1() { | ||
153| 1| debug!("debug is enabled"); | ||
^0 | ||
154| 1| debug!("debug is enabled"); | ||
^0 | ||
155| 1| let _ = 0; | ||
156| 1| debug!("debug is enabled"); | ||
^0 | ||
157| 1| unsafe { | ||
158| 1| DEBUG_LEVEL_ENABLED = true; | ||
159| 1| } | ||
160| 1| debug!("debug is enabled"); | ||
161| 1|} | ||
162| | | ||
163| |macro_rules! call_debug { | ||
164| | ($($arg:tt)+) => ( | ||
165| 1| fn call_print(s: &str) { | ||
166| 1| print!("{}", s); | ||
167| 1| } | ||
168| | | ||
169| | call_print("called from call_debug: "); | ||
170| | debug!($($arg)+); | ||
171| | ); | ||
172| |} | ||
173| | | ||
174| 1|fn test2() { | ||
175| 1| call_debug!("debug is enabled"); | ||
176| 1|} | ||
177| | | ||
178| 1|fn main() { | ||
179| 1| test1(); | ||
180| 1| test2(); | ||
181| 1| test3(); | ||
182| 1|} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.