Given Base<Foo> and Base<Bar>, is there a way to implement Add such that only Base<Foo> + Base<Bar> and Base<Bar> + Base<Foo> compile? ie. only add if the concrete types are different?
In my case they can be only 2 different types.
Example:
Given
#[derive(Debug)]
struct Base<T> {
n: u32,
_marker: std::marker::PhantomData<T>,
}
trait FooTrait {}
struct FooImpl;
impl FooTrait for FooImpl {}
trait BarTrait {}
struct BarImpl;
impl BarTrait for BarImpl {}
is there a way to implement Add such that
let foo: Base<Foo> = Base::new();
let foo2 = foo.clone();
let bar: Base<Bar> = Base::new();
let bar2: bar.clone();
let foobar = foo + bar;
let foobar = bar2 + foo2;
compiles but
let foo: Base<Foo> = Base::new();
let foo2 = foo.clone();
let bar: Base<Bar> = Base::new();
let bar2: bar.clone();
let foofoo = foo + foo2;
let barbar = bar + bar2;
does not?
I tried
impl<A, B> Add<Base<B>> for Base<A>
where
A: DerivedATrait,
B: DerivedBTrait,
{
type Output = Base<A>;
fn add(self, rhs: Base<B>) -> Base<A> {
Base::new(self.n + rhs.n)
}
}
but it only allows Base<A> + Base<B>, not the other way around, and an additional Add implementation swapping the bounds does not compile.