@@ -27,12 +27,23 @@ use self::Ordering::*;
27
27
/// Trait for equality comparisons which are [partial equivalence
28
28
/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
29
29
///
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
+ ///
30
33
/// This trait allows for partial equality, for types that do not have a full
31
34
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
32
35
/// so floating point types implement `PartialEq` but not [`trait@Eq`].
33
36
///
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`):
36
47
///
37
48
/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
38
49
/// implies `b == a`**; and
@@ -53,15 +64,6 @@ use self::Ordering::*;
53
64
///
54
65
/// ## How can I implement `PartialEq`?
55
66
///
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
- ///
65
67
/// An example implementation for a domain in which two books are considered
66
68
/// the same book if their ISBN matches, even if the formats differ:
67
69
///
@@ -634,7 +636,19 @@ impl<T: Clone> Clone for Reverse<T> {
634
636
/// An order is a total order if it is (for all `a`, `b` and `c`):
635
637
///
636
638
/// - 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`.
638
652
///
639
653
/// ## Derivable
640
654
///
@@ -659,12 +673,6 @@ impl<T: Clone> Clone for Reverse<T> {
659
673
/// Then you must define an implementation for [`cmp`]. You may find it useful to use
660
674
/// [`cmp`] on your type's fields.
661
675
///
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
- ///
668
676
/// Here's an example where you want to sort people by height only, disregarding `id`
669
677
/// and `name`:
670
678
///
@@ -824,15 +832,41 @@ impl PartialOrd for Ordering {
824
832
825
833
/// Trait for values that can be compared for a sort-order.
826
834
///
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
+ ///
827
853
/// The comparison must satisfy, for all `a`, `b` and `c`:
828
854
///
829
- /// - asymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
830
855
/// - 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`.
831
857
///
832
858
/// Note that these requirements mean that the trait itself must be implemented symmetrically and
833
859
/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
834
860
/// PartialOrd<V>`.
835
861
///
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
+ ///
836
870
/// ## Derivable
837
871
///
838
872
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
@@ -850,10 +884,6 @@ impl PartialOrd for Ordering {
850
884
///
851
885
/// `PartialOrd` requires your type to be [`PartialEq`].
852
886
///
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
- ///
857
887
/// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
858
888
///
859
889
/// ```
0 commit comments