Description
#93144 addressed an issue where some uncallable functions could show up in the list of unused functions. The coverage map generator adds coverage regions for unused functions (so coverage reports show these functions are not covered) and generates a function stub required by LLVM, and associates the coverage regions computed from the MIR.
Certain types of functions generate no coverage regions. This only seems to be the case for functions that are never called, so they are always in the unused function list.
#93144 fixed the main issue, so we no longer include those functions in the coverage map, but we are still generating the unused function stub.
What we should do, instead, is: In add_unused_functions()
check if an unused function has counter_regions
, and don't call define_unused_fn()
if there are none.
Then, in the finalize()
loop on the function_coverage_map, we should never see unused functions with no coverage. If we do, that's an error. So we can change the if coverage_mapping_buffer.is_empty()
block to just assert that it is never empty:
assert!(
!coverage_mapping_buffer.is_empty(),
"Every `FunctionCoverage` should have at least one counter"
);
The reason we chose not to do this in #93144 is, computing the counter_regions
variable is a non-trivial process, implemented in the function get_expressions_and_counter_regions()
. We don't want to perform that process more than once per function, and add_unused_functions()
only needs to know if counter_regions would be returned, without actually returning them.
I'd like to work out a clean way to find this out without duplicating too much of the decision logic used to generate that counter_regions
iterator.