@@ -557,8 +557,7 @@ use crate::iter::{self, FromIterator, FusedIterator, TrustedLen};
557557use crate :: panicking:: { panic, panic_str} ;
558558use crate :: pin:: Pin ;
559559use crate :: {
560- cmp, convert, hint, mem,
561- num:: NonZero ,
560+ convert, hint, mem,
562561 ops:: { self , ControlFlow , Deref , DerefMut } ,
563562 slice,
564563} ;
@@ -568,7 +567,7 @@ use crate::{
568567#[ rustc_diagnostic_item = "Option" ]
569568#[ lang = "Option" ]
570569#[ stable( feature = "rust1" , since = "1.0.0" ) ]
571- #[ allow( clippy:: derived_hash_with_manual_eq) ] // PartialEq is specialized
570+ #[ allow( clippy:: derived_hash_with_manual_eq) ] // PartialEq is manually implemented equivalently
572571pub enum Option < T > {
573572 /// No value.
574573 #[ lang = "None" ]
@@ -2146,86 +2145,26 @@ impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
21462145 }
21472146}
21482147
2148+ // Ideally, LLVM should be able to optimize our derive code to this.
2149+ // Once https://github.com/llvm/llvm-project/issues/52622 is fixed, we can
2150+ // go back to deriving `PartialEq`.
21492151#[ stable( feature = "rust1" , since = "1.0.0" ) ]
21502152impl < T > crate :: marker:: StructuralPartialEq for Option < T > { }
21512153#[ stable( feature = "rust1" , since = "1.0.0" ) ]
21522154impl < T : PartialEq > PartialEq for Option < T > {
21532155 #[ inline]
21542156 fn eq ( & self , other : & Self ) -> bool {
2155- SpecOptionPartialEq :: eq ( self , other)
2156- }
2157- }
2158-
2159- /// This specialization trait is a workaround for LLVM not currently (2023-01)
2160- /// being able to optimize this itself, even though Alive confirms that it would
2161- /// be legal to do so: <https://github.com/llvm/llvm-project/issues/52622>
2162- ///
2163- /// Once that's fixed, `Option` should go back to deriving `PartialEq`, as
2164- /// it used to do before <https://github.com/rust-lang/rust/pull/103556>.
2165- #[ unstable( feature = "spec_option_partial_eq" , issue = "none" , reason = "exposed only for rustc" ) ]
2166- #[ doc( hidden) ]
2167- pub trait SpecOptionPartialEq : Sized {
2168- fn eq ( l : & Option < Self > , other : & Option < Self > ) -> bool ;
2169- }
2170-
2171- #[ unstable( feature = "spec_option_partial_eq" , issue = "none" , reason = "exposed only for rustc" ) ]
2172- impl < T : PartialEq > SpecOptionPartialEq for T {
2173- #[ inline]
2174- default fn eq ( l : & Option < T > , r : & Option < T > ) -> bool {
2175- match ( l, r) {
2157+ // Spelling out the cases explicitly optimizes better than
2158+ // `_ => false`
2159+ match ( self , other) {
21762160 ( Some ( l) , Some ( r) ) => * l == * r,
2161+ ( Some ( _) , None ) => false ,
2162+ ( None , Some ( _) ) => false ,
21772163 ( None , None ) => true ,
2178- _ => false ,
21792164 }
21802165 }
21812166}
21822167
2183- macro_rules! non_zero_option {
2184- ( $( #[ $stability: meta] $NZ: ty; ) + ) => {
2185- $(
2186- #[ $stability]
2187- impl SpecOptionPartialEq for $NZ {
2188- #[ inline]
2189- fn eq( l: & Option <Self >, r: & Option <Self >) -> bool {
2190- l. map( Self :: get) . unwrap_or( 0 ) == r. map( Self :: get) . unwrap_or( 0 )
2191- }
2192- }
2193- ) +
2194- } ;
2195- }
2196-
2197- non_zero_option ! {
2198- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <u8 >;
2199- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <u16 >;
2200- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <u32 >;
2201- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <u64 >;
2202- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <u128 >;
2203- #[ stable( feature = "nonzero" , since = "1.28.0" ) ] NonZero <usize >;
2204- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <i8 >;
2205- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <i16 >;
2206- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <i32 >;
2207- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <i64 >;
2208- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <i128 >;
2209- #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ] NonZero <isize >;
2210- }
2211-
2212- #[ stable( feature = "nonnull" , since = "1.25.0" ) ]
2213- impl < T > SpecOptionPartialEq for crate :: ptr:: NonNull < T > {
2214- #[ inline]
2215- fn eq ( l : & Option < Self > , r : & Option < Self > ) -> bool {
2216- l. map ( Self :: as_ptr) . unwrap_or_else ( || crate :: ptr:: null_mut ( ) )
2217- == r. map ( Self :: as_ptr) . unwrap_or_else ( || crate :: ptr:: null_mut ( ) )
2218- }
2219- }
2220-
2221- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
2222- impl SpecOptionPartialEq for cmp:: Ordering {
2223- #[ inline]
2224- fn eq ( l : & Option < Self > , r : & Option < Self > ) -> bool {
2225- l. map_or ( 2 , |x| x as i8 ) == r. map_or ( 2 , |x| x as i8 )
2226- }
2227- }
2228-
22292168/////////////////////////////////////////////////////////////////////////////
22302169// The Option Iterators
22312170/////////////////////////////////////////////////////////////////////////////
0 commit comments