diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 7cc00e3f8d1b7..c43b728022d2f 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}, }; @@ -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 { @@ -2146,6 +2152,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 +}