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#118666 - Zalathar:body-closure, r=cjgillot
coverage: Simplify the heuristic for ignoring `async fn` return spans The code for extracting coverage spans from MIR has a special heuristic for dealing with `async fn`, so that the function's closing brace does not have a confusing double count. The code implementing that heuristic is currently mixed in with the code for flushing remaining spans after the main refinement loop, making the refinement code harder to understand. We can solve that by hoisting the heuristic to an earlier stage, after the spans have been extracted and sorted but before they have been processed by the refinement loop. The coverage tests verify that the heuristic is still effective, so coverage mappings/reports for `async fn` have not changed. --- This PR also has the side-effect of fixing the `None some_prev` panic that started appearing after rust-lang#118525. The old code assumed that `prev` would always be present after the refinement loop. That was only true if the list of collected spans was non-empty, but prior to rust-lang#118525 that didn't seem to come up in practice. After that change, the list of collected spans could be empty in some specific circumstances, leading to panics. The new code uses an `if let` to inspect `prev`, which correctly does nothing if there is no span present.
- Loading branch information
Showing
5 changed files
with
93 additions
and
31 deletions.
There are no files selected for viewing
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
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,8 @@ | ||
Function name: no_spans::affected_function::{closure#0} | ||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 1b, 0c, 00, 0e] | ||
Number of files: 1 | ||
- file 0 => global file 1 | ||
Number of expressions: 0 | ||
Number of file 0 mappings: 1 | ||
- Code(Counter(0)) at (prev + 27, 12) to (start + 0, 14) | ||
|
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,30 @@ | ||
LL| |#![feature(coverage_attribute)] | ||
LL| |// edition: 2021 | ||
LL| | | ||
LL| |// If the span extractor can't find any relevant spans for a function, the | ||
LL| |// refinement loop will terminate with nothing in its `prev` slot. If the | ||
LL| |// subsequent code tries to unwrap `prev`, it will panic. | ||
LL| |// | ||
LL| |// This scenario became more likely after #118525 started discarding spans that | ||
LL| |// can't be un-expanded back to within the function body. | ||
LL| |// | ||
LL| |// Regression test for "invalid attempt to unwrap a None some_prev", as seen | ||
LL| |// in issues such as #118643 and #118662. | ||
LL| | | ||
LL| |#[coverage(off)] | ||
LL| |fn main() { | ||
LL| | affected_function()(); | ||
LL| |} | ||
LL| | | ||
LL| |macro_rules! macro_that_defines_a_function { | ||
LL| | (fn $name:ident () $body:tt) => { | ||
LL| | fn $name () -> impl Fn() $body | ||
LL| | } | ||
LL| |} | ||
LL| | | ||
LL| |macro_that_defines_a_function! { | ||
LL| | fn affected_function() { | ||
LL| 1| || () | ||
LL| | } | ||
LL| |} | ||
|
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,29 @@ | ||
#![feature(coverage_attribute)] | ||
// edition: 2021 | ||
|
||
// If the span extractor can't find any relevant spans for a function, the | ||
// refinement loop will terminate with nothing in its `prev` slot. If the | ||
// subsequent code tries to unwrap `prev`, it will panic. | ||
// | ||
// This scenario became more likely after #118525 started discarding spans that | ||
// can't be un-expanded back to within the function body. | ||
// | ||
// Regression test for "invalid attempt to unwrap a None some_prev", as seen | ||
// in issues such as #118643 and #118662. | ||
|
||
#[coverage(off)] | ||
fn main() { | ||
affected_function()(); | ||
} | ||
|
||
macro_rules! macro_that_defines_a_function { | ||
(fn $name:ident () $body:tt) => { | ||
fn $name () -> impl Fn() $body | ||
} | ||
} | ||
|
||
macro_that_defines_a_function! { | ||
fn affected_function() { | ||
|| () | ||
} | ||
} |