Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementations conflict when using associated type across crates #51445

Open
bvinc opened this issue Jun 8, 2018 · 4 comments
Open

Implementations conflict when using associated type across crates #51445

bvinc opened this issue Jun 8, 2018 · 4 comments
Labels
A-associated-items Area: Associated items (types, constants & functions) A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@bvinc
Copy link
Contributor

bvinc commented Jun 8, 2018

crate bar:

pub struct Bar;
pub struct BarNext;

pub trait SomeTrait {
        type Next;
}

impl SomeTrait for Bar {
        type Next = BarNext;
}

crate foo:

extern crate bar;

struct Foo;

struct Baz;
struct BazNext;

pub trait MyTrait<T> {
}

impl MyTrait<BazNext> for Foo {
}

// Why does this conflict with the previous impl?  It should resolve to the type BarNext
impl MyTrait<<::bar::Bar as ::bar::SomeTrait>::Next> for Foo {
}

// Using the type BarNext directly does not conflict with the first impl
// impl MyTrait<::bar::BarNext> for Foo {
// }

fn main() {
    println!("Hello, world!");
}

Output:

error[E0119]: conflicting implementations of trait `MyTrait<BazNext>` for type `Foo`:
  --> src/main.rs:15:1
   |
11 | impl MyTrait<BazNext> for Foo {
   | ----------------------------- first implementation here
...
15 | impl MyTrait<<::bar::Bar as ::bar::SomeTrait>::Next> for Foo {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Foo`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0119`.
error: Could not compile `foo`.

I can only reproduce this issue when using the <Bar as SomeTrait>::Next syntax, and only when Bar is in an external crate. Reproduced in current stable and nightly.

@stokhos stokhos added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. A-specialization Area: Trait impl specialization and removed A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. labels Jun 9, 2018
@mtak-
Copy link
Contributor

mtak- commented Oct 4, 2018

The names of the types don't have to be the same, and... when the associated type is not public, there is no workaround AFAICT.

I ran into this while trying to implement Borrow<<back::Backend as hal::Backend>::Buffer> on a wrapper type https://github.com/gfx-rs/gfx. Is this really related to specialization? I think there's no way the two impls could overlap. I did not have the specialization feature flag on, and after turning it on, I still get the same error.

@mredlek
Copy link

mredlek commented Nov 11, 2018

I think the issue here is that <::bar::Bar as ::bar::SomeTrait>::Next is not stable under non-breaking changes. It is possible that bar-1.0 uses type X and bar-1.1 uses a different type Y. If ::foo::Foo already implemented Y, then two implementation exists for the same trait for bar-1.1 (bar-1.0 still compiles fine).

A possible (but not easy) change in the language would be to mark the associated type as stable under non-breaking changes. The type system can then prove that there will be no conflicing implementation under non-breaking changes and can accept the code.

I think the error message this issue generates in unclear. It did cost me a few days to narrow the error down to this issue. A better error message would have helped me here.

@aschampion
Copy link
Contributor

I ran into this, including a completely wrong and unhelpful error, basically where I was impl From<<A as B>::Assoc> for C, and was shown an error about a conflicting impl From<C> for C with std's impl<T> From<T> for T, even though C is not the same as <A as B>::Assoc (how could it be, the crate with A can't even name C!). It was only after tracking down that if A was in the same crate as C this wouldn't happen that I was able to reduce it to this issue.

I don't see how this isn't a bug.

@jonas-schievink jonas-schievink added A-associated-items Area: Associated items (types, constants & functions) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. C-bug Category: This is a bug. and removed A-specialization Area: Trait impl specialization labels Sep 15, 2019
@QuineDot
Copy link

Changing a type in your API is already considered a major breaking change, so I don't think that's a factor. I noted a couple dupes; there was a PR that passed review for #85898, but it ran into some CI problems and got dropped.

Here's another example:

impl<'a> GatLike<'a, String> for Foo {
    type Ref = &'a String;
}

impl<'a> GatLike<'a, <String as Deref>::Target> for Foo {
    type Ref = &'a <String as Deref>::Target;
}

It's quite annoying in a macro context, where now I have to manually supply the normalized types.

Search aids: Associated type projection, normalization.

While I feel this is a bug that should be fixed, the error is also counter-factual, so
@rustbot label: +A-diagnostics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions) A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

8 participants