Rollup merge of #91439 - ecstatic-morse:const-cmp-trait-default-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```
This commit is contained in:
Matthias Krüger 2021-12-18 10:26:35 +01:00 committed by GitHub
commit 359c88e426
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 0 deletions

View file

@ -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)
}
@ -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))
}
@ -1050,6 +1052,7 @@ fn lt(&self, other: &Rhs) -> bool {
#[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:
@ -1072,6 +1075,7 @@ fn le(&self, other: &Rhs) -> bool {
#[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))
}
@ -1091,6 +1095,7 @@ fn gt(&self, other: &Rhs) -> bool {
#[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))
}

View file

@ -203,3 +203,36 @@ fn partial_cmp(&self, other: &RevInt) -> Option<Ordering> {
assert!(Fool(false) != Fool(false));
assert_eq!(Fool(false), Fool(true));
}
#[cfg(not(bootstrap))]
mod const_cmp {
use super::*;
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));
}