0

I have 3 crates.

  • trait-def with a trait definition :
    pub trait Test { type Exec; } 
  • under with a first implementation of the trait for a type
 pub struct First; pub struct FirstArgument; impl Test for First { type Exec = FirstArgument; } 
  • over with a second implementation of the trait for another type
 pub struct Second; pub struct SecondArgument; impl Test for Second { type Exec = SecondArgument; } 

Until here, everything is alright. However, when trying to implement a simple From, things go sideways :

impl From<<First as Test>::Exec> for SecondArgument { fn from(value: <First as Test>::Exec) -> Self { Self } } 

It says :

error[E0119]: conflicting implementations of trait `std::convert::From<SecondArgument>` for type `SecondArgument` | 13 | impl From<<First as Test>::Exec> for SecondArgument { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: conflicting implementation in crate `core`: - impl<T> std::convert::From<T> for T; 

This is a very simplified example and I can't just implement From<FirstArgument> for SecondArgument for unrelated reasons.

I know you have to be careful about implementations of From with traits, but here everything is set in stone, I'm not using generic types. Does someone have an answer as to why this is not accepted in Rust ? Thank you !

Edit : I have this repo that illustrates the situation (https://github.com/Kayanski/rust-trait-impl-reproduce)

The over crate reproduces the issue. The both crate which show having everything in the same crate doesn't reproduce the issue.

2 Answers 2

0

Does someone have an answer as to why this is not accepted in Rust ?

Because <First as Test>::Exec could be SecondArgument, at which point you'd be implementing From<SecondArgument> for SecondArgument which conflicts with the blanket From<T> for T implementation.

Sign up to request clarification or add additional context in comments.

4 Comments

That's the thing ! It cannot because SecondArgument is defined in my crate and we can't have circular dependencies, so SecondArgument can't exist inside the first crate. So no this case could not happen
A second thing is I would argue that it's not the case today. If it becomes the case, then that's a breaking change on the upstream library, which is then a breaking change on the downstream library which can trigger errors. But that's maybe off the scope of stack-overflow
It doesn't matter that it's "not the case today" or that it's "a breaking change", Rust requires everything to be consistent and non-overlapping on its own.
Ok thanks, that answers my second comment. However, the first comment still stands. This can't be the case because I defined the 'SecondArgument' in my crate, so the imported crate can't have access to it
0

This is a bug in the compiler. Since all types are known, the compiler should understand that <First as Test>::Exec == FirstArgument != SecondArgument, but it does not. This is issue #37832.

You can fix that by replacing <First as Test>::Exec with FirstArgument.

2 Comments

Oh, this looks old. Any chance of this being allowed in the future ?
@kayanski You can see this bug was reported many times, the oldest I could fine was from 2016. There are older bugs, but yes, this is quite old. I hope it will be fixed eventually, but I can't promise when, especially when there is such easy workaround.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.