Skip to content

Commit 915e273

Browse files
authored
Rollup merge of #107022 - scottmcm:ordering-option-eq, r=m-ou-se
Implement `SpecOptionPartialEq` for `cmp::Ordering` Noticed as I continue to explore options for having code using `partial_cmp` optimize better. Before: ```llvm ; Function Attrs: mustprogress nofree nosync nounwind willreturn uwtable define noundef zeroext i1 `@ordering_eq(i8` noundef %0, i8 noundef %1) unnamed_addr #0 { start: %2 = icmp eq i8 %0, 2 br i1 %2, label %bb1.i, label %bb3.i bb1.i: ; preds = %start %3 = icmp eq i8 %1, 2 br label %"_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit" bb3.i: ; preds = %start %.not.i = icmp ne i8 %1, 2 %4 = icmp eq i8 %0, %1 %spec.select.i = and i1 %.not.i, %4 br label %"_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit" "_ZN55_$LT$T$u20$as$u20$core..option..SpecOptionPartialEq$GT$2eq17hb7e7beacecde585fE.exit": ; preds = %bb1.i, %bb3.i %.0.i = phi i1 [ %3, %bb1.i ], [ %spec.select.i, %bb3.i ] ret i1 %.0.i } ``` After: ```llvm ; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone willreturn uwtable define noundef zeroext i1 `@ordering_eq(i8` noundef %0, i8 noundef %1) unnamed_addr #1 { start: %2 = icmp eq i8 %0, %1 ret i1 %2 } ``` (Which <https://alive2.llvm.org/ce/z/-rop5r> says LLVM *could* just do itself, but there's probably an issue already open for that problem from when this was originally looked at for `Option<NonZeroU8>` and friends.)
2 parents 679cd32 + ea3bded commit 915e273

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

core/src/option.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ use crate::marker::Destruct;
551551
use crate::panicking::{panic, panic_str};
552552
use crate::pin::Pin;
553553
use crate::{
554-
convert, hint, mem,
554+
cmp, convert, hint, mem,
555555
ops::{self, ControlFlow, Deref, DerefMut},
556556
};
557557

@@ -2090,6 +2090,12 @@ impl<T: PartialEq> PartialEq for Option<T> {
20902090
}
20912091
}
20922092

2093+
/// This specialization trait is a workaround for LLVM not currently (2023-01)
2094+
/// being able to optimize this itself, even though Alive confirms that it would
2095+
/// be legal to do so: <https://github.com/llvm/llvm-project/issues/52622>
2096+
///
2097+
/// Once that's fixed, `Option` should go back to deriving `PartialEq`, as
2098+
/// it used to do before <https://github.com/rust-lang/rust/pull/103556>.
20932099
#[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")]
20942100
#[doc(hidden)]
20952101
pub trait SpecOptionPartialEq: Sized {
@@ -2146,6 +2152,14 @@ impl<T> SpecOptionPartialEq for crate::ptr::NonNull<T> {
21462152
}
21472153
}
21482154

2155+
#[stable(feature = "rust1", since = "1.0.0")]
2156+
impl SpecOptionPartialEq for cmp::Ordering {
2157+
#[inline]
2158+
fn eq(l: &Option<Self>, r: &Option<Self>) -> bool {
2159+
l.map_or(2, |x| x as i8) == r.map_or(2, |x| x as i8)
2160+
}
2161+
}
2162+
21492163
/////////////////////////////////////////////////////////////////////////////
21502164
// The Option Iterators
21512165
/////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)