Skip to content

Commit f2a92ef

Browse files
borsgitbot
authored and
gitbot
committed
Auto merge of rust-lang#86502 - JohnTitor:rollup-wge0f3x, r=JohnTitor
Rollup of 8 pull requests Successful merges: - rust-lang#83739 (Account for bad placeholder errors on consts/statics with trait objects) - rust-lang#85637 (document PartialEq, PartialOrd, Ord requirements more explicitly) - rust-lang#86152 (Lazify is_really_default condition in the RustdocGUI bootstrap step) - rust-lang#86156 (Fix a bug in the linkchecker) - rust-lang#86427 (Updated release note) - rust-lang#86452 (fix panic-safety in specialized Zip::next_back) - rust-lang#86484 (Do not set depth to 0 in fully_expand_fragment) - rust-lang#86491 (expand: Move some more derive logic to rustc_builtin_macros) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents be555fc + 90cb09c commit f2a92ef

File tree

1 file changed

+64
-25
lines changed

1 file changed

+64
-25
lines changed

core/src/cmp.rs

+64-25
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,25 @@ 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+
///
39+
/// - `a != b` if and only if `!(a == b)`
40+
/// (ensured by the default implementation).
41+
///
42+
/// If [`PartialOrd`] or [`Ord`] are also implemented for `Self` and `Rhs`, their methods must also
43+
/// be consistent with `PartialEq` (see the documentation of those traits for the exact
44+
/// requirememts). It's easy to accidentally make them disagree by deriving some of the traits and
45+
/// manually implementing others.
46+
///
47+
/// The equality relation `==` must satisfy the following conditions
48+
/// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
3649
///
3750
/// - **Symmetric**: if `A: PartialEq<B>` and `B: PartialEq<A>`, then **`a == b`
3851
/// implies `b == a`**; and
@@ -53,15 +66,6 @@ use self::Ordering::*;
5366
///
5467
/// ## How can I implement `PartialEq`?
5568
///
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-
///
6569
/// An example implementation for a domain in which two books are considered
6670
/// the same book if their ISBN matches, even if the formats differ:
6771
///
@@ -631,10 +635,25 @@ impl<T: Clone> Clone for Reverse<T> {
631635

632636
/// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
633637
///
634-
/// An order is a total order if it is (for all `a`, `b` and `c`):
638+
/// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure
639+
/// `max`, `min`, and `clamp` are consistent with `cmp`:
640+
///
641+
/// - `partial_cmp(a, b) == Some(cmp(a, b))`.
642+
/// - `max(a, b) == max_by(a, b, cmp)` (ensured by the default implementation).
643+
/// - `min(a, b) == min_by(a, b, cmp)` (ensured by the default implementation).
644+
/// - For `a.clamp(min, max)`, see the [method docs](#method.clamp)
645+
/// (ensured by the default implementation).
646+
///
647+
/// It's easy to accidentally make `cmp` and `partial_cmp` disagree by
648+
/// deriving some of the traits and manually implementing others.
649+
///
650+
/// ## Corollaries
651+
///
652+
/// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
653+
/// This means that for all `a`, `b` and `c`:
635654
///
636-
/// - 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 `>`.
655+
/// - exactly one of `a < b`, `a == b` or `a > b` is true; and
656+
/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
638657
///
639658
/// ## Derivable
640659
///
@@ -659,12 +678,6 @@ impl<T: Clone> Clone for Reverse<T> {
659678
/// Then you must define an implementation for [`cmp`]. You may find it useful to use
660679
/// [`cmp`] on your type's fields.
661680
///
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-
///
668681
/// Here's an example where you want to sort people by height only, disregarding `id`
669682
/// and `name`:
670683
///
@@ -824,15 +837,45 @@ impl PartialOrd for Ordering {
824837

825838
/// Trait for values that can be compared for a sort-order.
826839
///
840+
/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
841+
/// the `<`, `<=`, `>`, and `>=` operators, respectively.
842+
///
843+
/// The methods of this trait must be consistent with each other and with those of `PartialEq` in
844+
/// the following sense:
845+
///
846+
/// - `a == b` if and only if `partial_cmp(a, b) == Some(Equal)`.
847+
/// - `a < b` if and only if `partial_cmp(a, b) == Some(Less)`
848+
/// (ensured by the default implementation).
849+
/// - `a > b` if and only if `partial_cmp(a, b) == Some(Greater)`
850+
/// (ensured by the default implementation).
851+
/// - `a <= b` if and only if `a < b || a == b`
852+
/// (ensured by the default implementation).
853+
/// - `a >= b` if and only if `a > b || a == b`
854+
/// (ensured by the default implementation).
855+
/// - `a != b` if and only if `!(a == b)` (already part of `PartialEq`).
856+
///
857+
/// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
858+
/// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
859+
/// easy to accidentally make them disagree by deriving some of the traits and manually
860+
/// implementing others.
861+
///
827862
/// The comparison must satisfy, for all `a`, `b` and `c`:
828863
///
829-
/// - asymmetry: if `a < b` then `!(a > b)`, as well as `a > b` implying `!(a < b)`; and
830864
/// - transitivity: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
865+
/// - duality: `a < b` if and only if `b > a`.
831866
///
832867
/// Note that these requirements mean that the trait itself must be implemented symmetrically and
833868
/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
834869
/// PartialOrd<V>`.
835870
///
871+
/// ## Corollaries
872+
///
873+
/// The following corollaries follow from the above requirements:
874+
///
875+
/// - irreflexivity of `<` and `>`: `!(a < a)`, `!(a > a)`
876+
/// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
877+
/// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
878+
///
836879
/// ## Derivable
837880
///
838881
/// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a
@@ -850,10 +893,6 @@ impl PartialOrd for Ordering {
850893
///
851894
/// `PartialOrd` requires your type to be [`PartialEq`].
852895
///
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-
///
857896
/// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]:
858897
///
859898
/// ```

0 commit comments

Comments
 (0)