MIR InstrumentCoverage: Improve coverage of #[should_panic]
tests and catch_unwind()
handlers
#78544
Labels
A-code-coverage
Area: Source-based code coverage (-Cinstrument-coverage)
A-MIR
Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
At present, the MIR
InstrumentCoverage
pass omits unwind paths when computing coverage spans and injecting counters because (1) statements executed during an unwind are generally compiler-generated, so they don't have source code to "cover"; and (2) in normal runtime execution, unwind paths are generally called when an unexpected and/or unhandled error is encountered.Unexpected errors can (and probably should) be corrected before addressing coverage errors.
Some exceptions to this are: (1) tests that include testing for known
panic
situations, for instance, unit tests annotated with the#[should_panic]
attribute; and (2) code that leverages acatch_unwind()
handler.Since coverage analysis is commonly used to validate that test cases execute all source code, and
#[should_panic]
tests might be included among the test cases,InstrumentCoverage
could be improved to provide a more accurate representation of coverage when aCall
unwinds.Specifically, non-branching
Statement
s andTerminator
s that follow aTerminatorKind::Call
(if not otherTerminatorKind
s) are counted as having been "executed" by the same counter that counts the execution of theCall
, as well as the non-branching statements that preceded theCall
.But if the
Call
panics, non-branching statements leading up to theCall
will have been executed, and statements following theCall
will not be executed. With only one counter, both sets of statements (before and after, and theCall
itself will have the same execution count (either 1 or 0, depending on the type of counter, and where the counter is incremented).To accurately count these sequences with the potential for panics, an actual code counter needs to be incremented after each successful call.
Adding these counters will increase the physical size of the binaries and slow down execution, so this is a feature that should only be enabled as an option.
One question is, how can this option be enabled granularly?
For
#[should_panic]
tests, it makes sense to enable the option for the test function, but this would not correct the counters for panicking calls in functions called by the test function. It may be possible to trace the calls to enable the option on the functions called by#[should_panic]
test functions, and the functions executed by those functions, but this won't work for functions from external crates.Similar logic could be used for functions called via
catch_unwind()
, with similar limitations.So a worst-case approach would be to enable this feature when compiling the tested crate and all of its dependencies, using a
rustc
compiler flag.The text was updated successfully, but these errors were encountered: