I'm trying to do something fairly complicated, and I've horrible feeling I'm stumbling into an XY problem. However...
First of all, why does this work:
trait A { }
impl A for f64 { }
// impl A for Vec<f64> { }
trait B { }
impl<T> B for T where T: A { }
impl<T> B for Vec<T> where T: A { }
while as soon as I uncomment line 3 I get error E0119? Couldn't a conflicting implementation be added at any time making this code invalid already? I actually want to implement trait B
in exactly this way, as it happens, and I'm not planning on adding a conflicting implementation. However, I'd really like to understand with this does work, particularly in light of my actual problem, which follows.
So I have callback that will be used to implement B
, and I need to parametrise it to return a T
or Vec<T>
as appropriate. To do this I have been trying to implement a helper trait to interface to the data source; here is a reduced form of what I'm trying to do (here AF64
is one of several sources of f64
data):
trait A {
type R;
fn get(&self) -> Self::R;
fn get_vec(&self) -> Vec<Self::R>;
}
trait C<T: A> {
fn get_it(&T) -> Self;
}
impl<T> C<T> for T::R where T: A {
fn get_it(t: &T) -> Self { t.get() }
}
impl<T> C<T> for Vec<T::R> where T: A {
fn get_it(t: &T) -> Self { t.get_vec() }
}
So I want two implementations of my helper trait C
, one for getting a raw value out of an A
, and one for getting a vector. I could just throw up my hands and get a vector in the scalar case and throw the vector away, but I'd rather not.
The problem is, of course:
error[E0119]: conflicting implementations of trait `C<_>` for type `std::vec::Vec<_>`:
--> test.rs:21:1
|
11 | impl<T> C<T> for T::R where T: A {
| -------------------------------- first implementation here
...
15 | impl<T> C<T> for Vec<T::R> where T: A {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::vec::Vec<_>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
Ach. I've got a lot of freedom about how to structure this, but I'm going to have a lot of instances of trait A
, with several different implementations for each R
.
I'm digging myself into a hole here, I'd be grateful for a bit of guidance about what is and isn't actually possible with traits, and whether what I'm doing is actually completely misguided...
Edit: Removed unnecessary impl
for A
from second part.