376376
377377use crate :: cmp:: { self , PartialEq , PartialOrd } ;
378378use crate :: fmt;
379+ use crate :: hash:: { Hash , Hasher } ;
379380use crate :: marker:: { Sized , Unpin } ;
380381use crate :: ops:: { CoerceUnsized , Deref , DerefMut , DispatchFromDyn , Receiver } ;
381382
@@ -390,55 +391,78 @@ use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver};
390391/// [`Unpin`]: ../../std/marker/trait.Unpin.html
391392/// [`pin` module]: ../../std/pin/index.html
392393//
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 .
396397#[ stable( feature = "pin" , since = "1.33.0" ) ]
397398#[ lang = "pin" ]
398399#[ fundamental]
399400#[ repr( transparent) ]
400- #[ derive( Copy , Clone , Hash , Eq , Ord ) ]
401+ #[ derive( Copy , Clone ) ]
401402pub struct Pin < P > {
402403 pointer : P ,
403404}
404405
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 >
407414where
408- P : PartialEq < Q > ,
415+ P :: Target : PartialEq < Q :: Target > ,
409416{
410417 fn eq ( & self , other : & Pin < Q > ) -> bool {
411- self . pointer == other. pointer
418+ P :: Target :: eq ( self , other)
412419 }
413420
414421 fn ne ( & self , other : & Pin < Q > ) -> bool {
415- self . pointer != other. pointer
422+ P :: Target :: ne ( self , other)
416423 }
417424}
418425
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 >
421431where
422- P : PartialOrd < Q > ,
432+ P :: Target : PartialOrd < Q :: Target > ,
423433{
424434 fn partial_cmp ( & self , other : & Pin < Q > ) -> Option < cmp:: Ordering > {
425- self . pointer . partial_cmp ( & other. pointer )
435+ P :: Target :: partial_cmp ( self , other)
426436 }
427437
428438 fn lt ( & self , other : & Pin < Q > ) -> bool {
429- self . pointer < other. pointer
439+ P :: Target :: lt ( self , other)
430440 }
431441
432442 fn le ( & self , other : & Pin < Q > ) -> bool {
433- self . pointer <= other. pointer
443+ P :: Target :: le ( self , other)
434444 }
435445
436446 fn gt ( & self , other : & Pin < Q > ) -> bool {
437- self . pointer > other. pointer
447+ P :: Target :: gt ( self , other)
438448 }
439449
440450 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) ;
442466 }
443467}
444468
0 commit comments