Say you initially have code like this:
struct DeserializeError(String);
trait Deserialize<T> {
fn into_type(self) -> Result<T, DeserializeError>
}
struct Foo {}
impl Deserialize<Foo> for Vec<u8> {
fn into_type(self) -> Result<Foo, DeserializeError> {
unimplemented!() // Vec<u8> -> Foo
}
}
struct Bar {}
impl Deserialize<Bar> for Vec<u8> {
fn into_type(self) -> Result<Bar, DeserializeError> {
unimplemented!() // Vec<u8> -> Bar
}
}
and later down the road, you need to write a generic implementation of Deserialize
that requires the use of Deserialize<Foo>
, Deserialize<Bar>
, and whatever other implementations exist in your code base.
The problem I encountered was when I initially tried to do the following:
struct Wrapper<T> { foo: Foo, t: T }
// first 4 bytes are Foo, the rest will make up T
impl<T> Deserialize<Wrapper<T>> for Vec<u8> {
fn into_type(self) -> Result<Wrapper<T>, DeserializeError> {
self[0..=3].to_vec().into_type().and_then(|foo: Foo| {
self[4..].to_vec().into_type().map(|some_t: T| {
Wrapper { foo, t: some_t }
})
})
}
}
Unfortunately, you'll get the following error:
| self[4..].to_vec().into_type().map(|some_t: T| {
| ^^^^^^^^^^^^^^^^^^ the trait `Deserialize<T>` is not implemented for `std::vec::Vec<u8>`
The compiler wonderfully suggested the following advice though:
consider adding a `where std::vec::Vec<u8>: Deserialize<T>` bound
Ok, so let's try that:
impl<T> Deserialize<Wrapper<T>> for Vec<u8>
where Vec<u8>: Deserialize<T> {
fn into_type(self) -> Result<Wrapper<T>, DeserializeError> {
self[0..=3].to_vec().into_type().and_then(|foo: Foo| {
self[4..].to_vec().into_type().map(|some_t: T| {
Wrapper { foo, t: some_t }
})
})
}
}
But now we get the following compiler error:
= note: expected type `Foo`
found type `T`
Why? Because the where
bound has stated that Vec<u8>
in this scope must implement Deserialize<T>
, and based on my best guess, has explicitly enforced only that implementation into scope as well. So my problem is that although I don't have conflicting implementations of the trait for Vec<u8>
, I had conflicting use of the trait.