about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-12-18 10:26:35 +0100
committerGitHub <noreply@github.com>2021-12-18 10:26:35 +0100
commit359c88e426c7a696ebaac071feaeea1799d4db58 (patch)
tree652481be0267da3aab94a8588bdca5ecc3cc45d2
parentdde825db464b08d6f572766579dfb629b837368c (diff)
parent20492870307feae4ca57acdca75bcc8ea06fe175 (diff)
downloadrust-359c88e426c7a696ebaac071feaeea1799d4db58.tar.gz
rust-359c88e426c7a696ebaac071feaeea1799d4db58.zip
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```
-rw-r--r--library/core/src/cmp.rs5
-rw-r--r--library/core/tests/cmp.rs33
2 files changed, 38 insertions, 0 deletions
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 7456f886ea5..deed9901cc9 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -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 @@ 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:
@@ -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))
     }
@@ -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))
     }
diff --git a/library/core/tests/cmp.rs b/library/core/tests/cmp.rs
index 11cf7add07a..58fee19ca74 100644
--- a/library/core/tests/cmp.rs
+++ b/library/core/tests/cmp.rs
@@ -203,3 +203,36 @@ fn cmp_default() {
     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));
+}