diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-07-19 08:55:34 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-19 08:55:34 +0200 |
| commit | 3b4d79c949ec707ca477053392167e6f0d24e0dd (patch) | |
| tree | a648cab69a398118f63e688adca2c58540454589 /compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp | |
| parent | 44ee51de0b053a3cd56db91982e95eb0c8f3132e (diff) | |
| parent | 3b9c16bc0e90e57ed4ff548a50a577ea4dd7a50c (diff) | |
| download | rust-3b4d79c949ec707ca477053392167e6f0d24e0dd.tar.gz rust-3b4d79c949ec707ca477053392167e6f0d24e0dd.zip | |
Rollup merge of #143704 - compiler-errors:cycle-exotic, r=cjgillot
Be a bit more careful around exotic cycles in in the inliner
Copied from the comment here: https://github.com/rust-lang/rust/issues/143700#issuecomment-3053810353
---
```rust
#![feature(fn_traits)]
#[inline]
pub fn a() {
FnOnce::call_once(a, ());
FnOnce::call_once(b, ());
}
#[inline]
pub fn b() {
FnOnce::call_once(b, ());
FnOnce::call_once(a, ());
}
```
This should demonstrate the issue. For ease of discussion, I'm gonna call the two fn-def types `{a}` and `{b}`.
When collecting the cyclic local callees in `mir_callgraph_cyclic` for `a`, we first check the first call terminator in `a`. We end up calling process on `<{a} as FnOnce>::call_once`, which ends up visiting `a`'s instance again. This is cyclical. However, we don't end up marking `FnOnce::call_once` as a cyclical def id because it's a foreign item. That's fine.
When visiting the second call terminator in `a`, which is `<{b} as FnOnce>::call_once`, we end up recursing into `b`. We check the first terminator, which is `<{b} as FnOnce>::call_once`, but although that is its own mini cycle, it doesn't consider itself a cycle for the purpose of this query because it doesn't involve the *root*. However, when we visit the *second* terminator in `b`, which is `<{a} as FnOnce>::call_once`, we end up **erroneously** *not* considering that call to be cyclical since we've already inserted it into our set of seen instances, and as a consequence we don't recurse into it. This means that we never collect `b` as recursive.
Do this in the flipped case too, and we end up having two functions which mututally do not consider each other to be recursive participants. This leads to a query cycle.
---
I ended up also renaming some variables so I could more clearly understand their responsibilities in this code. Let me know if the renames are not welcome.
Fixes https://github.com/rust-lang/rust/issues/143700
r? `@cjgillot`
Diffstat (limited to 'compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp')
0 files changed, 0 insertions, 0 deletions
