I have a simple wrapper structure with a map method. I also have a hierarchy of error enums where I've implemented From to be able to convert an Error1 to an Error2, allowing the try! macro to automatically convert for me:
struct Span<T>(T);
impl<T> Span<T> {
fn map<F, U>(self, f: F) -> Span<U>
where F: FnOnce(F) -> U
{
Span(f(self.0))
}
}
enum Error1 { One }
enum Error2 { Two }
impl From<Error1> for Error2 {
fn from(v: Error1) -> Error2 { Error2::Two }
}
I'd like to be able to add a From implementation so that I can also automatically convert the insides of the Span structure:
impl<T,U> From<Span<T>> for Span<U>
where U: From<T>
{
fn from(v: Span<T>) -> Span<U> {
v.map(|v| v.into())
}
}
Unfortunately, this fails:
error[E0119]: conflicting implementations of trait `std::convert::From<Span<_>>` for type `Span<_>`:
--> src/main.rs:18:1
|
18 | impl<T,U> From<Span<T>> for Span<U>
| _^ starting here...
19 | | where U: From<T>
20 | | {
21 | | fn from(v: Span<T>) -> Span<U> {
22 | | v.map(|v| v.into())
23 | | }
24 | | }
| |_^ ...ending here
|
= note: conflicting implementation in crate `core`
The error message doesn't point to a specific implementation of From, but my guess is it's this one:
impl<T> From<T> for T
And that my implementation could conflict if my T and U happen to be the same concrete type. Is there any way I can implement my trait for all T and U where T != U?
Unfortunately this is not yet possible and the best approach to this problem has not really been decided yet. One proposal that is slightly relevant to this situation is the idea of negative bounds (specifically equality bounds), but I think it has been deemed too complex. See the latest issue on the subject for more information, where the team members are considering different ideas, including specialization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With