Skip to content

Commit f610834

Browse files
committed
Add+Use mir::BinOp::Cmp
1 parent 3be20da commit f610834

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

core/src/cmp.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> {
376376
/// ```
377377
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
378378
#[stable(feature = "rust1", since = "1.0.0")]
379+
#[cfg_attr(not(bootstrap), lang = "Ordering")]
379380
#[repr(i8)]
380381
pub enum Ordering {
381382
/// An ordering where a compared value is less than another.
@@ -1563,12 +1564,19 @@ mod impls {
15631564
impl Ord for $t {
15641565
#[inline]
15651566
fn cmp(&self, other: &$t) -> Ordering {
1567+
#[cfg(bootstrap)]
1568+
{
15661569
// The order here is important to generate more optimal assembly.
15671570
// See <https://github.com/rust-lang/rust/issues/63758> for more info.
15681571
if *self < *other { Less }
15691572
else if *self == *other { Equal }
15701573
else { Greater }
15711574
}
1575+
#[cfg(not(bootstrap))]
1576+
{
1577+
crate::intrinsics::three_way_compare(*self, *other)
1578+
}
1579+
}
15721580
}
15731581
)*)
15741582
}

core/src/intrinsics.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,18 @@ extern "rust-intrinsic" {
21462146
#[rustc_nounwind]
21472147
pub fn bitreverse<T: Copy>(x: T) -> T;
21482148

2149+
/// Does a three-way comparison between the two integer arguments.
2150+
///
2151+
/// This is included as an intrinsic as it's useful to let it be one thing
2152+
/// in MIR, rather than the multiple checks and switches that make its IR
2153+
/// large and difficult to optimize.
2154+
///
2155+
/// The stabilized version of this intrinsic is [`Ord::cmp`].
2156+
#[cfg(not(bootstrap))]
2157+
#[rustc_const_unstable(feature = "const_three_way_compare", issue = "none")]
2158+
#[rustc_safe_intrinsic]
2159+
pub fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> crate::cmp::Ordering;
2160+
21492161
/// Performs checked integer addition.
21502162
///
21512163
/// Note that, unlike most intrinsics, this is safe to call;

core/tests/intrinsics.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,22 @@ fn test_const_deallocate_at_runtime() {
9999
const_deallocate(core::ptr::null_mut(), 1, 1); // nop
100100
}
101101
}
102+
103+
#[cfg(not(bootstrap))]
104+
#[test]
105+
fn test_three_way_compare_in_const_contexts() {
106+
use core::cmp::Ordering::*;
107+
use core::intrinsics::three_way_compare;
108+
109+
const {
110+
assert!(Less as i8 == three_way_compare(123_u16, 456) as _);
111+
assert!(Equal as i8 == three_way_compare(456_u16, 456) as _);
112+
assert!(Greater as i8 == three_way_compare(789_u16, 456) as _);
113+
assert!(Less as i8 == three_way_compare('A', 'B') as _);
114+
assert!(Equal as i8 == three_way_compare('B', 'B') as _);
115+
assert!(Greater as i8 == three_way_compare('C', 'B') as _);
116+
assert!(Less as i8 == three_way_compare(-123_i16, 456) as _);
117+
assert!(Equal as i8 == three_way_compare(456_i16, 456) as _);
118+
assert!(Greater as i8 == three_way_compare(123_i16, -456) as _);
119+
}
120+
}

core/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#![feature(const_pointer_is_aligned)]
2222
#![feature(const_ptr_as_ref)]
2323
#![feature(const_ptr_write)]
24+
#![cfg_attr(not(bootstrap), feature(const_three_way_compare))]
2425
#![feature(const_trait_impl)]
2526
#![feature(const_likely)]
2627
#![feature(const_location_fields)]

0 commit comments

Comments
 (0)