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