From c59e93c753ba7e5945fe95f4d1785b09300aa0e0 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 24 Mar 2024 17:13:26 -0700 Subject: [PATCH] Address PR feedback --- compiler/rustc_middle/src/mir/syntax.rs | 8 +++++++ library/core/src/cmp.rs | 3 +++ library/core/tests/intrinsics.rs | 32 +++++++++++++++---------- 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 a33de2efe2fa..67f881e862a1 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 e3b7cf84920e..7f9c041f6918 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -376,6 +376,9 @@ pub struct AssertParamIsEq { /// ``` #[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 a9ef5415ada6..eb1e1a0b9b1d 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); }