@@ -238,12 +238,21 @@ pub trait ToStableHashKey<HCX> {
238
238
/// The associated constant `CAN_USE_UNSTABLE_SORT` denotes whether
239
239
/// unstable sorting can be used for this type. Set to true if and
240
240
/// only if `a == b` implies `a` and `b` are fully indistinguishable.
241
- pub unsafe trait StableOrd : Ord {
241
+ pub trait StableOrd : Ord {
242
242
const CAN_USE_UNSTABLE_SORT : bool ;
243
+
244
+ /// Marker to ensure that implementors have carefully considered
245
+ /// whether their `Ord` implementation obeys this trait's contract.
246
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) ;
243
247
}
244
248
245
- unsafe impl < T : StableOrd > StableOrd for & T {
249
+ impl < T : StableOrd > StableOrd for & T {
246
250
const CAN_USE_UNSTABLE_SORT : bool = T :: CAN_USE_UNSTABLE_SORT ;
251
+
252
+ // Ordering of a reference is exactly that of the referent, and since
253
+ // the ordering of the referet is stable so must be the ordering of the
254
+ // reference.
255
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
247
256
}
248
257
249
258
/// This is a companion trait to `StableOrd`. Some types like `Symbol` can be
@@ -290,8 +299,12 @@ macro_rules! impl_stable_traits_for_trivial_type {
290
299
}
291
300
}
292
301
293
- unsafe impl $crate:: stable_hasher:: StableOrd for $t {
302
+ impl $crate:: stable_hasher:: StableOrd for $t {
294
303
const CAN_USE_UNSTABLE_SORT : bool = true ;
304
+
305
+ // Encoding and decoding doesn't change the bytes of trivial types
306
+ // and `Ord::cmp` depends only on those bytes.
307
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
295
308
}
296
309
} ;
297
310
}
@@ -327,8 +340,12 @@ impl<CTX> HashStable<CTX> for Hash128 {
327
340
}
328
341
}
329
342
330
- unsafe impl StableOrd for Hash128 {
343
+ impl StableOrd for Hash128 {
331
344
const CAN_USE_UNSTABLE_SORT : bool = true ;
345
+
346
+ // Encoding and decoding doesn't change the bytes of `Hash128`
347
+ // and `Ord::cmp` depends only on those bytes.
348
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
332
349
}
333
350
334
351
impl < CTX > HashStable < CTX > for ! {
@@ -392,8 +409,12 @@ impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2)
392
409
}
393
410
}
394
411
395
- unsafe impl < T1 : StableOrd , T2 : StableOrd > StableOrd for ( T1 , T2 ) {
412
+ impl < T1 : StableOrd , T2 : StableOrd > StableOrd for ( T1 , T2 ) {
396
413
const CAN_USE_UNSTABLE_SORT : bool = T1 :: CAN_USE_UNSTABLE_SORT && T2 :: CAN_USE_UNSTABLE_SORT ;
414
+
415
+ // Ordering of tuples is a pure function of their elements' ordering, and since
416
+ // the ordering of each element is stable so must be the ordering of the tuple.
417
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
397
418
}
398
419
399
420
impl < T1 , T2 , T3 , CTX > HashStable < CTX > for ( T1 , T2 , T3 )
@@ -410,9 +431,13 @@ where
410
431
}
411
432
}
412
433
413
- unsafe impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd > StableOrd for ( T1 , T2 , T3 ) {
434
+ impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd > StableOrd for ( T1 , T2 , T3 ) {
414
435
const CAN_USE_UNSTABLE_SORT : bool =
415
436
T1 :: CAN_USE_UNSTABLE_SORT && T2 :: CAN_USE_UNSTABLE_SORT && T3 :: CAN_USE_UNSTABLE_SORT ;
437
+
438
+ // Ordering of tuples is a pure function of their elements' ordering, and since
439
+ // the ordering of each element is stable so must be the ordering of the tuple.
440
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
416
441
}
417
442
418
443
impl < T1 , T2 , T3 , T4 , CTX > HashStable < CTX > for ( T1 , T2 , T3 , T4 )
@@ -431,13 +456,15 @@ where
431
456
}
432
457
}
433
458
434
- unsafe impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd , T4 : StableOrd > StableOrd
435
- for ( T1 , T2 , T3 , T4 )
436
- {
459
+ impl < T1 : StableOrd , T2 : StableOrd , T3 : StableOrd , T4 : StableOrd > StableOrd for ( T1 , T2 , T3 , T4 ) {
437
460
const CAN_USE_UNSTABLE_SORT : bool = T1 :: CAN_USE_UNSTABLE_SORT
438
461
&& T2 :: CAN_USE_UNSTABLE_SORT
439
462
&& T3 :: CAN_USE_UNSTABLE_SORT
440
463
&& T4 :: CAN_USE_UNSTABLE_SORT ;
464
+
465
+ // Ordering of tuples is a pure function of their elements' ordering, and since
466
+ // the ordering of each element is stable so must be the ordering of the tuple.
467
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
441
468
}
442
469
443
470
impl < T : HashStable < CTX > , CTX > HashStable < CTX > for [ T ] {
@@ -530,8 +557,12 @@ impl<CTX> HashStable<CTX> for str {
530
557
}
531
558
}
532
559
533
- unsafe impl StableOrd for & str {
560
+ impl StableOrd for & str {
534
561
const CAN_USE_UNSTABLE_SORT : bool = true ;
562
+
563
+ // Encoding and decoding doesn't change the bytes of string slices
564
+ // and `Ord::cmp` depends only on those bytes.
565
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
535
566
}
536
567
537
568
impl < CTX > HashStable < CTX > for String {
@@ -541,10 +572,12 @@ impl<CTX> HashStable<CTX> for String {
541
572
}
542
573
}
543
574
544
- // Safety: String comparison only depends on their contents and the
545
- // contents are not changed by (de-)serialization.
546
- unsafe impl StableOrd for String {
575
+ impl StableOrd for String {
547
576
const CAN_USE_UNSTABLE_SORT : bool = true ;
577
+
578
+ // String comparison only depends on their contents and the
579
+ // contents are not changed by (de-)serialization.
580
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
548
581
}
549
582
550
583
impl < HCX > ToStableHashKey < HCX > for String {
@@ -570,9 +603,11 @@ impl<CTX> HashStable<CTX> for bool {
570
603
}
571
604
}
572
605
573
- // Safety: sort order of bools is not changed by (de-)serialization.
574
- unsafe impl StableOrd for bool {
606
+ impl StableOrd for bool {
575
607
const CAN_USE_UNSTABLE_SORT : bool = true ;
608
+
609
+ // sort order of bools is not changed by (de-)serialization.
610
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
576
611
}
577
612
578
613
impl < T , CTX > HashStable < CTX > for Option < T >
@@ -590,9 +625,11 @@ where
590
625
}
591
626
}
592
627
593
- // Safety: the Option wrapper does not add instability to comparison.
594
- unsafe impl < T : StableOrd > StableOrd for Option < T > {
628
+ impl < T : StableOrd > StableOrd for Option < T > {
595
629
const CAN_USE_UNSTABLE_SORT : bool = T :: CAN_USE_UNSTABLE_SORT ;
630
+
631
+ // the Option wrapper does not add instability to comparison.
632
+ const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED : ( ) = ( ) ;
596
633
}
597
634
598
635
impl < T1 , T2 , CTX > HashStable < CTX > for Result < T1 , T2 >
0 commit comments