@@ -558,17 +558,16 @@ use crate::panicking::{panic, panic_str};
558
558
use crate :: pin:: Pin ;
559
559
use crate :: {
560
560
cmp, convert, hint, mem,
561
- num:: NonZero ,
562
561
ops:: { self , ControlFlow , Deref , DerefMut } ,
563
562
slice,
564
563
} ;
565
564
566
565
/// The `Option` type. See [the module level documentation](self) for more.
567
- #[ derive( Copy , PartialOrd , Eq , Ord , Debug , Hash ) ]
566
+ #[ derive( Copy , Eq , Debug , Hash ) ]
568
567
#[ rustc_diagnostic_item = "Option" ]
569
568
#[ lang = "Option" ]
570
569
#[ 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
572
571
pub enum Option < T > {
573
572
/// No value.
574
573
#[ lang = "None" ]
@@ -2146,83 +2145,52 @@ impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
2146
2145
}
2147
2146
}
2148
2147
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`.
2149
2151
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2150
2152
impl < T > crate :: marker:: StructuralPartialEq for Option < T > { }
2151
2153
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2152
2154
impl < T : PartialEq > PartialEq for Option < T > {
2153
2155
#[ inline]
2154
2156
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) {
2176
2160
( Some ( l) , Some ( r) ) => * l == * r,
2161
+ ( Some ( _) , None ) => false ,
2162
+ ( None , Some ( _) ) => false ,
2177
2163
( None , None ) => true ,
2178
- _ => false ,
2179
2164
}
2180
2165
}
2181
2166
}
2182
2167
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 > {
2168
+ // Manually implementing here somewhat improves codegen for
2169
+ // https://github.com/rust-lang/rust/issues/49892, although still
2170
+ // not optimal.
2171
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
2172
+ impl < T : PartialOrd > PartialOrd for Option < T > {
2214
2173
#[ 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 ( ) )
2174
+ fn partial_cmp ( & self , other : & Self ) -> Option < cmp:: Ordering > {
2175
+ match ( self , other) {
2176
+ ( Some ( l) , Some ( r) ) => l. partial_cmp ( r) ,
2177
+ ( Some ( _) , None ) => Some ( cmp:: Ordering :: Greater ) ,
2178
+ ( None , Some ( _) ) => Some ( cmp:: Ordering :: Less ) ,
2179
+ ( None , None ) => Some ( cmp:: Ordering :: Equal ) ,
2180
+ }
2218
2181
}
2219
2182
}
2220
2183
2221
2184
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
2222
- impl SpecOptionPartialEq for cmp :: Ordering {
2185
+ impl < T : Ord > Ord for Option < T > {
2223
2186
#[ 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 )
2187
+ fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
2188
+ match ( self , other) {
2189
+ ( Some ( l) , Some ( r) ) => l. cmp ( r) ,
2190
+ ( Some ( _) , None ) => cmp:: Ordering :: Greater ,
2191
+ ( None , Some ( _) ) => cmp:: Ordering :: Less ,
2192
+ ( None , None ) => cmp:: Ordering :: Equal ,
2193
+ }
2226
2194
}
2227
2195
}
2228
2196
0 commit comments