about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2024-03-24 17:13:26 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2024-03-24 17:42:35 -0700
commitc59e93c753ba7e5945fe95f4d1785b09300aa0e0 (patch)
treee6dcbb7f2a97d5e6fb6915772d2cb769f7f3fd93
parent8d5977d6af03af18c7851025b9ca70d0f2d12c86 (diff)
downloadrust-c59e93c753ba7e5945fe95f4d1785b09300aa0e0.tar.gz
rust-c59e93c753ba7e5945fe95f4d1785b09300aa0e0.zip
Address PR feedback
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs8
-rw-r--r--library/core/src/cmp.rs3
-rw-r--r--library/core/tests/intrinsics.rs32
3 files changed, 31 insertions, 12 deletions
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index a33de2efe2f..67f881e862a 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1445,6 +1445,14 @@ pub enum BinOp {
     /// The `>` operator (greater than)
     Gt,
     /// The `<=>` operator (three-way comparison, like `Ord::cmp`)
+    ///
+    /// This is supported only on the integer types and `char`, always returning
+    /// [`rustc_hir::LangItem::OrderingEnum`] (aka [`std::cmp::Ordering`]).
+    ///
+    /// [`Rvalue::BinaryOp`]`(BinOp::Cmp, A, B)` returns
+    /// - `Ordering::Less` (`-1_i8`, as a Scalar) if `A < B`
+    /// - `Ordering::Equal` (`0_i8`, as a Scalar) if `A == B`
+    /// - `Ordering::Greater` (`+1_i8`, as a Scalar) if `A > B`
     Cmp,
     /// The `ptr.offset` operator
     Offset,
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index e3b7cf84920..7f9c041f691 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -376,6 +376,9 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
 /// ```
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
+// This is a lang item only so that `BinOp::Cmp` in MIR can return it.
+// It has no special behaviour, but does require that the three variants
+// `Less`/`Equal`/`Greater` remain `-1_i8`/`0_i8`/`+1_i8` respectively.
 #[cfg_attr(not(bootstrap), lang = "Ordering")]
 #[repr(i8)]
 pub enum Ordering {
diff --git a/library/core/tests/intrinsics.rs b/library/core/tests/intrinsics.rs
index a9ef5415ada..eb1e1a0b9b1 100644
--- a/library/core/tests/intrinsics.rs
+++ b/library/core/tests/intrinsics.rs
@@ -103,18 +103,26 @@ fn test_const_deallocate_at_runtime() {
 #[cfg(not(bootstrap))]
 #[test]
 fn test_three_way_compare_in_const_contexts() {
-    use core::cmp::Ordering::*;
+    use core::cmp::Ordering::{self, *};
     use core::intrinsics::three_way_compare;
 
-    const {
-        assert!(Less as i8 == three_way_compare(123_u16, 456) as _);
-        assert!(Equal as i8 == three_way_compare(456_u16, 456) as _);
-        assert!(Greater as i8 == three_way_compare(789_u16, 456) as _);
-        assert!(Less as i8 == three_way_compare('A', 'B') as _);
-        assert!(Equal as i8 == three_way_compare('B', 'B') as _);
-        assert!(Greater as i8 == three_way_compare('C', 'B') as _);
-        assert!(Less as i8 == three_way_compare(-123_i16, 456) as _);
-        assert!(Equal as i8 == three_way_compare(456_i16, 456) as _);
-        assert!(Greater as i8 == three_way_compare(123_i16, -456) as _);
-    }
+    const UNSIGNED_LESS: Ordering = three_way_compare(123_u16, 456);
+    const UNSIGNED_EQUAL: Ordering = three_way_compare(456_u16, 456);
+    const UNSIGNED_GREATER: Ordering = three_way_compare(789_u16, 456);
+    const CHAR_LESS: Ordering = three_way_compare('A', 'B');
+    const CHAR_EQUAL: Ordering = three_way_compare('B', 'B');
+    const CHAR_GREATER: Ordering = three_way_compare('C', 'B');
+    const SIGNED_LESS: Ordering = three_way_compare(123_i64, 456);
+    const SIGNED_EQUAL: Ordering = three_way_compare(456_i64, 456);
+    const SIGNED_GREATER: Ordering = three_way_compare(789_i64, 456);
+
+    assert_eq!(UNSIGNED_LESS, Less);
+    assert_eq!(UNSIGNED_EQUAL, Equal);
+    assert_eq!(UNSIGNED_GREATER, Greater);
+    assert_eq!(CHAR_LESS, Less);
+    assert_eq!(CHAR_EQUAL, Equal);
+    assert_eq!(CHAR_GREATER, Greater);
+    assert_eq!(SIGNED_LESS, Less);
+    assert_eq!(SIGNED_EQUAL, Equal);
+    assert_eq!(SIGNED_GREATER, Greater);
 }