Skip to content

Substituting concrete type in associated item binding can violate the trait bounds but emit no error #140649

@moxian

Description

@moxian

I tried this code:

trait Foo {
    fn foo();
}

trait Trait {
    type Assoc: Foo;
}

// compiles as expected
fn stuff_ok<T>() where
  T: Trait
{
    <<T as Trait>::Assoc as Foo>::foo()
}

fn stuff_u8_used<T>() where 
  T: Trait<Assoc = u8>  // no error on this line
{
    // fails to compile even though `Assoc: Foo` as per `Trait` definition
    <<T as Trait>::Assoc as Foo>::foo()
}

fn stuff_u8_empty<T>() where
  // compiles even though `Foo` is not implemented for `u8`
  T: Trait<Assoc = u8>
{
}

I expected to see this happen: I expected rustc to issue a the trait Foo is not implemented for u8 at the Trait<Assoc = u8> span in both stuff_u8_used and stuff_u8_empty where clauses.

Instead, this happened: rustc errors out much later, when I actively rely on the trait bound being there at <T as Trait>::Assoc as Foo.

I couldn't think of a way to coerce rustc into a miscompilation, since I cannot actually construct Trait<Assoc=u8> neccessary to instantiate stuff_u8_empty, but it is very surprising that the mere existence of Trait<Assoc=u8> does not by itself raise an error.

The behaves the same with -Znext-solver

Meta

rustc --version --verbose:

rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-pc-windows-msvc
release: 1.86.0
LLVM version: 19.1.7

@rustbot label: +A-associated-items +T-types

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)C-bugCategory: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions