rust-lang / rust-lang/rust

Failure to match identical `impl Trait` type signatures when using redundant trait bounds

Open
#154,868 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-impl-trait A-type-system C-bug T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I came across this while working on some more complex trait systems. Here is a minimal code example:

trait Trait {}

trait Foo {
    fn foo() -> impl Trait;
}

impl Trait for () {}
fn bar() -> impl Trait { () }

impl<T> Foo for T where T: Foo {
    fn foo() -> impl Trait {
        bar()
    }
}

This should logically compile, but instead produces this nonsensical type error diagnostic:

error[E0053]: method `foo` has an incompatible type for trait
  --> src\min_bug.rs:13:17
   |
13 |     fn foo() -> impl Trait {
   |                 ^^^^^^^^^^ expected associated type, found opaque type
   |
note: type in trait
  --> src\min_bug.rs:6:17
   |
 6 |     fn foo() -> impl Trait;
   |                 ^^^^^^^^^^
   = note: expected signature `fn() -> impl Trait`
              found signature `fn() -> impl Trait`

Note that this error disappears when the where T: Foo bound is removed, even though the bound is redundant since T is already implementing Foo in the same block. This kind of redundant bound is accepted in other contexts. Even if an error here is intended behavior, the error message is unhelpful to a problematic degree.

For clarification, the use case for this kind of of bound is for a circular trait bound relationship, and also occurs for the bound where T: Baz given trait Baz: Foo {}. This has been useful in my project to allow trait resolution to point out problems with blanket impls at the source and to enable less complex trait bounds elsewhere.

Meta

Experienced on latest stable and nightly, plus earlier stable 1.92.

rustc --version --verbose:

rustc 1.94.1 (e408947bf 2026-03-25)
binary: rustc
commit-hash: e408947bfd200af42db322daf0fadfe7e26d3bd1
commit-date: 2026-03-25
host: x86_64-pc-windows-gnu
release: 1.94.1
LLVM version: 21.1.8
rustc 1.96.0-nightly (9602bda1d 2026-04-05)
binary: rustc
commit-hash: 9602bda1dd0c1bbf5787e398385bbac81fd532f8
commit-date: 2026-04-05
host: x86_64-pc-windows-gnu
release: 1.96.0-nightly
LLVM version: 22.1.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the minimal example in src\min_bug.rs with the stable and nightly rustc versions listed in the report, focusing on the redundant where T: Foo bound. Trace the compiler's handling of the trait method signatures and opaque types. Done means either the example compiles as expected or the diagnostic clearly explains the intended restriction.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.