Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 114 additions & 185 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,23 @@ use crate::ops::ControlFlow;
#[rustc_diagnostic_item = "PartialEq"]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
pub const trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
/// Tests for `self` and `other` values to be equal, and is used by `==`.
/// Equality operator `==`.
///
/// Implementation of the "is equal to" operator `==`:
/// tests whether its arguments are equal.
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "cmp_partialeq_eq"]
fn eq(&self, other: &Rhs) -> bool;

/// Tests for `!=`. The default implementation is almost always sufficient,
/// and should not be overridden without very good reason.
/// Inequality operator `!=`.
///
/// Implementation of the "is not equal to" or "is different from" operator `!=`:
/// tests whether its arguments are different.
///
/// # Default implementation
/// The default implementation of the inequality operator simply calls
/// the implementation of the equality operator and negates the result.
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1854,34 +1863,38 @@ mod impls {
use crate::marker::PointeeSized;
use crate::ops::ControlFlow::{self, Break, Continue};

macro_rules! partial_eq_impl {
/// Implements `PartialEq` for primitive types.
///
/// Primitive types have a compiler-defined primitive implementation of `==` and `!=`.
/// This implements the `PartialEq` trait is terms of those primitive implementations.
///
/// NOTE: Calling this on a non-primitive type (such as `()`)
/// leads to infinitely recursive implementations.
macro_rules! impl_partial_eq_for_primitive {
($($t:ty)*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl const PartialEq for $t {
#[inline]
fn eq(&self, other: &Self) -> bool { *self == *other }
// Override the default to use the primitive implementation for `!=`.
#[inline]
fn ne(&self, other: &Self) -> bool { *self != *other }
}
)*)
}

impl_partial_eq_for_primitive! {
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl const PartialEq for () {
#[inline]
fn eq(&self, _other: &()) -> bool {
true
}
#[inline]
fn ne(&self, _other: &()) -> bool {
false
}
}

partial_eq_impl! {
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
}

macro_rules! eq_impl {
Expand Down Expand Up @@ -2075,185 +2088,101 @@ mod impls {
}
}

// & pointers
// reference types

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &A
where
A: [const] PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
fn ne(&self, other: &&B) -> bool {
PartialEq::ne(*self, *other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&B> for &A
where
A: [const] PartialOrd<B>,
{
#[inline]
fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &&B) -> bool {
PartialOrd::lt(*self, *other)
}
#[inline]
fn le(&self, other: &&B) -> bool {
PartialOrd::le(*self, *other)
}
#[inline]
fn gt(&self, other: &&B) -> bool {
PartialOrd::gt(*self, *other)
}
#[inline]
fn ge(&self, other: &&B) -> bool {
PartialOrd::ge(*self, *other)
}
#[inline]
fn __chaining_lt(&self, other: &&B) -> ControlFlow<bool> {
PartialOrd::__chaining_lt(*self, *other)
}
#[inline]
fn __chaining_le(&self, other: &&B) -> ControlFlow<bool> {
PartialOrd::__chaining_le(*self, *other)
}
#[inline]
fn __chaining_gt(&self, other: &&B) -> ControlFlow<bool> {
PartialOrd::__chaining_gt(*self, *other)
}
#[inline]
fn __chaining_ge(&self, other: &&B) -> ControlFlow<bool> {
PartialOrd::__chaining_ge(*self, *other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized> const Ord for &A
where
A: [const] Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(*self, *other)
}
macro_rules! impl_partial_eq {
(<$A:ident, $B:ident> for $(($ref_A:ty, $ref_B:ty))*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<$A, $B> const PartialEq<$ref_B> for $ref_A
where
$A: [const] PartialEq<$B> + PointeeSized,
$B: PointeeSized,
{
#[inline]
fn eq(&self, other: &$ref_B) -> bool {
PartialEq::eq(*self, *other)
}
// if <A as PartialEq<B>>::ne uses inline assembly or FFI, then
// this forwarding impl may be more efficient than the default impl
#[inline]
fn ne(&self, other: &$ref_B) -> bool {
PartialEq::ne(*self, *other)
}
}
)*)
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized> const Eq for &A where A: [const] Eq {}

// &mut pointers
impl_partial_eq!(<A, B> for (&A, &B) (&A, &mut B) (&mut A, &B) (&mut A, &mut B));

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &mut A
where
A: [const] PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&mut B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
fn ne(&self, other: &&mut B) -> bool {
PartialEq::ne(*self, *other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&mut B> for &mut A
where
A: [const] PartialOrd<B>,
{
#[inline]
fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &&mut B) -> bool {
PartialOrd::lt(*self, *other)
}
#[inline]
fn le(&self, other: &&mut B) -> bool {
PartialOrd::le(*self, *other)
}
#[inline]
fn gt(&self, other: &&mut B) -> bool {
PartialOrd::gt(*self, *other)
}
#[inline]
fn ge(&self, other: &&mut B) -> bool {
PartialOrd::ge(*self, *other)
}
#[inline]
fn __chaining_lt(&self, other: &&mut B) -> ControlFlow<bool> {
PartialOrd::__chaining_lt(*self, *other)
}
#[inline]
fn __chaining_le(&self, other: &&mut B) -> ControlFlow<bool> {
PartialOrd::__chaining_le(*self, *other)
}
#[inline]
fn __chaining_gt(&self, other: &&mut B) -> ControlFlow<bool> {
PartialOrd::__chaining_gt(*self, *other)
}
#[inline]
fn __chaining_ge(&self, other: &&mut B) -> ControlFlow<bool> {
PartialOrd::__chaining_ge(*self, *other)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized> const Ord for &mut A
where
A: [const] Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(*self, *other)
}
macro_rules! impl_partial_ord {
(<$A:ident, $B:ident> for $(($ref_A:ty, $ref_B:ty))*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<$A, $B> const PartialOrd<$ref_B> for $ref_A
where
$A: [const] PartialOrd<$B> + PointeeSized,
$B: PointeeSized,
{
#[inline]
fn partial_cmp(&self, other: &$ref_B) -> Option<Ordering> {
PartialOrd::partial_cmp(*self, *other)
}
#[inline]
fn lt(&self, other: &$ref_B) -> bool {
PartialOrd::lt(*self, *other)
}
#[inline]
fn le(&self, other: &$ref_B) -> bool {
PartialOrd::le(*self, *other)
}
#[inline]
fn gt(&self, other: &$ref_B) -> bool {
PartialOrd::gt(*self, *other)
}
#[inline]
fn ge(&self, other: &$ref_B) -> bool {
PartialOrd::ge(*self, *other)
}
#[inline]
fn __chaining_lt(&self, other: &$ref_B) -> ControlFlow<bool> {
PartialOrd::__chaining_lt(*self, *other)
}
#[inline]
fn __chaining_le(&self, other: &$ref_B) -> ControlFlow<bool> {
PartialOrd::__chaining_le(*self, *other)
}
#[inline]
fn __chaining_gt(&self, other: &$ref_B) -> ControlFlow<bool> {
PartialOrd::__chaining_gt(*self, *other)
}
#[inline]
fn __chaining_ge(&self, other: &$ref_B) -> ControlFlow<bool> {
PartialOrd::__chaining_ge(*self, *other)
}
}
)*)
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized> const Eq for &mut A where A: [const] Eq {}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&mut B> for &A
where
A: [const] PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&mut B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
fn ne(&self, other: &&mut B) -> bool {
PartialEq::ne(*self, *other)
}
}
impl_partial_ord!(<A, B> for (&A, &B) /*(&A, &mut B) (&mut A, &B)*/ (&mut A, &mut B));

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<A: PointeeSized, B: PointeeSized> const PartialEq<&B> for &mut A
where
A: [const] PartialEq<B>,
{
#[inline]
fn eq(&self, other: &&B) -> bool {
PartialEq::eq(*self, *other)
}
#[inline]
fn ne(&self, other: &&B) -> bool {
PartialEq::ne(*self, *other)
}
macro_rules! impl_ord_eq {
(<$A:ident> for $($ref_A:ty),*) => ($(
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<$A: [const] Ord + PointeeSized> const Ord for $ref_A
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(*self, *other)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
impl<$A: [const] Eq + PointeeSized> const Eq for $ref_A {}
)*)
}

impl_ord_eq!(<A> for &A, &mut A);
}
Loading