summaryrefslogtreecommitdiffstats
path: root/library/core/src/cmp.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /library/core/src/cmp.rs
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/cmp.rs')
-rw-r--r--library/core/src/cmp.rs76
1 files changed, 54 insertions, 22 deletions
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 360806167..fadf2fcc9 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -3,14 +3,17 @@
//! This module contains various tools for comparing and ordering values. In
//! summary:
//!
-//! * [`Eq`] and [`PartialEq`] are traits that allow you to define total and
-//! partial equality between values, respectively. Implementing them overloads
-//! the `==` and `!=` operators.
+//! * [`PartialEq<Rhs>`] overloads the `==` and `!=` operators. In cases where
+//! `Rhs` (the right hand side's type) is `Self`, this trait corresponds to a
+//! partial equivalence relation.
+//! * [`Eq`] indicates that the overloaded `==` operator corresponds to an
+//! equivalence relation.
//! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
//! partial orderings between values, respectively. Implementing them overloads
//! the `<`, `<=`, `>`, and `>=` operators.
//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
-//! [`PartialOrd`], and describes an ordering.
+//! [`PartialOrd`], and describes an ordering of two values (less, equal, or
+//! greater).
//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
//! to find the maximum or minimum of two values.
@@ -27,16 +30,21 @@ pub(crate) use bytewise::BytewiseEq;
use self::Ordering::*;
-/// Trait for equality comparisons.
+/// Trait for comparisons using the equality operator.
+///
+/// Implementing this trait for types provides the `==` and `!=` operators for
+/// those types.
///
/// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
/// We use the easier-to-read infix notation in the remainder of this documentation.
///
-/// This trait allows for partial equality, for types that do not have a full
-/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
-/// so floating point types implement `PartialEq` but not [`trait@Eq`].
-/// Formally speaking, when `Rhs == Self`, this trait corresponds to a [partial equivalence
-/// relation](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
+/// This trait allows for comparisons using the equality operator, for types
+/// that do not have a full equivalence relation. For example, in floating point
+/// numbers `NaN != NaN`, so floating point types implement `PartialEq` but not
+/// [`trait@Eq`]. Formally speaking, when `Rhs == Self`, this trait corresponds
+/// to a [partial equivalence relation].
+///
+/// [partial equivalence relation]: https://en.wikipedia.org/wiki/Partial_equivalence_relation
///
/// Implementations must ensure that `eq` and `ne` are consistent with each other:
///
@@ -242,15 +250,15 @@ pub macro PartialEq($item:item) {
/* compiler built-in */
}
-/// Trait for equality comparisons which are [equivalence relations](
+/// Trait for comparisons corresponding to [equivalence relations](
/// https://en.wikipedia.org/wiki/Equivalence_relation).
///
-/// This means, that in addition to `a == b` and `a != b` being strict inverses, the equality must
-/// be (for all `a`, `b` and `c`):
+/// This means, that in addition to `a == b` and `a != b` being strict inverses,
+/// the relation must be (for all `a`, `b` and `c`):
///
/// - reflexive: `a == a`;
-/// - symmetric: `a == b` implies `b == a`; and
-/// - transitive: `a == b` and `b == c` implies `a == c`.
+/// - symmetric: `a == b` implies `b == a` (required by `PartialEq` as well); and
+/// - transitive: `a == b` and `b == c` implies `a == c` (required by `PartialEq` as well).
///
/// This property cannot be checked by the compiler, and therefore `Eq` implies
/// [`PartialEq`], and has no extra methods.
@@ -260,6 +268,10 @@ pub macro PartialEq($item:item) {
/// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of these
/// methods.
///
+/// Implement `Eq` in addition to `PartialEq` if it's guaranteed that
+/// `PartialEq::eq(a, a)` always returns `true` (reflexivity), in addition to
+/// the symmetric and transitive properties already required by `PartialEq`.
+///
/// ## Derivable
///
/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
@@ -299,8 +311,7 @@ pub trait Eq: PartialEq<Self> {
//
// This should never be implemented by hand.
#[doc(hidden)]
- #[cfg_attr(bootstrap, no_coverage)] // rust-lang/rust#84605
- #[cfg_attr(not(bootstrap), coverage(off))] //
+ #[coverage(off)]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn assert_receiver_is_total_eq(&self) {}
@@ -310,8 +321,7 @@ pub trait Eq: PartialEq<Self> {
#[rustc_builtin_macro]
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
#[allow_internal_unstable(core_intrinsics, derive_eq, structural_match)]
-#[cfg_attr(bootstrap, allow_internal_unstable(no_coverage))]
-#[cfg_attr(not(bootstrap), allow_internal_unstable(coverage_attribute))]
+#[allow_internal_unstable(coverage_attribute)]
pub macro Eq($item:item) {
/* compiler built-in */
}
@@ -676,12 +686,19 @@ impl<T: Clone> Clone for Reverse<T> {
///
/// ## Corollaries
///
-/// From the above and the requirements of `PartialOrd`, it follows that `<` defines a strict total order.
-/// This means that for all `a`, `b` and `c`:
+/// From the above and the requirements of `PartialOrd`, it follows that for
+/// all `a`, `b` and `c`:
///
/// - exactly one of `a < b`, `a == b` or `a > b` is true; and
/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
///
+/// Mathematically speaking, the `<` operator defines a strict [weak order]. In
+/// cases where `==` conforms to mathematical equality, it also defines a
+/// strict [total order].
+///
+/// [weak order]: https://en.wikipedia.org/wiki/Weak_ordering
+/// [total order]: https://en.wikipedia.org/wiki/Total_order
+///
/// ## Derivable
///
/// This trait can be used with `#[derive]`.
@@ -723,7 +740,7 @@ impl<T: Clone> Clone for Reverse<T> {
/// - Two sequences are compared element by element.
/// - The first mismatching element defines which sequence is lexicographically less or greater than the other.
/// - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other.
-/// - If two sequence have equivalent elements and are of the same length, then the sequences are lexicographically equal.
+/// - If two sequences have equivalent elements and are of the same length, then the sequences are lexicographically equal.
/// - An empty sequence is lexicographically less than any non-empty sequence.
/// - Two empty sequences are lexicographically equal.
///
@@ -790,6 +807,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "ord_cmp_method"]
fn cmp(&self, other: &Self) -> Ordering;
/// Compares and returns the maximum of two values.
@@ -920,6 +938,20 @@ pub macro Ord($item:item) {
/// - transitivity of `>`: if `a > b` and `b > c` then `a > c`
/// - duality of `partial_cmp`: `partial_cmp(a, b) == partial_cmp(b, a).map(Ordering::reverse)`
///
+/// ## Strict and non-strict partial orders
+///
+/// The `<` and `>` operators behave according to a *strict* partial order.
+/// However, `<=` and `>=` do **not** behave according to a *non-strict*
+/// partial order.
+/// That is because mathematically, a non-strict partial order would require
+/// reflexivity, i.e. `a <= a` would need to be true for every `a`. This isn't
+/// always the case for types that implement `PartialOrd`, for example:
+///
+/// ```
+/// let a = f64::sqrt(-1.0);
+/// assert_eq!(a <= a, false);
+/// ```
+///
/// ## Derivable
///
/// This trait can be used with `#[derive]`.