Open
Description
A coworker recently ran into a situation where tuples aren't comparable even when their individual elements are. I was able to boil it down to the following code snippet:
fn main() {
assert_partial_eq::<A, B>();
assert_partial_eq::<C, D>();
assert_partial_eq::<(A, C), (B, D)>();
}
fn assert_partial_eq<A, B>() where A: PartialEq<B> {}
#[derive(Debug, PartialEq)] struct A;
#[derive(Debug, PartialEq)] struct B;
#[derive(Debug, PartialEq)] struct C;
#[derive(Debug, PartialEq)] struct D;
impl PartialEq<A> for B { fn eq(&self, other: &A) -> bool { true } }
impl PartialEq<B> for A { fn eq(&self, other: &B) -> bool { true } }
impl PartialEq<C> for D { fn eq(&self, other: &C) -> bool { true } }
impl PartialEq<D> for C { fn eq(&self, other: &D) -> bool { true } }
I expected the above snippet to compile and run successfully, but the code fails to compile.
Compiling playground v0.0.1 (/playground)
error[[E0277]](https://doc.rust-lang.org/stable/error-index.html#E0277): can't compare `(A, C)` with `(B, D)`
--> src/main.rs:19:25
|
19 | assert_partial_eq::<(A, C), (B, D)>();
| ^^^^^^ no implementation for `(A, C) == (B, D)`
|
= help: the trait `PartialEq<(B, D)>` is not implemented for `(A, C)`
= help: the following other types implement trait `PartialEq<Rhs>`:
()
(A, Z, Y, X, W, V, U, T)
(B, A, Z, Y, X, W, V, U, T)
(C, B, A, Z, Y, X, W, V, U, T)
(D, C, B, A, Z, Y, X, W, V, U, T)
(E, D, C, B, A, Z, Y, X, W, V, U, T)
(T,)
(U, T)
and 5 others
note: required by a bound in `assert_partial_eq`
--> src/main.rs:22:39
|
22 | fn assert_partial_eq<A, B>() where A: PartialEq<B> {}
| ^^^^^^^^^^^^ required by this bound in `assert_partial_eq`
I always thought the standard library would have something like this:
impl<LHS1, LHS2, RHS1, RHS2> PartialEq<(RHS1, RHS2)> for (LHS1, LHS2)
where
LHS1: PartialEq<RHS1>,
LHS2: PartialEq<RHS2>,
{
...
}
But it seems like it only implements PartialEq
when the left-hand side tuple and right-hand side tuple have the exact same type.
Meta
This is reproducible on the Rust playground using stable (1.65.0).