Commit Graph

261 Commits

Author SHA1 Message Date
Zalathar
412c86cf03 coverage: When merging spans, keep prev and merge curr into it
Swapping the direction of this merge produces the same results, but means that
we never need to mutate `curr`.
2024-02-13 21:01:17 +11:00
Michael Goulet
cb024ba6e3 is_closure_like 2024-02-11 22:09:52 +00:00
Guillaume Boisseau
d62fd21215
Rollup merge of #120564 - Zalathar:increment-site, r=oli-obk
coverage: Split out counter increment sites from BCB node/edge counters

This makes it possible for two nodes/edges in the coverage graph to share the same counter, without causing the instrumentor to inject unwanted duplicate counter-increment statements.

---

````@rustbot```` label +A-code-coverage
2024-02-07 18:24:43 +01:00
Michael Goulet
a82bae2172 Teach typeck/borrowck/solvers how to deal with async closures 2024-02-06 02:22:58 +00:00
Zalathar
a246b6be1d coverage: Make fn_sig_span optional, and note its quirks 2024-02-05 10:09:50 +11:00
Zalathar
fde1702db8 coverage: Hoist special handling of async function spans
This sidesteps the normal span refinement code in cases where we know that we
are only dealing with the special signature span that represents having called
an async function.
2024-02-05 10:09:50 +11:00
Zalathar
dd6d7f27e4 coverage: Make unexpansion of closure bodies more precise
This improves the coverage instrumentation of closures declared in macros, as
seen in `closure_macro.rs` and `closure_macro_async.rs`.
2024-02-05 10:09:46 +11:00
Zalathar
2e212b79e0 coverage: Split out counter increment sites from BCB node/edge counters
This makes it possible for two nodes/edges in the coverage graph to share the
same counter, without causing the instrumentor to inject unwanted duplicate
counter-increment statements.
2024-02-02 10:50:05 +11:00
Vadim Petrochenkov
667d5d325f hir: Add non-optional hir_owner_nodes for real OwnerIds 2024-01-30 15:00:52 +03:00
Vadim Petrochenkov
64b6b5b6ce hir: Simplify hir_owner_nodes query
The query accept arbitrary DefIds, not just owner DefIds.
The return can be an `Option` because if there are no nodes, then it doesn't matter whether it's due to NonOwner or Phantom.
Also rename the query to `opt_hir_owner_nodes`.
2024-01-30 15:00:52 +03:00
Matthias Krüger
72b70ec474
Rollup merge of #120292 - Zalathar:dismantle, r=oli-obk
coverage: Dismantle `Instrumentor` and flatten span refinement

This is a combination of two refactorings that are unrelated, but would otherwise have a merge conflict.

No functional changes, other than a small tweak to debug logging as part of rearranging some functions.

Ignoring whitespace is highly recommended, since most of the modified lines have just been reindented.

---

The first change is to dismantle `Instrumentor` into ordinary functions.

This is one of those cases where encapsulating several values into a struct ultimately hurts more than it helps. With everything stored as local variables in one main function, and passed explicitly into helper functions, it's easier to see what is used where, and make changes as necessary.

---

The second change is to flatten the functions for extracting/refining coverage spans.

Consolidating this code into flatter functions reduces the amount of pointer-chasing required to read and modify it.
2024-01-25 08:39:43 +01:00
León Orell Valerian Liehr
8bd126cb18
Rollup merge of #120185 - Zalathar:auto-derived, r=wesleywiser
coverage: Don't instrument `#[automatically_derived]` functions

