-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Description
I tried this code: rustc -g non_recursive.rs
struct Wrap<T>(T);
enum NonRecursive<T> {
A(*const NonRecursive<Wrap<()>>),
B(T),
}
fn main() {
let _ = std::hint::black_box(NonRecursive::B(()));
}
I expected to see this happen: No expanding recursion detected and debuginfo is complete.
Instead, this happened: NonRecurse<()>
is detected as expanding recursive. NonRecurse<Wrap<()>>
has no debuginfo for members.
Meta
rustc --version --verbose
:
rustc 1.91.0-dev
binary: rustc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.91.0-dev
LLVM version: 21.1.0
Analysis
The expanding recursion check I introduced in #138599 and #145297 is fundamentally flawed.
The idea is that if we see an expanding generic parameter in traversal, then we conclude the type is expanding recursive.
E.g.
enum Recursive<T> {
Rec(*const Recursive<Wrap<T>>),
Item(T),
}
If we starts with Recursive<T>
, then we'll visit the following types:
Recurse<T>
*const Recursive<Wrap<T>>
Recursive<Wrap<T>>
// the generic parameter gets an additional depth.
The problem is that we're working with instantiated types in debug info generation.
There we can't distinguish generic parameters from concrete types.
E.g. for the false positive code, we'll visit the following types:
NonRecursive<()>
*const NonRecursive<Wrap<()>>
NonRecursive<Wrap<()>>
// detected but shouldn't.
Maybe the check should be changed into plain old recursion limit.