Skip to content

Commit 13b3294

Browse files
Rollup merge of #81198 - dtolnay:partialeq, r=m-ou-se
Remove requirement that forces symmetric and transitive PartialEq impls to exist ### Counterexample of symmetry: If you [have](https://docs.rs/proc-macro2/1.0.24/proc_macro2/struct.Ident.html#impl-PartialEq%3CT%3E) an impl like: ```rust impl<T> PartialEq<T> for Ident where T: ?Sized + AsRef<str> ``` then Rust will not even allow the symmetric impl to exist. ```console error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Ident`) --> src/main.rs:9:6 | 9 | impl<T> PartialEq<Ident> for T where T: ?Sized + AsRef<str> { | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Ident`) | = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last ``` <br> ### Counterexample of transitivity: Consider these two existing impls from `regex` and `clap`: ```rust // regex /// An inline representation of `Option<char>`. pub struct Char(u32); impl PartialEq<char> for Char { fn eq(&self, other: &char) -> bool { self.0 == *other as u32 } } ``` ```rust // clap pub(crate) enum KeyType { Short(char), Long(OsString), Position(u64), } impl PartialEq<char> for KeyType { fn eq(&self, rhs: &char) -> bool { match self { KeyType::Short(c) => c == rhs, _ => false, } } } ``` It's nice to be able to add `PartialEq<proc_macro::Punct> for char` in libproc_macro (#80595), but it makes no sense to force an `impl PartialEq<Punct> for Char` and `impl PartialEq<Punct> for KeyType` in `regex` and `clap` in code that otherwise has nothing to do with proc macros. <br> `@rust-lang/libs`
2 parents 0793fab + 8758083 commit 13b3294

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

library/core/src/cmp.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,18 @@ use self::Ordering::*;
3131
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
3232
/// so floating point types implement `PartialEq` but not [`trait@Eq`].
3333
///
34-
/// Formally, the equality must be (for all `a`, `b` and `c`):
34+
/// Formally, the equality must be (for all `a`, `b`, `c` of type `A`, `B`,
35+
/// `C`):
3536
///
36-
/// - symmetric: `a == b` implies `b == a`; and
37-
/// - transitive: `a == b` and `b == c` implies `a == c`.
37+
/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
38+
/// implies `b == a`**; and
39+
///
40+
/// - **Transitive**: if `A: PartialEq<B>` and `B: PartialEq<C>` and `A:
41+
/// PartialEq<C>`, then **`a == b` and `b == c` implies `a == c`**.
3842
///
39-
/// Note that these requirements mean that the trait itself must be implemented
40-
/// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
41-
/// then `U: PartialEq<T>` and `T: PartialEq<V>`.
43+
/// Note that the `B: PartialEq<A>` (symmetric) and `A: PartialEq<C>`
44+
/// (transitive) impls are not forced to exist, but these requirements apply
45+
/// whenever they do exist.
4246
///
4347
/// ## Derivable
4448
///

0 commit comments

Comments
 (0)