Skip to content

Commit 04f8630

Browse files
committed
Add comment about Mapped(Mutex|RwLockWrite)Guard variance.
1 parent ea97c1f commit 04f8630

File tree

2 files changed

+43
-35
lines changed

2 files changed

+43
-35
lines changed

Diff for: library/std/src/sync/mutex.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -238,19 +238,23 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
238238
#[must_not_suspend = "holding a MappedMutexGuard across suspend \
239239
points can cause deadlocks, delays, \
240240
and cause Futures to not implement `Send`"]
241-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
241+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
242242
#[clippy::has_significant_drop]
243243
pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
244+
// NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
245+
// `MappedMutexGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
246+
// `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
247+
// below for the correct variance over `T` (invariance).
244248
data: NonNull<T>,
245249
inner: &'a sys::Mutex,
246250
poison_flag: &'a poison::Flag,
247251
poison: poison::Guard,
248252
_variance: PhantomData<&'a mut T>,
249253
}
250254

251-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
255+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
252256
impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
253-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
257+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
254258
unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
255259

256260
impl<T> Mutex<T> {
@@ -602,7 +606,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
602606
/// This is an associated function that needs to be used as
603607
/// `MutexGuard::map(...)`. A method would interfere with methods of the
604608
/// same name on the contents of the `MutexGuard` used through `Deref`.
605-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
609+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
606610
pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
607611
where
608612
F: FnOnce(&mut T) -> &mut U,
@@ -629,7 +633,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
629633
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
630634
/// same name on the contents of the `MutexGuard` used through `Deref`.
631635
#[doc(alias = "filter_map")]
632-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
636+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
633637
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
634638
where
635639
F: FnOnce(&mut T) -> Option<&mut U>,
@@ -649,7 +653,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
649653
}
650654
}
651655

652-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
656+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
653657
impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
654658
type Target = T;
655659

@@ -658,14 +662,14 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
658662
}
659663
}
660664

661-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
665+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
662666
impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
663667
fn deref_mut(&mut self) -> &mut T {
664668
unsafe { self.data.as_mut() }
665669
}
666670
}
667671

668-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
672+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
669673
impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
670674
#[inline]
671675
fn drop(&mut self) {
@@ -676,14 +680,14 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
676680
}
677681
}
678682

679-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
683+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
680684
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
681685
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
682686
fmt::Debug::fmt(&**self, f)
683687
}
684688
}
685689

686-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
690+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
687691
impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
688692
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
689693
(**self).fmt(f)
@@ -699,7 +703,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
699703
/// This is an associated function that needs to be used as
700704
/// `MutexGuard::map(...)`. A method would interfere with methods of the
701705
/// same name on the contents of the `MutexGuard` used through `Deref`.
702-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
706+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
703707
pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
704708
where
705709
F: FnOnce(&mut T) -> &mut U,
@@ -726,7 +730,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
726730
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
727731
/// same name on the contents of the `MutexGuard` used through `Deref`.
728732
#[doc(alias = "filter_map")]
729-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
733+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
730734
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
731735
where
732736
F: FnOnce(&mut T) -> Option<&mut U>,

Diff for: library/std/src/sync/rwlock.rs

+27-23
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
158158
#[must_not_suspend = "holding a MappedRwLockReadGuard across suspend \
159159
points can cause deadlocks, delays, \
160160
and cause Futures to not implement `Send`"]
161-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
161+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
162162
#[clippy::has_significant_drop]
163163
pub struct MappedRwLockReadGuard<'a, T: ?Sized + 'a> {
164164
// NB: we use a pointer instead of `&'a T` to avoid `noalias` violations, because a
@@ -169,10 +169,10 @@ pub struct MappedRwLockReadGuard<'a, T: ?Sized + 'a> {
169169
inner_lock: &'a sys::RwLock,
170170
}
171171

172-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
172+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
173173
impl<T: ?Sized> !Send for MappedRwLockReadGuard<'_, T> {}
174174

175-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
175+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
176176
unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
177177

178178
/// RAII structure used to release the exclusive write access of a lock when
@@ -187,20 +187,24 @@ unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
187187
#[must_not_suspend = "holding a MappedRwLockWriteGuard across suspend \
188188
points can cause deadlocks, delays, \
189189
and cause Future's to not implement `Send`"]
190-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
190+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
191191
#[clippy::has_significant_drop]
192192
pub struct MappedRwLockWriteGuard<'a, T: ?Sized + 'a> {
193+
// NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
194+
// `MappedRwLockWriteGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
195+
// `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
196+
// below for the correct variance over `T` (invariance).
193197
data: NonNull<T>,
194198
inner_lock: &'a sys::RwLock,
195199
poison_flag: &'a poison::Flag,
196200
poison: poison::Guard,
197201
_variance: PhantomData<&'a mut T>,
198202
}
199203

200-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
204+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
201205
impl<T: ?Sized> !Send for MappedRwLockWriteGuard<'_, T> {}
202206

203-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
207+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
204208
unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockWriteGuard<'_, T> {}
205209

206210
impl<T> RwLock<T> {
@@ -621,28 +625,28 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
621625
}
622626
}
623627

