@@ -8,8 +8,8 @@ use crate::sys::sync as sys;
88
99/// A mutual exclusion primitive useful for protecting shared data.
1010///
11- /// For more information about mutexes, check out the documentation for the
12- /// poisoning variant of this lock found at [std::sync:: poison::Mutex](crate::sync::poison::Mutex).
11+ /// For more information about mutexes, check out the documentation for the poisoning variant of
12+ /// this lock (which can be found at [` poison::Mutex`])
1313///
1414/// # Example
1515///
@@ -47,17 +47,37 @@ use crate::sys::sync as sys;
4747/// rx.recv().unwrap();
4848/// ```
4949///
50+ /// [`poison::Mutex`]: crate::sync::poison::Mutex
5051#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
5152#[ cfg_attr( not( test) , rustc_diagnostic_item = "NonPoisonMutex" ) ]
5253pub struct Mutex < T : ?Sized > {
5354 inner : sys:: Mutex ,
5455 data : UnsafeCell < T > ,
5556}
5657
57- // these are the only places where `T: Send` matters; all other
58- // functionality works fine on a single thread.
58+ /// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
59+ /// the owned `T` from the `Mutex` via [`into_inner`].
60+ ///
61+ /// [`into_inner`]: Mutex::into_inner
5962#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
6063unsafe impl < T : ?Sized + Send > Send for Mutex < T > { }
64+
65+ /// `T` must be `Send` for [`Mutex`] to be `Sync`.
66+ /// This ensures that the protected data can be accessed safely from multiple threads
67+ /// without causing data races or other unsafe behavior.
68+ ///
69+ /// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
70+ /// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
71+ /// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
72+ /// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
73+ /// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
74+ /// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
75+ /// to potential data races.
76+ ///
77+ /// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
78+ /// to one thread at a time if `T` is not `Sync`.
79+ ///
80+ /// [`Rc`]: crate::rc::Rc
6181#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
6282unsafe impl < T : ?Sized + Send > Sync for Mutex < T > { }
6383
@@ -110,6 +130,7 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
110130#[ must_not_suspend = "holding a MappedMutexGuard across suspend \
111131 points can cause deadlocks, delays, \
112132 and cause Futures to not implement `Send`"]
133+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
113134#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
114135#[ clippy:: has_significant_drop]
115136pub struct MappedMutexGuard < ' a , T : ?Sized + ' a > {
@@ -122,8 +143,10 @@ pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
122143 _variance : PhantomData < & ' a mut T > ,
123144}
124145
146+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
125147#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
126148impl < T : ?Sized > !Send for MappedMutexGuard < ' _ , T > { }
149+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
127150#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
128151unsafe impl < T : ?Sized + Sync > Sync for MappedMutexGuard < ' _ , T > { }
129152
@@ -143,6 +166,8 @@ impl<T> Mutex<T> {
143166 pub const fn new ( t : T ) -> Mutex < T > {
144167 Mutex { inner : sys:: Mutex :: new ( ) , data : UnsafeCell :: new ( t) }
145168 }
169+
170+ // TODO(connor): Add `lock_value_accessors` feature methods.
146171}
147172
148173impl < T : ?Sized > Mutex < T > {
@@ -197,6 +222,9 @@ impl<T: ?Sized> Mutex<T> {
197222 ///
198223 /// If the mutex could not be acquired because it is already locked, then
199224 /// this call will return [`None`].
225+ ///
226+ /// TODO(connor): This should return a `TryLockResult` as specified in
227+ /// <https://github.com/rust-lang/rust/issues/134645>
200228 ///
201229 /// # Examples
202230 ///
@@ -235,7 +263,6 @@ impl<T: ?Sized> Mutex<T> {
235263 /// assert_eq!(mutex.into_inner(), 0);
236264 /// ```
237265 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
238- #[ inline]
239266 pub fn into_inner ( self ) -> T
240267 where
241268 T : Sized ,
@@ -259,10 +286,11 @@ impl<T: ?Sized> Mutex<T> {
259286 /// assert_eq!(*mutex.lock(), 10);
260287 /// ```
261288 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
262- #[ inline]
263289 pub fn get_mut ( & mut self ) -> & mut T {
264290 self . data . get_mut ( )
265291 }
292+
293+ // TODO(connor): Add `mutex_data_ptr` feature method.
266294}
267295
268296#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
@@ -330,14 +358,14 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
330358 }
331359}
332360
333- #[ stable ( feature = "std_debug " , since = "1.16.0 " ) ]
361+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
334362impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MutexGuard < ' _ , T > {
335363 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
336364 fmt:: Debug :: fmt ( & * * self , f)
337365 }
338366}
339367
340- #[ stable ( feature = "std_guard_impls " , since = "1.20.0 " ) ]
368+ #[ unstable ( feature = "nonpoison_mutex " , issue = "134645 " ) ]
341369impl < T : ?Sized + fmt:: Display > fmt:: Display for MutexGuard < ' _ , T > {
342370 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
343371 ( * * self ) . fmt ( f)
@@ -353,6 +381,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
353381 /// This is an associated function that needs to be used as
354382 /// `MutexGuard::map(...)`. A method would interfere with methods of the
355383 /// same name on the contents of the `MutexGuard` used through `Deref`.
384+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
356385 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
357386 pub fn map < U , F > ( orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
358387 where
@@ -378,6 +407,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
378407 /// `MutexGuard::try_map(...)`. A method would interfere with methods of the
379408 /// same name on the contents of the `MutexGuard` used through `Deref`.
380409 #[ doc( alias = "filter_map" ) ]
410+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
381411 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
382412 pub fn try_map < U , F > ( orig : Self , f : F ) -> Result < MappedMutexGuard < ' a , U > , Self >
383413 where
@@ -399,6 +429,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
399429 }
400430}
401431
432+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
402433#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
403434impl < T : ?Sized > Deref for MappedMutexGuard < ' _ , T > {
404435 type Target = T ;
@@ -408,13 +439,15 @@ impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
408439 }
409440}
410441
442+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
411443#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
412444impl < T : ?Sized > DerefMut for MappedMutexGuard < ' _ , T > {
413445 fn deref_mut ( & mut self ) -> & mut T {
414446 unsafe { self . data . as_mut ( ) }
415447 }
416448}
417449
450+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
418451#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
419452impl < T : ?Sized > Drop for MappedMutexGuard < ' _ , T > {
420453 #[ inline]
@@ -425,13 +458,15 @@ impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
425458 }
426459}
427460
461+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
428462#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
429463impl < T : ?Sized + fmt:: Debug > fmt:: Debug for MappedMutexGuard < ' _ , T > {
430464 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
431465 fmt:: Debug :: fmt ( & * * self , f)
432466 }
433467}
434468
469+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
435470#[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
436471impl < T : ?Sized + fmt:: Display > fmt:: Display for MappedMutexGuard < ' _ , T > {
437472 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
@@ -448,6 +483,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
448483 /// This is an associated function that needs to be used as
449484 /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
450485 /// same name on the contents of the `MutexGuard` used through `Deref`.
486+ // #[unstable(feature = "mapped_lock_guards", issue = "117108")]
451487 #[ unstable( feature = "nonpoison_mutex" , issue = "134645" ) ]
452488 pub fn map < U , F > ( mut orig : Self , f : F ) -> MappedMutexGuard < ' a , U >
453489 where
0 commit comments