376
376
377
377
use crate :: cmp:: { self , PartialEq , PartialOrd } ;
378
378
use crate :: fmt;
379
+ use crate :: hash:: { Hash , Hasher } ;
379
380
use crate :: marker:: { Sized , Unpin } ;
380
381
use crate :: ops:: { CoerceUnsized , Deref , DerefMut , DispatchFromDyn , Receiver } ;
381
382
@@ -390,55 +391,78 @@ use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
390
391
/// [`Unpin`]: ../../std/marker/trait.Unpin.html
391
392
/// [`pin` module]: ../../std/pin/index.html
392
393
//
393
- // Note: the derives below, and the explicit `PartialEq` and `PartialOrd`
394
- // implementations, are allowed because they all only use `&P`, so they cannot move
395
- // the value behind `pointer` .
394
+ // Note: the `Clone` derive below causes unsoundness as it's possible to implement
395
+ // `Clone` for mutable references.
396
+ // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311> for more details .
396
397
#[ stable( feature = "pin" , since = "1.33.0" ) ]
397
398
#[ lang = "pin" ]
398
399
#[ fundamental]
399
400
#[ repr( transparent) ]
400
- #[ derive( Copy , Clone , Hash , Eq , Ord ) ]
401
+ #[ derive( Copy , Clone ) ]
401
402
pub struct Pin < P > {
402
403
pointer : P ,
403
404
}
404
405
405
- #[ stable( feature = "pin_partialeq_partialord_impl_applicability" , since = "1.34.0" ) ]
406
- impl < P , Q > PartialEq < Pin < Q > > for Pin < P >
406
+ // The following implementations aren't derived in order to avoid soundness
407
+ // issues. `&self.pointer` should not be accessible to untrusted trait
408
+ // implementations.
409
+ //
410
+ // See <https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73> for more details.
411
+
412
+ #[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
413
+ impl < P : Deref , Q : Deref > PartialEq < Pin < Q > > for Pin < P >
407
414
where
408
- P : PartialEq < Q > ,
415
+ P :: Target : PartialEq < Q :: Target > ,
409
416
{
410
417
fn eq ( & self , other : & Pin < Q > ) -> bool {
411
- self . pointer == other. pointer
418
+ P :: Target :: eq ( self , other)
412
419
}
413
420
414
421
fn ne ( & self , other : & Pin < Q > ) -> bool {
415
- self . pointer != other. pointer
422
+ P :: Target :: ne ( self , other)
416
423
}
417
424
}
418
425
419
- #[ stable( feature = "pin_partialeq_partialord_impl_applicability" , since = "1.34.0" ) ]
420
- impl < P , Q > PartialOrd < Pin < Q > > for Pin < P >
426
+ #[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
427
+ impl < P : Deref < Target : Eq > > Eq for Pin < P > { }
428
+
429
+ #[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
430
+ impl < P : Deref , Q : Deref > PartialOrd < Pin < Q > > for Pin < P >
421
431
where
422
- P : PartialOrd < Q > ,
432
+ P :: Target : PartialOrd < Q :: Target > ,
423
433
{
424
434
fn partial_cmp ( & self , other : & Pin < Q > ) -> Option < cmp:: Ordering > {
425
- self . pointer . partial_cmp ( & other. pointer )
435
+ P :: Target :: partial_cmp ( self , other)
426
436
}
427
437
428
438
fn lt ( & self , other : & Pin < Q > ) -> bool {
429
- self . pointer < other. pointer
439
+ P :: Target :: lt ( self , other)
430
440
}
431
441
432
442
fn le ( & self , other : & Pin < Q > ) -> bool {
433
- self . pointer <= other. pointer
443
+ P :: Target :: le ( self , other)
434
444
}
435
445
436
446
fn gt ( & self , other : & Pin < Q > ) -> bool {
437
- self . pointer > other. pointer
447
+ P :: Target :: gt ( self , other)
438
448
}
439
449
440
450
fn ge ( & self , other : & Pin < Q > ) -> bool {
441
- self . pointer >= other. pointer
451
+ P :: Target :: ge ( self , other)
452
+ }
453
+ }
454
+
455
+ #[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
456
+ impl < P : Deref < Target : Ord > > Ord for Pin < P > {
457
+ fn cmp ( & self , other : & Self ) -> cmp:: Ordering {
458
+ P :: Target :: cmp ( self , other)
459
+ }
460
+ }
461
+
462
+ #[ stable( feature = "pin_trait_impls" , since = "1.41.0" ) ]
463
+ impl < P : Deref < Target : Hash > > Hash for Pin < P > {
464
+ fn hash < H : Hasher > ( & self , state : & mut H ) {
465
+ P :: Target :: hash ( self , state) ;
442
466
}
443
467
}
444
468
0 commit comments