Skip to content

Hang in trait solver with mutually recursive trait bounds #150532

@trait-Cong

Description

@trait-Cong

I tried this code:

// Minimal reproduction of a trait solver hang with generics

trait MyTrait<T> {}
struct Foo;
struct Bar;

// Cycle: Foo<T> requires Bar<T>
impl<T> MyTrait<T> for Foo
where 
    Foo: MyTrait<T>, 
    Bar: MyTrait<T> 
{}

// Cycle: Bar<T> requires Foo<T>
impl<T> MyTrait<T> for Bar
where 
    Foo: MyTrait<T> 
{}

fn trigger<T>(_: impl MyTrait<T>) {}

fn main() {
    // This triggers the infinite loop. 
    // The unconstrained generic T seems to prevent the recursion limit from catching the cycle.
    trigger(Bar);
}

I expected to see this happen: The compiler should detect the cyclic dependency or hit the recursion limit, resulting in a compilation error (e.g., error: overflow evaluating the requirement).

Instead, this happened: The compiler hangs indefinitely (tested for > 5 minutes) ,indicating an infinite loop in the trait solver (likely struggling with the generic inference in the recursive bounds).

Meta

rustc --version --verbose:

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-pc-windows-msvc
release: 1.92.0
LLVM version: 21.1.3
Backtrace

N/A (The compiler hangs indefinitely, so no panic backtrace is produced.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-hangIssue: The compiler never terminates, due to infinite loops, deadlock, livelock, etc.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions