@@ -618,10 +618,14 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
618
618
F : FnOnce ( & mut T ) -> & mut U ,
619
619
U : ?Sized ,
620
620
{
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) ;
623
627
MappedMutexGuard {
624
- data : value ,
628
+ data,
625
629
inner_state : & orig. lock . state ,
626
630
poison : orig. poison . clone ( ) ,
627
631
_variance : PhantomData ,
@@ -644,15 +648,22 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
644
648
F : FnOnce ( & mut T ) -> Option < & mut U > ,
645
649
U : ?Sized ,
646
650
{
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) ,
656
667
}
657
668
}
658
669
}
@@ -708,16 +719,20 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
708
719
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
709
720
/// same name on the contents of the `MutexGuard` used through `Deref`.
710
721
#[ 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 >
712
723
where
713
724
F : FnOnce ( & mut T ) -> & mut U ,
714
725
U : ?Sized ,
715
726
{
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) ;
718
733
MappedMutexGuard {
719
- data : value ,
720
- inner_state : & orig. inner_state ,
734
+ data,
735
+ inner_state : orig. inner_state ,
721
736
poison : orig. poison . clone ( ) ,
722
737
_variance : PhantomData ,
723
738
}
@@ -734,20 +749,27 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
734
749
/// same name on the contents of the `MutexGuard` used through `Deref`.
735
750
#[ doc( alias = "filter_map" ) ]
736
751
#[ 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 >
738
753
where
739
754
F : FnOnce ( & mut T ) -> Option < & mut U > ,
740
755
U : ?Sized ,
741
756
{
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) ,
751
773
}
752
774
}
753
775
}
0 commit comments