Skip to content

Commit eae5ed6

Browse files
committed
Make is_le and friends work like clang's
1 parent 1b21952 commit eae5ed6

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

Diff for: library/core/src/cmp.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,12 @@ pub enum Ordering {
397397
}
398398

399399
impl Ordering {
400+
#[inline]
401+
const fn as_raw(self) -> i8 {
402+
// FIXME(const-hack): just use `PartialOrd` against `Equal` once that's const
403+
crate::intrinsics::discriminant_value(&self)
404+
}
405+
400406
/// Returns `true` if the ordering is the `Equal` variant.
401407
///
402408
/// # Examples
@@ -413,7 +419,11 @@ impl Ordering {
413419
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
414420
#[stable(feature = "ordering_helpers", since = "1.53.0")]
415421
pub const fn is_eq(self) -> bool {
416-
matches!(self, Equal)
422+
// All the `is_*` methods are implemented as comparisons against zero
423+
// to follow how clang's libcxx implements their equivalents in
424+
// <https://github.com/llvm/llvm-project/blob/60486292b79885b7800b082754153202bef5b1f0/libcxx/include/__compare/is_eq.h#L23-L28>
425+
426+
self.as_raw() == 0
417427
}
418428

419429
/// Returns `true` if the ordering is not the `Equal` variant.
@@ -432,7 +442,7 @@ impl Ordering {
432442
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
433443
#[stable(feature = "ordering_helpers", since = "1.53.0")]
434444
pub const fn is_ne(self) -> bool {
435-
!matches!(self, Equal)
445+
self.as_raw() != 0
436446
}
437447

438448
/// Returns `true` if the ordering is the `Less` variant.
@@ -451,7 +461,7 @@ impl Ordering {
451461
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
452462
#[stable(feature = "ordering_helpers", since = "1.53.0")]
453463
pub const fn is_lt(self) -> bool {
454-
matches!(self, Less)
464+
self.as_raw() < 0
455465
}
456466

457467
/// Returns `true` if the ordering is the `Greater` variant.
@@ -470,7 +480,7 @@ impl Ordering {
470480
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
471481
#[stable(feature = "ordering_helpers", since = "1.53.0")]
472482
pub const fn is_gt(self) -> bool {
473-
matches!(self, Greater)
483+
self.as_raw() > 0
474484
}
475485

476486
/// Returns `true` if the ordering is either the `Less` or `Equal` variant.
@@ -489,7 +499,7 @@ impl Ordering {
489499
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
490500
#[stable(feature = "ordering_helpers", since = "1.53.0")]
491501
pub const fn is_le(self) -> bool {
492-
!matches!(self, Greater)
502+
self.as_raw() <= 0
493503
}
494504

495505
/// Returns `true` if the ordering is either the `Greater` or `Equal` variant.
@@ -508,7 +518,7 @@ impl Ordering {
508518
#[rustc_const_stable(feature = "ordering_helpers", since = "1.53.0")]
509519
#[stable(feature = "ordering_helpers", since = "1.53.0")]
510520
pub const fn is_ge(self) -> bool {
511-
!matches!(self, Less)
521+
self.as_raw() >= 0
512522
}
513523

514524
/// Reverses the `Ordering`.

Diff for: tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir

+7-9
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
1212
scope 4 (inlined <fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) {
1313
scope 5 (inlined std::cmp::Ordering::is_le) {
1414
let mut _13: i8;
15-
let mut _14: bool;
15+
scope 6 (inlined std::cmp::Ordering::as_raw) {
16+
}
1617
}
1718
}
1819
}
1920
}
20-
scope 6 (inlined <MultiField as PartialOrd>::partial_cmp) {
21+
scope 7 (inlined <MultiField as PartialOrd>::partial_cmp) {
2122
let mut _6: std::option::Option<std::cmp::Ordering>;
2223
let mut _7: i8;
23-
scope 7 {
24+
scope 8 {
2425
}
25-
scope 8 (inlined std::cmp::impls::<impl PartialOrd for char>::partial_cmp) {
26+
scope 9 (inlined std::cmp::impls::<impl PartialOrd for char>::partial_cmp) {
2627
let mut _3: char;
2728
let mut _4: char;
2829
let mut _5: std::cmp::Ordering;
2930
}
30-
scope 9 (inlined std::cmp::impls::<impl PartialOrd for i16>::partial_cmp) {
31+
scope 10 (inlined std::cmp::impls::<impl PartialOrd for i16>::partial_cmp) {
3132
let mut _8: i16;
3233
let mut _9: i16;
3334
let mut _10: std::cmp::Ordering;
@@ -78,11 +79,8 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
7879
bb3: {
7980
_12 = move ((_11 as Some).0: std::cmp::Ordering);
8081
StorageLive(_13);
81-
StorageLive(_14);
8282
_13 = discriminant(_12);
83-
_14 = Eq(copy _13, const 1_i8);
84-
_0 = Not(move _14);
85-
StorageDead(_14);
83+
_0 = Le(move _13, const 0_i8);
8684
StorageDead(_13);
8785
StorageDead(_11);
8886
StorageDead(_12);

Diff for: tests/mir-opt/pre-codegen/derived_ord.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// skip-filecheck
21
//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
32

43
#![crate_type = "lib"]
@@ -9,6 +8,24 @@ pub struct MultiField(char, i16);
98
// Because this isn't derived by the impl, it's not on the `{impl#0}-partial_cmp`,
109
// and thus we need to call it to see what the inlined generic one produces.
1110
pub fn demo_le(a: &MultiField, b: &MultiField) -> bool {
11+
// CHECK-LABEL: fn demo_le
12+
// CHECK: inlined <MultiField as PartialOrd>::le
13+
// CHECK: inlined{{.+}}is_some_and
14+
// CHECK: inlined <MultiField as PartialOrd>::partial_cmp
15+
16+
// CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char);
17+
// CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char);
18+
// CHECK: Cmp(move [[A0]], move [[B0]]);
19+
20+
// CHECK: [[D0:_[0-9]+]] = discriminant({{.+}});
21+
// CHECK: switchInt(move [[D0]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}];
22+
23+
// CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16);
24+
// CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16);
25+
// CHECK: Cmp(move [[A1]], move [[B1]]);
26+
27+
// CHECK: [[D1:_[0-9]+]] = discriminant({{.+}});
28+
// CHECK: _0 = Le(move [[D1]], const 0_i8);
1229
*a <= *b
1330
}
1431

Diff for: tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// MIR for `<impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp` after PreCodegen
1+
// MIR for `<impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp` after PreCodegen
22

3-
fn <impl at $DIR/derived_ord.rs:6:10: 6:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
3+
fn <impl at $DIR/derived_ord.rs:5:10: 5:20>::partial_cmp(_1: &MultiField, _2: &MultiField) -> Option<std::cmp::Ordering> {
44
debug self => _1;
55
debug other => _2;
66
let mut _0: std::option::Option<std::cmp::Ordering>;

0 commit comments

Comments
 (0)