This PR makes the coverage instrumentor detect and skip functions that have [`#[automatically_derived]`](https://doc.rust-lang.org/reference/attributes/derive.html#the-automatically_derived-attribute) on their enclosing impl block.

Most notably, this means that methods generated by built-in derives (e.g. `Clone`, `Debug`, `PartialEq`) are now ignored by coverage instrumentation, and won't appear as executed or not-executed in coverage reports.

This is a noticeable change in user-visible behaviour, but overall I think it's a net improvement. For example, we've had a few user requests for this sort of change (e.g. #105055, https://github.com/rust-lang/rust/issues/84605#issuecomment-1902069040), and I believe it's the behaviour that most users will expect/prefer by default.

It's possible to imagine situations where users would want to instrument these derived implementations, but I think it's OK to treat that as an opportunity to consider adding more fine-grained option flags to control the details of coverage instrumentation, while leaving this new behaviour as the default.

(Also note that while `-Cinstrument-coverage` is a stable feature, the exact details of coverage instrumentation are allowed to change. So we *can* make this change; the main question is whether we *should*.)

Fixes #105055.
2024-01-24 15:43:12 +01:00
León Orell Valerian Liehr
5a38754d23
Rollup merge of #119460 - Zalathar:improper-region, r=wesleywiser
coverage: Never emit improperly-ordered coverage regions

If we emit a coverage region that is improperly ordered (end < start), `llvm-cov` will fail with `coveragemap_error::malformed`, which is inconvenient for users and also very hard to debug.

Ideally we would fix the root causes of these situations, but they tend to occur in very obscure edge-case scenarios (often involving nested macros), and we don't always have a good MCVE to work from. So it makes sense to also have a catch-all check that will prevent improperly-ordered regions from ever being emitted.

---

This is mainly aimed at resolving #119453. We don't have a specific way to reproduce it, which is why I haven't been able to add a test case in this PR. But based on the information provided in that issue, this change seems likely to avoid the error in `llvm-cov`.

`````@rustbot````` label +A-code-coverage
2024-01-24 15:43:11 +01:00
Zalathar
572d7e9e69 coverage: Flatten the functions for extracting/refining coverage spans
Consolidating this code into flatter functions reduces the amount of
pointer-chasing required to read and modify it.
2024-01-24 16:59:52 +11:00
Zalathar
83ef18cd6c coverage: Dismantle Instrumentor into ordinary functions 2024-01-24 13:19:56 +11:00
Wesley Wiser
21e5beae3c
Use debug_assert instead of expanded equivalent 2024-01-22 10:10:00 -06:00
Zalathar
41dcba805d coverage: Don't instrument #[automatically_derived] functions 2024-01-22 12:18:57 +11:00
Zalathar
5eae9452b6 coverage: Simplify computing successors in the BCB graph 2024-01-14 12:11:26 +11:00
Zalathar
867950f8c6 coverage: Move helper add_basic_coverage_block into a local closure
This also switches from `split_off(0)` to `std::mem::take` when emptying the
accumulated list of blocks, because `split_off(0)` handles capacity in a way
that is unintuitive when used in a loop.
2024-01-14 12:11:25 +11:00
Zalathar
229d0983b5 coverage: Simplify the loop that combines blocks into BCBs
The old loop had two separate places where it would flush the acumulated list
of straight-line blocks into a new BCB. One occurred at the start of the loop
body when the current block couldn't be chained into, and the other occurred at
the end of the loop body when the current block couldn't be chained from.

The latter check can be hoisted to the start of the loop body by making it
examine the previous block (which has added itself to the list) instead of the
current block. With that done, we can combine the two separate flushes into one
flush with two possible trigger conditions.
2024-01-14 12:11:25 +11:00
Zalathar
c412cd4bc2 coverage: Indicate whether a block's successors allow BCB chaining 2024-01-14 12:11:25 +11:00
Zalathar
6d1c396399 coverage: Determine a block's successors from just the terminator
Filtering out unreachable successors is only needed by the main graph traversal
loop, so we can move the filtering step into that loop instead, eliminating the
need to pass the MIR body into `bcb_filtered_successors`.
2024-01-14 12:11:25 +11:00
Zalathar
124fff0777 coverage: Add enums to accommodate other kinds of coverage mappings 2024-01-11 16:43:12 +11:00
Zalathar
c5932182ad coverage: Store extracted spans as a flat list of mappings
This is less elegant in some ways, since we no longer visit a BCB's spans as a
batch, but will make it much easier to add support for other kinds of coverage
mapping regions (e.g. branch regions or gap regions).
2024-01-11 16:43:01 +11:00
Zalathar
8f98b54a7e coverage: Extract helper function term_for_bcb 2024-01-11 16:07:38 +11:00
Zalathar
b152de29c5 coverage: Discard code regions that might cause fatal errors in llvm-cov 2024-01-10 11:01:45 +11:00
Zalathar
6971e9332d coverage: llvm-cov expects column numbers to be bytes, not code points 2024-01-08 21:58:46 +11:00
Zalathar
88f5759ace coverage: Allow make_code_region to fail 2024-01-08 21:43:22 +11:00
Zalathar
514e026853 coverage: Make the remaining fields of CoverageSpan non-public
The struct itself is already non-public, so having public fields doesn't
achieve anything.
2024-01-05 12:53:23 +11:00
Zalathar
cd5084388a coverage: Split out SpanFromMir from CoverageSpan
This draws a clear distinction between the fields/methods that are needed by
initial span extraction and preprocessing, and those that are needed by the
main "refinement" loop.
2024-01-05 12:53:23 +11:00
Zalathar
d4d2f1428c coverage: Hoist the splitting of visible macro invocations 2024-01-05 12:53:23 +11:00
Zalathar
cd3a9760e4 coverage: Hoist the removal of unwanted macro expansion spans 2024-01-05 12:53:23 +11:00
Zalathar
df0df5256b coverage: Overhaul how "visible macros" are determined 2024-01-05 12:53:23 +11:00
Zalathar
506b9f9689 coverage: Avoid early returns from mir_to_initial_sorted_coverage_spans 2024-01-05 12:53:23 +11:00
León Orell Valerian Liehr
3053ced813
Rollup merge of #119444 - compiler-errors:closure-or-coroutine, r=oli-obk
Rename `TyCtxt::is_closure` to `TyCtxt::is_closure_or_coroutine`

This function has always been used to test whether the def-id was a closure **or** coroutine: https://github.com/rust-lang/rust/pull/118311/files#diff-69ebec59f7d38331dd1be84ede7957977dcaa39e30ed2869b04aa8c99b2079ccR552 -- the name is just confusing because it disagrees with other fns named `is_closure`, like `Ty::is_closure`.

So let's rename it.
2024-01-03 16:08:26 +01:00
Michael Goulet
07adee7072 is_coroutine -> is_coroutine_or_closure 2023-12-30 15:24:15 +00:00
Zalathar
3f67118ae7 coverage: Make coverage_counters a local variable
This avoids the awkwardness of having to create it in the pass's constructor,
and then mutate it later to actually create the counters.
2023-12-30 22:36:11 +11:00
Zalathar
e1a2babc06 coverage: Prepare mappings separately from injecting statements
These two tasks historically needed to be interleaved, but after various recent
changes (including #116046 and #116917) they can now be fully separated.
2023-12-30 22:34:15 +11:00
Zalathar
8529b63e2b coverage: Avoid a possible query stability hazard in CoverageCounters
The iteration order of this hashmap can potentially affect the relative
creation order of MIR blocks.
2023-12-29 12:33:52 +11:00
Michael Goulet
fcb42b42d6 Remove movability from TyKind::Coroutine 2023-12-28 16:35:01 +00:00
Zalathar
be6b059169 coverage: Unexpand spans with find_ancestor_inside_same_ctxt 2023-12-27 23:49:31 +11:00
Zalathar
cf6dc7adb3 coverage: Check for async fn explicitly, without needing a heuristic
The old code used a heuristic to detect async functions and adjust their
coverage spans to produce better output. But there's no need to resort to a
heuristic when we can just check whether the current function is actually an
`async fn`.
2023-12-20 18:48:04 +11:00
Zalathar
2a0290a802 coverage: Pass around &ExtractedHirInfo instead of individual fields
This reduces the risk of mixing up `fn_source_span` and `body_span`, and makes
it easier to pass along additional fields as needed.
2023-12-20 18:48:04 +11:00
Zalathar
dfa6441354 coverage: Skip instrumenting a function if no spans were extracted 2023-12-16 11:10:10 +11:00
Zalathar
684b9ea408 coverage: Check that the function signature span precedes the body
This will normally be true, but in cases where it's not true we're better off
not making any assumptions about the signature.
2023-12-15 10:59:32 +11:00
Zalathar
3b610c764d coverage: Compare span source files without involving Lrc<SourceFile>
If we want to know whether two byte positions are in the same file, we don't
need to clone and compare `Lrc<SourceFile>`; we can just get their indices and
compare those instead.
2023-12-15 10:59:32 +11:00
Zalathar
7de2156bfd coverage: Inline and simplify fn_sig_and_body 2023-12-15 10:59:32 +11:00
Zalathar
e2f449bcc9 coverage: Use LocalDefId in extract_hir_info 2023-12-15 10:59:32 +11:00
Zalathar
b9955fb340 coverage: Extract helper for getting HIR info for coverage 2023-12-15 10:59:32 +11:00
Zalathar
bf424c28d2 coverage: Don't bother storing the source file in Instrumentor
We can just as easily look it up again from the source map and body span when
needed.
2023-12-15 10:59:32 +11:00