Skip to content

Commit

Permalink
Rollup merge of rust-lang#91439 - ecstatic-morse:const-cmp-trait-defa…
Browse files Browse the repository at this point in the history
…ult-methods, r=oli-obk

Mark defaulted `PartialEq`/`PartialOrd` methods as const

WIthout it, `const` impls of these traits are unpleasant to write. I think this kind of change is allowed now. although it looks like it might require some Miri tweaks. Let's find out.

r? `@fee1-dead`
  • Loading branch information
matthiaskrgr authored Dec 14, 2021
2 parents 404c847 + dc18d50 commit af27a43
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
5 changes: 5 additions & 0 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[default_method_body_is_const]
fn ne(&self, other: &Rhs) -> bool {
!self.eq(other)
}
Expand Down Expand Up @@ -1031,6 +1032,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[default_method_body_is_const]
fn lt(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Less))
}
Expand All @@ -1050,6 +1052,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[default_method_body_is_const]
fn le(&self, other: &Rhs) -> bool {
// Pattern `Some(Less | Eq)` optimizes worse than negating `None | Some(Greater)`.
// FIXME: The root cause was fixed upstream in LLVM with:
Expand All @@ -1072,6 +1075,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[default_method_body_is_const]
fn gt(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Greater))
}
Expand All @@ -1091,6 +1095,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
#[default_method_body_is_const]
fn ge(&self, other: &Rhs) -> bool {
matches!(self.partial_cmp(other), Some(Greater | Equal))
}
Expand Down
28 changes: 28 additions & 0 deletions library/core/tests/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,31 @@ fn cmp_default() {
assert!(Fool(false) != Fool(false));
assert_eq!(Fool(false), Fool(true));
}

struct S(i32);

impl const PartialEq for S {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}

impl const PartialOrd for S {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let ret = match (self.0, other.0) {
(a, b) if a > b => Ordering::Greater,
(a, b) if a < b => Ordering::Less,
_ => Ordering::Equal,
};

Some(ret)
}
}

const _: () = assert!(S(1) == S(1));
const _: () = assert!(S(0) != S(1));

const _: () = assert!(S(1) <= S(1));
const _: () = assert!(S(1) >= S(1));
const _: () = assert!(S(0) < S(1));
const _: () = assert!(S(1) > S(0));

0 comments on commit af27a43

Please sign in to comment.