@@ -612,10 +612,14 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
612612 F : FnOnce ( & mut T ) -> & mut U ,
613613 U : ?Sized ,
614614 {
615- let mut orig = ManuallyDrop :: new ( orig) ;
616- let value = NonNull :: from ( f ( & mut * orig) ) ;
615+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
616+ // was created, and have been upheld throughout `map` and/or `try_map`.
617+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
618+ // passed to it. If the closure panics, the guard will be dropped.
619+ let data = NonNull :: from ( f ( unsafe { & mut * orig. lock . data . get ( ) } ) ) ;
620+ let orig = ManuallyDrop :: new ( orig) ;
617621 MappedMutexGuard {
618- data : value ,
622+ data,
619623 inner : & orig. lock . inner ,
620624 poison_flag : & orig. lock . poison ,
621625 poison : orig. poison . clone ( ) ,
@@ -639,16 +643,23 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
639643 F : FnOnce ( & mut T ) -> Option < & mut U > ,
640644 U : ?Sized ,
641645 {
642- let mut orig = ManuallyDrop :: new ( orig) ;
643- match f ( & mut * orig) . map ( NonNull :: from) {
644- Some ( value) => Ok ( MappedMutexGuard {
645- data : value,
646- inner : & orig. lock . inner ,
647- poison_flag : & orig. lock . poison ,
648- poison : orig. poison . clone ( ) ,
649- _variance : PhantomData ,
650- } ) ,
651- None => Err ( ManuallyDrop :: into_inner ( orig) ) ,
646+ // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
647+ // was created, and have been upheld throughout `map` and/or `try_map`.
648+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
649+ // passed to it. If the closure panics, the guard will be dropped.
650+ match f ( unsafe { & mut * orig. lock . data . get ( ) } ) {
651+ Some ( data) => {
652+ let data = NonNull :: from ( data) ;
653+ let orig = ManuallyDrop :: new ( orig) ;
654+ Ok ( MappedMutexGuard {
655+ data,
656+ inner : & orig. lock . inner ,
657+ poison_flag : & orig. lock . poison ,
658+ poison : orig. poison . clone ( ) ,
659+ _variance : PhantomData ,
660+ } )
661+ }
662+ None => Err ( orig) ,
652663 }
653664 }
654665}
@@ -704,15 +715,19 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
704715 /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
705716 /// same name on the contents of the `MutexGuard` used through `Deref`.
706717 #[ unstable( feature = "mapped_lock_guards" , issue = "117108" ) ]
707- pub fn map < U , F > ( orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
718+ pub fn map < U , F > ( mut orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
708719 where
709720 F : FnOnce ( & mut T ) -> & mut U ,
710721 U : ?Sized ,
711722 {
712- let mut orig = ManuallyDrop :: new ( orig) ;
713- let value = NonNull :: from ( f ( & mut * orig) ) ;
723+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
724+ // was created, and have been upheld throughout `map` and/or `try_map`.
725+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
726+ // passed to it. If the closure panics, the guard will be dropped.
727+ let data = NonNull :: from ( f ( unsafe { orig. data . as_mut ( ) } ) ) ;
728+ let orig = ManuallyDrop :: new ( orig) ;
714729 MappedMutexGuard {
715- data : value ,
730+ data,
716731 inner : orig. inner ,
717732 poison_flag : orig. poison_flag ,
718733 poison : orig. poison . clone ( ) ,
@@ -731,21 +746,28 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
731746 /// same name on the contents of the `MutexGuard` used through `Deref`.
732747 #[ doc( alias = "filter_map" ) ]
733748 #[ unstable( feature = "mapped_lock_guards" , issue = "117108" ) ]
734- pub fn try_map < U , F > ( orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
749+ pub fn try_map < U , F > ( mut orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
735750 where
736751 F : FnOnce ( & mut T ) -> Option < & mut U > ,
737752 U : ?Sized ,
738753 {
739- let mut orig = ManuallyDrop :: new ( orig) ;
740- match f ( & mut * orig) . map ( NonNull :: from) {
741- Some ( value) => Ok ( MappedMutexGuard {
742- data : value,
743- inner : orig. inner ,
744- poison_flag : orig. poison_flag ,
745- poison : orig. poison . clone ( ) ,
746- _variance : PhantomData ,
747- } ) ,
748- None => Err ( ManuallyDrop :: into_inner ( orig) ) ,
754+ // SAFETY: the conditions of `MutedGuard::new` were satisfied when the original guard
755+ // was created, and have been upheld throughout `map` and/or `try_map`.
756+ // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
757+ // passed to it. If the closure panics, the guard will be dropped.
758+ match f ( unsafe { orig. data . as_mut ( ) } ) {
759+ Some ( data) => {
760+ let data = NonNull :: from ( data) ;
761+ let orig = ManuallyDrop :: new ( orig) ;
762+ Ok ( MappedMutexGuard {
763+ data,
764+ inner : orig. inner ,
765+ poison_flag : orig. poison_flag ,
766+ poison : orig. poison . clone ( ) ,
767+ _variance : PhantomData ,
768+ } )
769+ }
770+ None => Err ( orig) ,
749771 }
750772 }
751773}
0 commit comments