@@ -618,10 +618,14 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
618618 F : FnOnce ( & mut T ) -> & mut U ,
619619 U : ?Sized ,
620620 {
621- let mut orig = ManuallyDrop :: new ( orig) ;
622- let value = NonNull :: from ( f ( & mut * orig) ) ;
621+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
622+ // was created, and have been upheld throughout `map` and/or `try_map`.
623+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
624+ // passed to it. If the closure panics, the guard will be dropped.
625+ let data = NonNull :: from ( f ( unsafe { & mut * orig. lock . data . get ( ) } ) ) ;
626+ let orig = ManuallyDrop :: new ( orig) ;
623627 MappedMutexGuard {
624- data : value ,
628+ data,
625629 inner_state : & orig. lock . state ,
626630 poison : orig. poison . clone ( ) ,
627631 _variance : PhantomData ,
@@ -644,15 +648,22 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
644648 F : FnOnce ( & mut T ) -> Option < & mut U > ,
645649 U : ?Sized ,
646650 {
647- let mut orig = ManuallyDrop :: new ( orig) ;
648- match f ( & mut * orig) . map ( NonNull :: from) {
649- Some ( value) => Ok ( MappedMutexGuard {
650- data : value,
651- inner_state : & orig. lock . state ,
652- poison : orig. poison . clone ( ) ,
653- _variance : PhantomData ,
654- } ) ,
655- None => Err ( ManuallyDrop :: into_inner ( orig) ) ,
651+ // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
652+ // was created, and have been upheld throughout `map` and/or `try_map`.
653+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
654+ // passed to it. If the closure panics, the guard will be dropped.
655+ match f ( unsafe { & mut * orig. lock . data . get ( ) } ) {
656+ Some ( data) => {
657+ let data = NonNull :: from ( data) ;
658+ let orig = ManuallyDrop :: new ( orig) ;
659+ Ok ( MappedMutexGuard {
660+ data,
661+ inner_state : & orig. lock . state ,
662+ poison : orig. poison . clone ( ) ,
663+ _variance : PhantomData ,
664+ } )
665+ }
666+ None => Err ( orig) ,
656667 }
657668 }
658669}
@@ -708,16 +719,20 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
708719 /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
709720 /// same name on the contents of the `MutexGuard` used through `Deref`.
710721 #[ unstable( feature = "mapped_lock_guards" , issue = "117108" ) ]
711- pub fn map < U , F > ( orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
722+ pub fn map < U , F > ( mut orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
712723 where
713724 F : FnOnce ( & mut T ) -> & mut U ,
714725 U : ?Sized ,
715726 {
716- let mut orig = ManuallyDrop :: new ( orig) ;
717- let value = NonNull :: from ( f ( & mut * orig) ) ;
727+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
728+ // was created, and have been upheld throughout `map` and/or `try_map`.
729+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
730+ // passed to it. If the closure panics, the guard will be dropped.
731+ let data = NonNull :: from ( f ( unsafe { orig. data . as_mut ( ) } ) ) ;
732+ let orig = ManuallyDrop :: new ( orig) ;
718733 MappedMutexGuard {
719- data : value ,
720- inner_state : & orig. inner_state ,
734+ data,
735+ inner_state : orig. inner_state ,
721736 poison : orig. poison . clone ( ) ,
722737 _variance : PhantomData ,
723738 }
@@ -734,20 +749,27 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
734749 /// same name on the contents of the `MutexGuard` used through `Deref`.
735750 #[ doc( alias = "filter_map" ) ]
736751 #[ unstable( feature = "mapped_lock_guards" , issue = "117108" ) ]
737- pub fn try_map < U , F > ( orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
752+ pub fn try_map < U , F > ( mut orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
738753 where
739754 F : FnOnce ( & mut T ) -> Option < & mut U > ,
740755 U : ?Sized ,
741756 {
742- let mut orig = ManuallyDrop :: new ( orig) ;
743- match f ( & mut * orig) . map ( NonNull :: from) {
744- Some ( value) => Ok ( MappedMutexGuard {
745- data : value,
746- inner_state : & orig. inner_state ,
747- poison : orig. poison . clone ( ) ,
748- _variance : PhantomData ,
749- } ) ,
750- None => Err ( ManuallyDrop :: into_inner ( orig) ) ,
757+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
758+ // was created, and have been upheld throughout `map` and/or `try_map`.
759+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
760+ // passed to it. If the closure panics, the guard will be dropped.
761+ match f ( unsafe { orig. data . as_mut ( ) } ) {
762+ Some ( data) => {
763+ let data = NonNull :: from ( data) ;
764+ let orig = ManuallyDrop :: new ( orig) ;
765+ Ok ( MappedMutexGuard {
766+ data,
767+ inner_state : & orig. inner_state ,
768+ poison : orig. poison . clone ( ) ,
769+ _variance : PhantomData ,
770+ } )
771+ }
772+ None => Err ( orig) ,
751773 }
752774 }
753775}
0 commit comments