Let f
be a symmetric function of 2 variables.
Let's say I define an associated trait, F
, to mark f
-implementors:
trait F<T> {
fn f(&self, other: T);
}
Now, since f
is symmetric, I'd like to have the following blanket impl:
impl<T0, T1> F<T1> for T0 where T1: F<T0> {
fn f(&self, other: &T1) {
other.f(self)
}
}
Obviously I can't do that because then coherence prevents any concrete impl of F
.
So instead I define a trait converse to F:
trait ConF<T> where Self: Sized, T: F<Self> {
fn f(&self, other: &T) {
other.f(self)
}
}
impl<T0, T1> ConF<T1> for T0 where T1: F<T0> {}
Now, consider this playground.
Somehow the compiler fails to resolve the f
calls. But u8
only impl F<u16>
and u16
only impl ConF<u8>
so there is, in fact, no ambiguity.
Resorting to fully qualified syntax is not an option since it defeats the purpose of ConF
.
What's wrong here? Is there a (better) way to achieve the desired symmetry effect?