624-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
628+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
625629
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
626630
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
627631
(**self).fmt(f)
628632
}
629633
}
630634

631-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
635+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
632636
impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
633637
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634638
(**self).fmt(f)
635639
}
636640
}
637641

638-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
642+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
639643
impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
640644
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641645
(**self).fmt(f)
642646
}
643647
}
644648

645-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
649+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
646650
impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
647651
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
648652
(**self).fmt(f)
@@ -677,7 +681,7 @@ impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
677681
}
678682
}
679683

680-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
684+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
681685
impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
682686
type Target = T;
683687

@@ -688,7 +692,7 @@ impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
688692
}
689693
}
690694

691-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
695+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
692696
impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
693697
type Target = T;
694698

@@ -699,7 +703,7 @@ impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
699703
}
700704
}
701705

702-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
706+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
703707
impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
704708
fn deref_mut(&mut self) -> &mut T {
705709
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
@@ -729,7 +733,7 @@ impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
729733
}
730734
}
731735

732-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
736+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
733737
impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
734738
fn drop(&mut self) {
735739
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
@@ -740,7 +744,7 @@ impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
740744
}
741745
}
742746

743-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
747+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
744748
impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
745749
fn drop(&mut self) {
746750
self.poison_flag.done(&self.poison);
@@ -762,7 +766,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
762766
/// `RwLockReadGuard::map(...)`. A method would interfere with methods of
763767
/// the same name on the contents of the `RwLockReadGuard` used through
764768
/// `Deref`.
765-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
769+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
766770
pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
767771
where
768772
F: FnOnce(&T) -> &U,
@@ -784,7 +788,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
784788
/// of the same name on the contents of the `RwLockReadGuard` used through
785789
/// `Deref`.
786790
#[doc(alias = "filter_map")]
787-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
791+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
788792
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
789793
where
790794
F: FnOnce(&T) -> Option<&U>,
@@ -808,7 +812,7 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
808812
/// `MappedRwLockReadGuard::map(...)`. A method would interfere with
809813
/// methods of the same name on the contents of the `MappedRwLockReadGuard`
810814
/// used through `Deref`.
811-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
815+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
812816
pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
813817
where
814818
F: FnOnce(&T) -> &U,
@@ -830,7 +834,7 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
830834
/// methods of the same name on the contents of the `MappedRwLockReadGuard`
831835
/// used through `Deref`.
832836
#[doc(alias = "filter_map")]
833-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
837+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
834838
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
835839
where
836840
F: FnOnce(&T) -> Option<&U>,
@@ -854,7 +858,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
854858
/// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
855859
/// the same name on the contents of the `RwLockWriteGuard` used through
856860
/// `Deref`.
857-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
861+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
858862
pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
859863
where
860864
F: FnOnce(&mut T) -> &mut U,
@@ -882,7 +886,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
882886
/// of the same name on the contents of the `RwLockWriteGuard` used through
883887
/// `Deref`.
884888
#[doc(alias = "filter_map")]
885-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
889+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
886890
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
887891
where
888892
F: FnOnce(&mut T) -> Option<&mut U>,
@@ -912,7 +916,7 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
912916
/// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
913917
/// methods of the same name on the contents of the `MappedRwLockWriteGuard`
914918
/// used through `Deref`.
915-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
919+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
916920
pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
917921
where
918922
F: FnOnce(&mut T) -> &mut U,
@@ -940,7 +944,7 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
940944
/// methods of the same name on the contents of the `MappedRwLockWriteGuard`
941945
/// used through `Deref`.
942946
#[doc(alias = "filter_map")]
943-
#[unstable(feature = "mapped_lock_guards", issue = "none")]
947+
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
944948
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
945949
where
946950
F: FnOnce(&mut T) -> Option<&mut U>,

0 commit comments

Comments
 (0)