user1935361
user1935361

Reputation: 442

Blanket implementation of core traits constrained by locally-defined public trait

I have the following code:

pub trait GetIdentifier {
    //...
}
impl<T: GetIdentifier> Hash for T {
     fn hash(&self) -> //....
}

I get the following error:

error[E0119]: conflicting implementations of trait `std::hash::Hash` for type `&_`:
  --> <anon>:18:1
   |
18 | / impl<T: GetIdentifier> Hash for T {
19 | | }
   | |_^
   |
   = note: conflicting implementation in crate `core`

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
  --> <anon>:18:1
   |
18 | / impl<T: GetIdentifier> Hash for T {
19 | | }
   | |_^

Why? I haven't implemented GetIdentifier for &_, so the blanket impl shouldn't apply to &_. Consumers of my crate wouldn't be able to implement GetIdentifier for core types either, so no problem there. What am I missing here? Why is &_ even involved here -- I didn't put an ?Sized bound on my trait so references shouldn't even be considered....right?

Upvotes: 1

Views: 366

Answers (1)

oli_obk
oli_obk

Reputation: 31163

Consumers of your crate might implement GetIdentifier for TheirType and simultaneously implement Hash for TheirType.

Now you might say that's their problem, but imagine another crate with a trait Foo that also does impl<T: Foo> Hash for T {}, and TheirType implementing Foo and GetIdentifier. Suddenly they can't implement either trait.

The reason the error occurs for &_ is that the stdlib impl says any type T implementing Hash causes &T to also implement Hash.

Upvotes: 1

Related Questions