@@ -233,7 +233,17 @@ pub trait ToStableHashKey<HCX> {
233233/// - `DefIndex`, `CrateNum`, `LocalDefId`, because their concrete
234234/// values depend on state that might be different between
235235/// compilation sessions.
236- pub unsafe trait StableOrd : Ord { }
236+ ///
237+ /// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether
238+ /// unstable sorting can be used for this type. Set to true if and
239+ /// only if `a == b` implies `a` and `b` are fully indistinguishable.
240+ pub unsafe trait StableOrd : Ord {
241+ const CAN_USE_UNSTABLE_SORT : bool ;
242+ }
243+
244+ unsafe impl < T : StableOrd > StableOrd for & T {
245+ const CAN_USE_UNSTABLE_SORT : bool = T :: CAN_USE_UNSTABLE_SORT ;
246+ }
237247
238248/// Implement HashStable by just calling `Hash::hash()`. Also implement `StableOrd` for the type since
239249/// that has the same requirements.
@@ -253,7 +263,9 @@ macro_rules! impl_stable_traits_for_trivial_type {
253263 }
254264 }
255265
256- unsafe impl $crate:: stable_hasher:: StableOrd for $t { }
266+ unsafe impl $crate:: stable_hasher:: StableOrd for $t {
267+ const CAN_USE_UNSTABLE_SORT : bool = true ;
268+ }
257269 } ;
258270}
259271
@@ -339,7 +351,9 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2)
339351 }
340352}
341353
342- unsafe impl < T1 : StableOrd , T2 : StableOrd > StableOrd for ( T1 , T2 ) { }
354+ unsafe impl < T1 : StableOrd , T2 : StableOrd > StableOrd for ( T1 , T2 ) {
355+ const CAN_USE_UNSTABLE_SORT : bool = T1 :: CAN_USE_UNSTABLE_SORT && T2 :: CAN_USE_UNSTABLE_SORT ;
356+ }
343357
344358impl < T1 , T2 , T3 , CTX > HashStable < CTX > for ( T1 , T2 , T3 )
345359where
@@ -355,7 +369,10 @@ where
355369 }
356370}
357371
358- unsafe impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd > StableOrd for ( T1 , T2 , T3 ) { }
372+ unsafe impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd > StableOrd for ( T1 , T2 , T3 ) {
373+ const CAN_USE_UNSTABLE_SORT : bool =
374+ T1 :: CAN_USE_UNSTABLE_SORT && T2 :: CAN_USE_UNSTABLE_SORT && T3 :: CAN_USE_UNSTABLE_SORT ;
375+ }
359376
360377impl < T1 , T2 , T3 , T4 , CTX > HashStable < CTX > for ( T1 , T2 , T3 , T4 )
361378where
@@ -376,6 +393,10 @@ where
376393unsafe impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd , T4 : StableOrd > StableOrd
377394 for ( T1 , T2 , T3 , T4 )
378395{
396+ const CAN_USE_UNSTABLE_SORT : bool = T1 :: CAN_USE_UNSTABLE_SORT
397+ && T2 :: CAN_USE_UNSTABLE_SORT
398+ && T3 :: CAN_USE_UNSTABLE_SORT
399+ && T4 :: CAN_USE_UNSTABLE_SORT ;
379400}
380401
381402impl < T : HashStable < CTX > , CTX > HashStable < CTX > for [ T ] {
@@ -468,7 +489,9 @@ impl<CTX> HashStable<CTX> for str {
468489 }
469490}
470491
471- unsafe impl StableOrd for & str { }
492+ unsafe impl StableOrd for & str {
493+ const CAN_USE_UNSTABLE_SORT : bool = true ;
494+ }
472495
473496impl < CTX > HashStable < CTX > for String {
474497 #[ inline]
@@ -479,7 +502,9 @@ impl<CTX> HashStable<CTX> for String {
479502
480503// Safety: String comparison only depends on their contents and the
481504// contents are not changed by (de-)serialization.
482- unsafe impl StableOrd for String { }
505+ unsafe impl StableOrd for String {
506+ const CAN_USE_UNSTABLE_SORT : bool = true ;
507+ }
483508
484509impl < HCX > ToStableHashKey < HCX > for String {
485510 type KeyType = String ;
@@ -505,7 +530,9 @@ impl<CTX> HashStable<CTX> for bool {
505530}
506531
507532// Safety: sort order of bools is not changed by (de-)serialization.
508- unsafe impl StableOrd for bool { }
533+ unsafe impl StableOrd for bool {
534+ const CAN_USE_UNSTABLE_SORT : bool = true ;
535+ }
509536
510537impl < T , CTX > HashStable < CTX > for Option < T >
511538where
@@ -523,7 +550,9 @@ where
523550}
524551
525552// Safety: the Option wrapper does not add instability to comparison.
526- unsafe impl < T : StableOrd > StableOrd for Option < T > { }
553+ unsafe impl < T : StableOrd > StableOrd for Option < T > {
554+ const CAN_USE_UNSTABLE_SORT : bool = T :: CAN_USE_UNSTABLE_SORT ;
555+ }
527556
528557impl < T1 , T2 , CTX > HashStable < CTX > for Result < T1 , T2 >
529558where
0 commit comments