Skip to content

overflow evaluating the requirement for Recursively-implemented Traits with Additional Parameters #143425

@zheland

Description

@zheland

The current stable trait solver may enter an infinite recursion when recursively-implemented traits with additional implementation parameters used without full type annotations (with type inference).

Compilation success depends on the compilation cache (see fn1 comments).
This issue is resolved in next-generation trait solver (RUSTFLAGS="-Znext-solver").

Code

pub trait Trait<T> { type Ty; // Error remains for `fn get() -> Result<T, Self::Ty>`. // Error remains for `fn get(&self) -> (T, Self::Ty);`. fn get() -> (T, Self::Ty); } // Error remains for `impl<C, T, A> Trait<&'static T>> for C` // Error remains for `impl<C, T, A> Trait<Box<T>> for C` // Error remains for `impl<C, T, A> Trait<Option<T>> for C` // Error remains for `impl<C, T, E, A> Trait<Result<T, E>> for C` impl<C, T, A> Trait<(T,)> for C where C: Trait<T, Ty = A>, { // Removing `A` impl argument and using `type Ty = C::Ty;` fixes the error. type Ty = A; fn get() -> ((T,), Self::Ty) { todo!() } } struct Type; // Error remains when using other primitive types instead of `u8`. impl Trait<u8> for Type { type Ty = (); fn get() -> (u8, Self::Ty) { todo!() } } // Uncommenting the function below fixes the compilation of `fn2`. // Compilation is fixed only if `fn1` is located before `fn2`. // Commenting it back doesn't break the compilation of `fn2` back. // Using `cargo clean` with commented `fn1` will break the compilation back. // fn fn1() { // let res: ((u8,), ()) = Type::get(); // } // This fails to compile. fn fn2() { let res: ((u8,), ()) = <Type as Trait<(_,)>>::get(); } // This succeeds to compile. fn fn3() { // Fully-specified trait arguments fixes the issue. let res: ((u8,), ()) = <Type as Trait<(u8,)>>::get(); }

Checked with: cargo check
Expected: success
Result:

error[E0275]: overflow evaluating the requirement `Type: Trait<(_,)>` --> src/lib.rs:43:28 | 43 | let res: ((u8,), ()) = <Type as Trait<(_,)>>::get(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`test_lib2`) note: required for `Type` to implement `Trait<((_,),)>` --> src/lib.rs:12:15 | 12 | impl<C, T, A> Trait<(T,)> for C | ^^^^^^^^^^^ ^ 13 | where 14 | C: Trait<T, Ty = A>, | ------ unsatisfied trait bound introduced here = note: 127 redundant requirements hidden = note: required for `Type` to implement `Trait<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((_,),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),),)>` 

Meta

Affected Rust versions:

  • 1.31.0 - reproducible.
  • Stable (rustc 1.88.0 (6b00bc388 2025-06-23)) - reproducible.
  • Beta (rustc 1.89.0-beta.3 (b5e10d8c0 2025-07-02))- reproducible.
  • Nightly (rustc 1.90.0-nightly (da58c0513 2025-07-03)) - reproducible.
$ rustc --version --verbose rustc 1.88.0 (6b00bc388 2025-06-23) binary: rustc commit-hash: 6b00bc3880198600130e1cf62b8f8a93494488cc commit-date: 2025-06-23 host: x86_64-unknown-linux-gnu release: 1.88.0 LLVM version: 20.1.5 

The issue doesn't occur when using RUSTFLAGS="-Znext-solver" cargo +nightly check

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions