Skip to content

Conflicting implementations error despite bound preventing conflict #90587

Open
@dhardy

Description

@dhardy

The following fails:

trait A {
    type C;
}

trait B<M>: A {}

impl<T: A, M: Into<T::C>> B<M> for T {}
// equivalent; also errors:
// impl<C, T: A<C=C>, M: Into<C>> B<M> for T {}

struct S {}

impl A for S {
    type C = u32;
}

// error[E0119]: conflicting implementations of trait `B<()>` for type `S`
impl B<()> for S {}

Note that due to the bounds such a conflict is impossible unless (): Into<u32>, which cannot happen...

... actually, this may simply be the compiler giving a lot of leeway for additional implementations in std.

... replacing u32 and/or () with local private types does not change the error:

struct X;
struct Y;

trait A {
    type C;
}

trait B<M>: A {}

impl<T: A, M: Into<T::C>> B<M> for T {}

struct S {}

impl A for S {
    type C = X;
}
impl B<Y> for S {}

Introducing a local Into trait slightly changes the error:

trait Into<Y> {}

// ...

This version has the same error but now includes an (incorrect) explanation:

note: downstream crates may implement trait Into<_> for type ()

Variant

Here's a variant:

trait A<C> {}

trait B<C, M>: A<C> {}

impl<C, T: A<C>, M: Into<C>> B<C, M> for T {}

struct S {}

impl A<u32> for S {}

impl B<u32, ()> for S {}

This results in the same error, except that:

  • there is a valid explanation:

    note: upstream crates may add a new impl of trait std::convert::From<()> for type u32 in future versions

  • introducing a local private trait Into<Y> {} fixes it

  • introducing a local private type to replace u32 or () fixes it

Meta

rustc versions tested ``` rustc 1.56.1 (59eed8a 2021-11-01)

rustc 1.58.0-nightly (db062de 2021-11-01)
binary: rustc
commit-hash: db062de
commit-date: 2021-11-01
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0

</details>

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coherenceArea: CoherenceA-trait-systemArea: Trait systemC-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