@@ -27,12 +27,23 @@ use self::Ordering::*;
2727/// Trait for equality comparisons which are [partial equivalence
2828/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
2929///
30+ /// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
31+ /// We use the easier-to-read infix notation in the remainder of this documentation.
32+ ///
3033/// This trait allows for partial equality, for types that do not have a full
3134/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
3235/// so floating point types implement `PartialEq` but not [`trait@Eq`].
3336///
34- /// Formally, the equality must be (for all `a`, `b`, `c` of type `A`, `B`,
35- /// `C`):
37+ /// Implementations must ensure that `eq` and `ne` are consistent with each other:
38+ /// `a != b` if and only if `!(a == b)`.
39+ /// This is ensured by the default implementation of `ne`.
40+ /// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
41+ /// be consistent with `PartialEq` (see the documentation of those traits for the exact
42+ /// requirememts). It's easy to accidentally make them disagree by deriving some of the traits and
43+ /// manually implementing others.
44+ ///
45+ /// The equality relation `==` must satisfy the following conditions
46+ /// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
3647///
3748/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
3849/// implies `b == a`**; and
@@ -53,15 +64,6 @@ use self::Ordering::*;
5364///
5465/// ## How can I implement `PartialEq`?
5566///
56- /// `PartialEq` only requires the [`eq`] method to be implemented; [`ne`] is defined
57- /// in terms of it by default. Any manual implementation of [`ne`] *must* respect
58- /// the rule that [`eq`] is a strict inverse of [`ne`]; that is, `!(a == b)` if and
59- /// only if `a != b`.
60- ///
61- /// Implementations of `PartialEq`, [`PartialOrd`], and [`Ord`] *must* agree with
62- /// each other. It's easy to accidentally make them disagree by deriving some
63- /// of the traits and manually implementing others.
64- ///
6567/// An example implementation for a domain in which two books are considered
6668/// the same book if their ISBN matches, even if the formats differ:
6769///
@@ -634,7 +636,19 @@ impl<T: Clone> Clone for Reverse<T> {
634636/// An order is a total order if it is (for all `a`, `b` and `c`):
635637///
636638/// - total and asymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
637- /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
639+ /// - transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
640+ ///
641+ /// Implementations of [`PartialEq`], [`PartialOrd`], and `Ord` *must* agree with each other (for
642+ /// all `a` and `b`):
643+ ///
644+ /// - `a.partial_cmp(b) == Some(a.cmp(b))`
645+ /// - `a.cmp(b) == Ordering::Equal` if and only if `a == b`
646+ /// (already follows from the above and the requirements of `PartialOrd`)
647+ ///
648+ /// It's easy to accidentally make them disagree by
649+ /// deriving some of the traits and manually implementing others.
650+ ///
651+ /// Furthermore, the `max`, `min`, and `clamp` methods of this trait must be consistent with `cmp`.
638652///
639653/// ## Derivable
640654///
@@ -659,12 +673,6 @@ impl<T: Clone> Clone for Reverse<T> {
659673/// Then you must define an implementation for [`cmp`]. You may find it useful to use
660674/// [`cmp`] on your type's fields.
661675///
662- /// Implementations of [`PartialEq`], [`PartialOrd`], and `Ord` *must*
663- /// agree with each other. That is, `a.cmp(b) == Ordering::Equal` if
664- /// and only if `a == b` and `Some(a.cmp(b)) == a.partial_cmp(b)` for
665- /// all `a` and `b`. It's easy to accidentally make them disagree by
666- /// deriving some of the traits and manually implementing others.
667- ///
668676/// Here's an example where you want to sort people by height only, disregarding `id`
669677/// and `name`:
670678///
@@ -824,15 +832,41 @@ impl PartialOrd for Ordering {
824832
825833/// Trait for values that can be compared for a sort-order.
826834///
835+ /// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
836+ /// the `<`, `<=`, `>`, and `>=` operators, respectively.
837+ ///
838+ /// The methods of this trait must be consistent with each other and with those of `PartialEq` in
839+ /// the following sense:
840+ ///
841+ /// - `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
842+ /// - `a < b` if and only if `partial_cmp(a, b) == Some(Less)`.
843+ /// - `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`.
844+ /// - `a <= b` if and only if `a < b || a == b`.
845+ /// - `a >= b` if and only if `a > b || a == b`.
846+ /// - `a != b` if and only if `!(a == b)` (already part of `PartialEq`).
847+ ///
848+ /// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
849+ /// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
850+ /// easy to accidentally make them disagree by deriving some of the traits and manually
851+ /// implementing others.
852+ ///
827853/// The comparison must satisfy, for all `a`, `b` and `c`:
828854///
829- /// - asymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
830855/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
856+ /// - duality: `a < b` if and only if `b > a`.
831857///
832858/// Note that these requirements mean that the trait itself must be implemented symmetrically and
833859/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
834860/// PartialOrd<V>`.
835861///
862+ /// ## Corollaries
863+ ///
864+ /// The following corollaries follow from the above requirements:
865+ ///
866+ /// - irreflexivity of `<` and `>`: `!(a < a)`, `!(a > a)`
867+ /// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
868+ /// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
869+ ///
836870/// ## Derivable
837871///
838872/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
@@ -850,10 +884,6 @@ impl PartialOrd for Ordering {
850884///
851885/// `PartialOrd` requires your type to be [`PartialEq`].
852886///
853- /// Implementations of [`PartialEq`], `PartialOrd`, and [`Ord`] *must* agree with each other. It's
854- /// easy to accidentally make them disagree by deriving some of the traits and manually
855- /// implementing others.
856- ///
857887/// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
858888///
859889/// ```
0 commit comments