Skip to main content

std/sync/nonpoison/
mutex.rs

1use crate::cell::UnsafeCell;
2use crate::fmt;
3use crate::marker::PhantomData;
4use crate::mem::{self, ManuallyDrop};
5use crate::ops::{Deref, DerefMut};
6use crate::ptr::NonNull;
7use crate::sync::nonpoison::{TryLockResult, WouldBlock};
8use crate::sys::sync as sys;
9
10/// A mutual exclusion primitive useful for protecting shared data that does not keep track of
11/// lock poisoning.
12///
13/// For more information about mutexes, check out the documentation for the poisoning variant of
14/// this lock at [`poison::Mutex`].
15///
16/// [`poison::Mutex`]: crate::sync::poison::Mutex
17///
18/// # Examples
19///
20/// Note that this `Mutex` does **not** propagate threads that panic while holding the lock via
21/// poisoning. If you need this functionality, see [`poison::Mutex`].
22///
23/// ```
24/// #![feature(nonpoison_mutex)]
25///
26/// use std::thread;
27/// use std::sync::{Arc, nonpoison::Mutex};
28///
29/// let mutex = Arc::new(Mutex::new(0u32));
30/// let mut handles = Vec::new();
31///
32/// for n in 0..10 {
33///     let m = Arc::clone(&mutex);
34///     let handle = thread::spawn(move || {
35///         let mut guard = m.lock();
36///         *guard += 1;
37///         panic!("panic from thread {n} {guard}")
38///     });
39///     handles.push(handle);
40/// }
41///
42/// for h in handles {
43///     let _ = h.join();
44/// }
45///
46/// println!("Finished, locked {} times", mutex.lock());
47/// ```
48#[unstable(feature = "nonpoison_mutex", issue = "134645")]
49#[cfg_attr(not(test), rustc_diagnostic_item = "NonPoisonMutex")]
50pub struct Mutex<#[rustc_assert_variance(invariant)] T: ?Sized> {
51    inner: sys::Mutex,
52    data: UnsafeCell<T>,
53}
54
55/// `T` must be `Send` for a [`Mutex`] to be `Send` because it is possible to acquire
56/// the owned `T` from the `Mutex` via [`into_inner`].
57///
58/// [`into_inner`]: Mutex::into_inner
59#[unstable(feature = "nonpoison_mutex", issue = "134645")]
60unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
61
62/// `T` must be `Send` for [`Mutex`] to be `Sync`.
63/// This ensures that the protected data can be accessed safely from multiple threads
64/// without causing data races or other unsafe behavior.
65///
66/// [`Mutex<T>`] provides mutable access to `T` to one thread at a time. However, it's essential
67/// for `T` to be `Send` because it's not safe for non-`Send` structures to be accessed in
68/// this manner. For instance, consider [`Rc`], a non-atomic reference counted smart pointer,
69/// which is not `Send`. With `Rc`, we can have multiple copies pointing to the same heap
70/// allocation with a non-atomic reference count. If we were to use `Mutex<Rc<_>>`, it would
71/// only protect one instance of `Rc` from shared access, leaving other copies vulnerable
72/// to potential data races.
73///
74/// Also note that it is not necessary for `T` to be `Sync` as `&T` is only made available
75/// to one thread at a time if `T` is not `Sync`.
76///
77/// [`Rc`]: crate::rc::Rc
78#[unstable(feature = "nonpoison_mutex", issue = "134645")]
79unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
80
81/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
82/// dropped (falls out of scope), the lock will be unlocked.
83///
84/// The data protected by the mutex can be accessed through this guard via its
85/// [`Deref`] and [`DerefMut`] implementations.
86///
87/// This structure is created by the [`lock`] and [`try_lock`] methods on
88/// [`Mutex`].
89///
90/// [`lock`]: Mutex::lock
91/// [`try_lock`]: Mutex::try_lock
92#[must_use = "if unused the Mutex will immediately unlock"]
93#[must_not_suspend = "holding a MutexGuard across suspend \
94                      points can cause deadlocks, delays, \
95                      and cause Futures to not implement `Send`"]
96#[unstable(feature = "nonpoison_mutex", issue = "134645")]
97#[clippy::has_significant_drop]
98#[cfg_attr(not(test), rustc_diagnostic_item = "NonPoisonMutexGuard")]
99pub struct MutexGuard<
100    #[rustc_assert_variance(covariant)] 'a,
101    #[rustc_assert_variance(invariant)] T: ?Sized + 'a,
102> {
103    lock: &'a Mutex<T>,
104}
105
106/// A [`MutexGuard`] is not `Send` to maximize platform portability.
107///
108/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
109/// release mutex locks on the same thread they were acquired.
110/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
111/// another thread.
112#[unstable(feature = "nonpoison_mutex", issue = "134645")]
113impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
114
115/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
116/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
117#[unstable(feature = "nonpoison_mutex", issue = "134645")]
118unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
119
120/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
121/// subfield of the protected data. When this structure is dropped (falls out
122/// of scope), the lock will be unlocked.
123///
124/// The main difference between `MappedMutexGuard` and [`MutexGuard`] is that the
125/// former cannot be used with [`Condvar`], since that could introduce soundness issues if the
126/// locked object is modified by another thread while the `Mutex` is unlocked.
127///
128/// The data protected by the mutex can be accessed through this guard via its
129/// [`Deref`] and [`DerefMut`] implementations.
130///
131/// This structure is created by the [`map`] and [`filter_map`] methods on
132/// [`MutexGuard`].
133///
134/// [`map`]: MutexGuard::map
135/// [`filter_map`]: MutexGuard::filter_map
136/// [`Condvar`]: crate::sync::nonpoison::Condvar
137#[must_use = "if unused the Mutex will immediately unlock"]
138#[must_not_suspend = "holding a MappedMutexGuard across suspend \
139                      points can cause deadlocks, delays, \
140                      and cause Futures to not implement `Send`"]
141#[unstable(feature = "mapped_lock_guards", issue = "117108")]
142// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
143#[clippy::has_significant_drop]
144pub struct MappedMutexGuard<
145    #[rustc_assert_variance(covariant)] 'a,
146    #[rustc_assert_variance(invariant)] T: ?Sized + 'a,
147> {
148    // NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
149    // `MappedMutexGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
150    // `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
151    // below for the correct variance over `T` (invariance).
152    data: NonNull<T>,
153    inner: &'a sys::Mutex,
154    _variance: PhantomData<&'a mut T>,
155}
156
157#[unstable(feature = "mapped_lock_guards", issue = "117108")]
158// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
159impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
160#[unstable(feature = "mapped_lock_guards", issue = "117108")]
161// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
162unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
163
164impl<T> Mutex<T> {
165    /// Creates a new mutex in an unlocked state ready for use.
166    ///
167    /// # Examples
168    ///
169    /// ```
170    /// #![feature(nonpoison_mutex)]
171    ///
172    /// use std::sync::nonpoison::Mutex;
173    ///
174    /// let mutex = Mutex::new(0);
175    /// ```
176    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
177    #[inline]
178    pub const fn new(t: T) -> Mutex<T> {
179        Mutex { inner: sys::Mutex::new(), data: UnsafeCell::new(t) }
180    }
181
182    /// Returns the contained value by cloning it.
183    ///
184    /// # Examples
185    ///
186    /// ```
187    /// #![feature(nonpoison_mutex)]
188    /// #![feature(lock_value_accessors)]
189    ///
190    /// use std::sync::nonpoison::Mutex;
191    ///
192    /// let mut mutex = Mutex::new(7);
193    ///
194    /// assert_eq!(mutex.get_cloned(), 7);
195    /// ```
196    #[unstable(feature = "lock_value_accessors", issue = "133407")]
197    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
198    pub fn get_cloned(&self) -> T
199    where
200        T: Clone,
201    {
202        self.lock().clone()
203    }
204
205    /// Sets the contained value.
206    ///
207    /// # Examples
208    ///
209    /// ```
210    /// #![feature(nonpoison_mutex)]
211    /// #![feature(lock_value_accessors)]
212    ///
213    /// use std::sync::nonpoison::Mutex;
214    ///
215    /// let mut mutex = Mutex::new(7);
216    ///
217    /// assert_eq!(mutex.get_cloned(), 7);
218    /// mutex.set(11);
219    /// assert_eq!(mutex.get_cloned(), 11);
220    /// ```
221    #[unstable(feature = "lock_value_accessors", issue = "133407")]
222    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
223    pub fn set(&self, value: T) {
224        if mem::needs_drop::<T>() {
225            // If the contained value has a non-trivial destructor, we
226            // call that destructor after the lock has been released.
227            drop(self.replace(value))
228        } else {
229            *self.lock() = value;
230        }
231    }
232
233    /// Replaces the contained value with `value`, and returns the old contained value.
234    ///
235    /// # Examples
236    ///
237    /// ```
238    /// #![feature(nonpoison_mutex)]
239    /// #![feature(lock_value_accessors)]
240    ///
241    /// use std::sync::nonpoison::Mutex;
242    ///
243    /// let mut mutex = Mutex::new(7);
244    ///
245    /// assert_eq!(mutex.replace(11), 7);
246    /// assert_eq!(mutex.get_cloned(), 11);
247    /// ```
248    #[unstable(feature = "lock_value_accessors", issue = "133407")]
249    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
250    pub fn replace(&self, value: T) -> T {
251        let mut guard = self.lock();
252        mem::replace(&mut *guard, value)
253    }
254}
255
256impl<T: ?Sized> Mutex<T> {
257    /// Acquires a mutex, blocking the current thread until it is able to do so.
258    ///
259    /// This function will block the local thread until it is available to acquire
260    /// the mutex. Upon returning, the thread is the only thread with the lock
261    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
262    /// the guard goes out of scope, the mutex will be unlocked.
263    ///
264    /// The exact behavior on locking a mutex in the thread which already holds
265    /// the lock is left unspecified. However, this function will not return on
266    /// the second call (it might panic or deadlock, for example).
267    ///
268    /// # Panics
269    ///
270    /// This function might panic when called if the lock is already held by
271    /// the current thread.
272    ///
273    /// # Examples
274    ///
275    /// ```
276    /// #![feature(nonpoison_mutex)]
277    ///
278    /// use std::sync::{Arc, nonpoison::Mutex};
279    /// use std::thread;
280    ///
281    /// let mutex = Arc::new(Mutex::new(0));
282    /// let c_mutex = Arc::clone(&mutex);
283    ///
284    /// thread::spawn(move || {
285    ///     *c_mutex.lock() = 10;
286    /// }).join().expect("`thread::spawn` should not fail");
287    /// assert_eq!(*mutex.lock(), 10);
288    /// ```
289    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
290    pub fn lock(&self) -> MutexGuard<'_, T> {
291        unsafe {
292            self.inner.lock();
293            MutexGuard::new(self)
294        }
295    }
296
297    /// Attempts to acquire this lock.
298    ///
299    /// This function does not block. If the lock could not be acquired at this time, then
300    /// [`WouldBlock`] is returned. Otherwise, an RAII guard is returned.
301    ///
302    /// The lock will be unlocked when the guard is dropped.
303    ///
304    /// # Errors
305    ///
306    /// If the mutex could not be acquired because it is already locked, then this call will return
307    /// the [`WouldBlock`] error.
308    ///
309    /// # Examples
310    ///
311    /// ```
312    /// use std::sync::{Arc, Mutex};
313    /// use std::thread;
314    ///
315    /// let mutex = Arc::new(Mutex::new(0));
316    /// let c_mutex = Arc::clone(&mutex);
317    ///
318    /// thread::spawn(move || {
319    ///     let mut lock = c_mutex.try_lock();
320    ///     if let Ok(ref mut mutex) = lock {
321    ///         **mutex = 10;
322    ///     } else {
323    ///         println!("try_lock failed");
324    ///     }
325    /// }).join().expect("`thread::spawn` should not fail");
326    /// assert_eq!(*mutex.lock().unwrap(), 10);
327    /// ```
328    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
329    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
330        unsafe { if self.inner.try_lock() { Ok(MutexGuard::new(self)) } else { Err(WouldBlock) } }
331    }
332
333    /// Consumes this mutex, returning the underlying data.
334    ///
335    /// # Examples
336    ///
337    /// ```
338    /// #![feature(nonpoison_mutex)]
339    ///
340    /// use std::sync::nonpoison::Mutex;
341    ///
342    /// let mutex = Mutex::new(0);
343    /// assert_eq!(mutex.into_inner(), 0);
344    /// ```
345    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
346    pub fn into_inner(self) -> T
347    where
348        T: Sized,
349    {
350        self.data.into_inner()
351    }
352
353    /// Returns a mutable reference to the underlying data.
354    ///
355    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
356    /// take place -- the mutable borrow statically guarantees no locks exist.
357    ///
358    /// # Examples
359    ///
360    /// ```
361    /// #![feature(nonpoison_mutex)]
362    ///
363    /// use std::sync::nonpoison::Mutex;
364    ///
365    /// let mut mutex = Mutex::new(0);
366    /// *mutex.get_mut() = 10;
367    /// assert_eq!(*mutex.lock(), 10);
368    /// ```
369    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
370    pub fn get_mut(&mut self) -> &mut T {
371        self.data.get_mut()
372    }
373
374    /// Returns a raw pointer to the underlying data.
375    ///
376    /// The returned pointer is always non-null and properly aligned, but it is
377    /// the user's responsibility to ensure that any reads and writes through it
378    /// are properly synchronized to avoid data races, and that it is not read
379    /// or written through after the mutex is dropped.
380    #[unstable(feature = "mutex_data_ptr", issue = "140368")]
381    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
382    pub const fn data_ptr(&self) -> *mut T {
383        self.data.get()
384    }
385
386    /// Acquires the mutex and provides mutable access to the underlying data by passing
387    /// a mutable reference to the given closure.
388    ///
389    /// This method acquires the lock, calls the provided closure with a mutable reference
390    /// to the data, and returns the result of the closure. The lock is released after
391    /// the closure completes, even if it panics.
392    ///
393    /// # Examples
394    ///
395    /// ```
396    /// #![feature(lock_value_accessors, nonpoison_mutex)]
397    ///
398    /// use std::sync::nonpoison::Mutex;
399    ///
400    /// let mutex = Mutex::new(2);
401    ///
402    /// let result = mutex.with_mut(|data| {
403    ///     *data += 3;
404    ///
405    ///     *data + 5
406    /// });
407    ///
408    /// assert_eq!(*mutex.lock(), 5);
409    /// assert_eq!(result, 10);
410    /// ```
411    #[unstable(feature = "lock_value_accessors", issue = "133407")]
412    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
413    pub fn with_mut<F, R>(&self, f: F) -> R
414    where
415        F: FnOnce(&mut T) -> R,
416    {
417        f(&mut self.lock())
418    }
419}
420
421#[unstable(feature = "nonpoison_mutex", issue = "134645")]
422impl<T> From<T> for Mutex<T> {
423    /// Creates a new mutex in an unlocked state ready for use.
424    /// This is equivalent to [`Mutex::new`].
425    fn from(t: T) -> Self {
426        Mutex::new(t)
427    }
428}
429
430#[unstable(feature = "nonpoison_mutex", issue = "134645")]
431impl<T: Default> Default for Mutex<T> {
432    /// Creates a `Mutex<T>`, with the `Default` value for T.
433    fn default() -> Mutex<T> {
434        Mutex::new(Default::default())
435    }
436}
437
438#[unstable(feature = "nonpoison_mutex", issue = "134645")]
439impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
440    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
441        let mut d = f.debug_struct("Mutex");
442        match self.try_lock() {
443            Ok(guard) => {
444                d.field("data", &&*guard);
445            }
446            Err(WouldBlock) => {
447                d.field("data", &"<locked>");
448            }
449        }
450        d.finish_non_exhaustive()
451    }
452}
453
454impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
455    unsafe fn new(lock: &'mutex Mutex<T>) -> MutexGuard<'mutex, T> {
456        MutexGuard { lock }
457    }
458}
459
460#[unstable(feature = "nonpoison_mutex", issue = "134645")]
461impl<T: ?Sized> Deref for MutexGuard<'_, T> {
462    type Target = T;
463
464    fn deref(&self) -> &T {
465        unsafe { &*self.lock.data.get() }
466    }
467}
468
469#[unstable(feature = "nonpoison_mutex", issue = "134645")]
470impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
471    fn deref_mut(&mut self) -> &mut T {
472        unsafe { &mut *self.lock.data.get() }
473    }
474}
475
476#[unstable(feature = "nonpoison_mutex", issue = "134645")]
477impl<T: ?Sized> Drop for MutexGuard<'_, T> {
478    #[inline]
479    fn drop(&mut self) {
480        unsafe {
481            self.lock.inner.unlock();
482        }
483    }
484}
485
486#[unstable(feature = "nonpoison_mutex", issue = "134645")]
487impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
488    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489        fmt::Debug::fmt(&**self, f)
490    }
491}
492
493#[unstable(feature = "nonpoison_mutex", issue = "134645")]
494impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
495    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
496        (**self).fmt(f)
497    }
498}
499
500/// For use in [`nonpoison::condvar`](super::condvar).
501pub(super) fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
502    &guard.lock.inner
503}
504
505impl<'a, T: ?Sized> MutexGuard<'a, T> {
506    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
507    /// an enum variant.
508    ///
509    /// The `Mutex` is already locked, so this cannot fail.
510    ///
511    /// This is an associated function that needs to be used as
512    /// `MutexGuard::map(...)`. A method would interfere with methods of the
513    /// same name on the contents of the `MutexGuard` used through `Deref`.
514    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
515    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
516    pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
517    where
518        F: FnOnce(&mut T) -> &mut U,
519        U: ?Sized,
520    {
521        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
522        // was created, and have been upheld throughout `map` and/or `filter_map`.
523        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
524        // passed to it. If the closure panics, the guard will be dropped.
525        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
526        let orig = ManuallyDrop::new(orig);
527        MappedMutexGuard { data, inner: &orig.lock.inner, _variance: PhantomData }
528    }
529
530    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
531    /// original guard is returned as an `Err(...)` if the closure returns
532    /// `None`.
533    ///
534    /// The `Mutex` is already locked, so this cannot fail.
535    ///
536    /// This is an associated function that needs to be used as
537    /// `MutexGuard::filter_map(...)`. A method would interfere with methods of the
538    /// same name on the contents of the `MutexGuard` used through `Deref`.
539    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
540    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
541    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
542    where
543        F: FnOnce(&mut T) -> Option<&mut U>,
544        U: ?Sized,
545    {
546        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
547        // was created, and have been upheld throughout `map` and/or `filter_map`.
548        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
549        // passed to it. If the closure panics, the guard will be dropped.
550        match f(unsafe { &mut *orig.lock.data.get() }) {
551            Some(data) => {
552                let data = NonNull::from(data);
553                let orig = ManuallyDrop::new(orig);
554                Ok(MappedMutexGuard { data, inner: &orig.lock.inner, _variance: PhantomData })
555            }
556            None => Err(orig),
557        }
558    }
559}
560
561#[unstable(feature = "mapped_lock_guards", issue = "117108")]
562impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
563    type Target = T;
564
565    fn deref(&self) -> &T {
566        unsafe { self.data.as_ref() }
567    }
568}
569
570#[unstable(feature = "mapped_lock_guards", issue = "117108")]
571impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
572    fn deref_mut(&mut self) -> &mut T {
573        unsafe { self.data.as_mut() }
574    }
575}
576
577#[unstable(feature = "mapped_lock_guards", issue = "117108")]
578impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
579    #[inline]
580    fn drop(&mut self) {
581        unsafe {
582            self.inner.unlock();
583        }
584    }
585}
586
587#[unstable(feature = "mapped_lock_guards", issue = "117108")]
588impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
589    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
590        fmt::Debug::fmt(&**self, f)
591    }
592}
593
594#[unstable(feature = "mapped_lock_guards", issue = "117108")]
595impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
596    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
597        (**self).fmt(f)
598    }
599}
600
601impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
602    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
603    /// an enum variant.
604    ///
605    /// The `Mutex` is already locked, so this cannot fail.
606    ///
607    /// This is an associated function that needs to be used as
608    /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
609    /// same name on the contents of the `MutexGuard` used through `Deref`.
610    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
611    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
612    pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
613    where
614        F: FnOnce(&mut T) -> &mut U,
615        U: ?Sized,
616    {
617        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
618        // was created, and have been upheld throughout `map` and/or `filter_map`.
619        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
620        // passed to it. If the closure panics, the guard will be dropped.
621        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
622        let orig = ManuallyDrop::new(orig);
623        MappedMutexGuard { data, inner: orig.inner, _variance: PhantomData }
624    }
625
626    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
627    /// original guard is returned as an `Err(...)` if the closure returns
628    /// `None`.
629    ///
630    /// The `Mutex` is already locked, so this cannot fail.
631    ///
632    /// This is an associated function that needs to be used as
633    /// `MappedMutexGuard::filter_map(...)`. A method would interfere with methods of the
634    /// same name on the contents of the `MutexGuard` used through `Deref`.
635    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
636    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
637    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
638    where
639        F: FnOnce(&mut T) -> Option<&mut U>,
640        U: ?Sized,
641    {
642        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
643        // was created, and have been upheld throughout `map` and/or `filter_map`.
644        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
645        // passed to it. If the closure panics, the guard will be dropped.
646        match f(unsafe { orig.data.as_mut() }) {
647            Some(data) => {
648                let data = NonNull::from(data);
649                let orig = ManuallyDrop::new(orig);
650                Ok(MappedMutexGuard { data, inner: orig.inner, _variance: PhantomData })
651            }
652            None => Err(orig),
653        }
654    }
655}