From 3122db7d038734ab4b0d92d799763ce1ac43580d Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 17 Jan 2023 22:44:16 -0800 Subject: [PATCH 1/2] Implement `SpecOptionPartialEq` for `cmp::Ordering` --- library/core/src/option.rs | 10 +++++++++- tests/codegen/option-nonzero-eq.rs | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 7cc00e3f8d1b7..4aeb707fa6788 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -551,7 +551,7 @@ use crate::marker::Destruct; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ - convert, hint, mem, + cmp, convert, hint, mem, ops::{self, ControlFlow, Deref, DerefMut}, }; @@ -2146,6 +2146,14 @@ impl SpecOptionPartialEq for crate::ptr::NonNull { } } +#[stable(feature = "rust1", since = "1.0.0")] +impl SpecOptionPartialEq for cmp::Ordering { + #[inline] + fn eq(l: &Option, r: &Option) -> bool { + l.map_or(2, |x| x as i8) == r.map_or(2, |x| x as i8) + } +} + ///////////////////////////////////////////////////////////////////////////// // The Option Iterators ///////////////////////////////////////////////////////////////////////////// diff --git a/tests/codegen/option-nonzero-eq.rs b/tests/codegen/option-nonzero-eq.rs index 598dcc19b491b..835decd3e5f5e 100644 --- a/tests/codegen/option-nonzero-eq.rs +++ b/tests/codegen/option-nonzero-eq.rs @@ -3,6 +3,7 @@ #![crate_type = "lib"] extern crate core; +use core::cmp::Ordering; use core::num::{NonZeroU32, NonZeroI64}; use core::ptr::NonNull; @@ -32,3 +33,12 @@ pub fn non_null_eq(l: Option>, r: Option>) -> bool { // CHECK-NEXT: ret i1 l == r } + +// CHECK-lABEL: @ordering_eq +#[no_mangle] +pub fn ordering_eq(l: Option, r: Option) -> bool { + // CHECK: start: + // CHECK-NEXT: icmp eq i8 + // CHECK-NEXT: ret i1 + l == r +} From 3e9d1e40cb2a4dc1e1d303e9d9fa382c34106277 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 27 Jan 2023 19:09:52 -0800 Subject: [PATCH 2/2] Link to the LLVM issue from a comment on `SpecOptionPartialEq` --- library/core/src/option.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4aeb707fa6788..c43b728022d2f 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -2090,6 +2090,12 @@ impl PartialEq for Option { } } +/// This specialization trait is a workaround for LLVM not currently (2023-01) +/// being able to optimize this itself, even though Alive confirms that it would +/// be legal to do so: +/// +/// Once that's fixed, `Option` should go back to deriving `PartialEq`, as +/// it used to do before . #[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")] #[doc(hidden)] pub trait SpecOptionPartialEq: Sized {