@@ -612,10 +612,14 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
612
612
F : FnOnce ( & mut T ) -> & mut U ,
613
613
U : ?Sized ,
614
614
{
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) ;
617
621
MappedMutexGuard {
618
- data : value ,
622
+ data,
619
623
inner : & orig. lock . inner ,
620
624
poison_flag : & orig. lock . poison ,
621
625
poison : orig. poison . clone ( ) ,
@@ -639,16 +643,23 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
639
643
F : FnOnce ( & mut T ) -> Option < & mut U > ,
640
644
U : ?Sized ,
641
645
{
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) ,
652
663
}
653
664
}
654
665
}
@@ -704,15 +715,19 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
704
715
/// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
705
716
/// same name on the contents of the `MutexGuard` used through `Deref`.
706
717
#[ 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 >
708
719
where
709
720
F : FnOnce ( & mut T ) -> & mut U ,
710
721
U : ?Sized ,
711
722
{
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) ;
714
729
MappedMutexGuard {
715
- data : value ,
730
+ data,
716
731
inner : orig. inner ,
717
732
poison_flag : orig. poison_flag ,
718
733
poison : orig. poison . clone ( ) ,
@@ -731,21 +746,28 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
731
746
/// same name on the contents of the `MutexGuard` used through `Deref`.
732
747
#[ doc( alias = "filter_map" ) ]
733
748
#[ 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 >
735
750
where
736
751
F : FnOnce ( & mut T ) -> Option < & mut U > ,
737
752
U : ?Sized ,
738
753
{
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) ,
749
771
}
750
772
}
751
773
}
0 commit comments