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<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<'a, T: ?Sized + 'a> {
100    lock: &'a Mutex<T>,
101}
102
103/// A [`MutexGuard`] is not `Send` to maximize platform portablity.
104///
105/// On platforms that use POSIX threads (commonly referred to as pthreads) there is a requirement to
106/// release mutex locks on the same thread they were acquired.
107/// For this reason, [`MutexGuard`] must not implement `Send` to prevent it being dropped from
108/// another thread.
109#[unstable(feature = "nonpoison_mutex", issue = "134645")]
110impl<T: ?Sized> !Send for MutexGuard<'_, T> {}
111
112/// `T` must be `Sync` for a [`MutexGuard<T>`] to be `Sync`
113/// because it is possible to get a `&T` from `&MutexGuard` (via `Deref`).
114#[unstable(feature = "nonpoison_mutex", issue = "134645")]
115unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
116
117// FIXME(nonpoison_condvar): Use this link instead: [`Condvar`]: crate::sync::nonpoison::Condvar
118/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
119/// subfield of the protected data. When this structure is dropped (falls out
120/// of scope), the lock will be unlocked.
121///
122/// The main difference between `MappedMutexGuard` and [`MutexGuard`] is that the
123/// former cannot be used with [`Condvar`], since that could introduce soundness issues if the
124/// locked object is modified by another thread while the `Mutex` is unlocked.
125///
126/// The data protected by the mutex can be accessed through this guard via its
127/// [`Deref`] and [`DerefMut`] implementations.
128///
129/// This structure is created by the [`map`] and [`filter_map`] methods on
130/// [`MutexGuard`].
131///
132/// [`map`]: MutexGuard::map
133/// [`filter_map`]: MutexGuard::filter_map
134/// [`Condvar`]: crate::sync::Condvar
135#[must_use = "if unused the Mutex will immediately unlock"]
136#[must_not_suspend = "holding a MappedMutexGuard across suspend \
137                      points can cause deadlocks, delays, \
138                      and cause Futures to not implement `Send`"]
139#[unstable(feature = "mapped_lock_guards", issue = "117108")]
140// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
141#[clippy::has_significant_drop]
142pub struct MappedMutexGuard<'a, T: ?Sized + 'a> {
143    // NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
144    // `MappedMutexGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
145    // `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
146    // below for the correct variance over `T` (invariance).
147    data: NonNull<T>,
148    inner: &'a sys::Mutex,
149    _variance: PhantomData<&'a mut T>,
150}
151
152#[unstable(feature = "mapped_lock_guards", issue = "117108")]
153// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
154impl<T: ?Sized> !Send for MappedMutexGuard<'_, T> {}
155#[unstable(feature = "mapped_lock_guards", issue = "117108")]
156// #[unstable(feature = "nonpoison_mutex", issue = "134645")]
157unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
158
159impl<T> Mutex<T> {
160    /// Creates a new mutex in an unlocked state ready for use.
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// #![feature(nonpoison_mutex)]
166    ///
167    /// use std::sync::nonpoison::Mutex;
168    ///
169    /// let mutex = Mutex::new(0);
170    /// ```
171    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
172    #[inline]
173    pub const fn new(t: T) -> Mutex<T> {
174        Mutex { inner: sys::Mutex::new(), data: UnsafeCell::new(t) }
175    }
176
177    /// Returns the contained value by cloning it.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// #![feature(nonpoison_mutex)]
183    /// #![feature(lock_value_accessors)]
184    ///
185    /// use std::sync::nonpoison::Mutex;
186    ///
187    /// let mut mutex = Mutex::new(7);
188    ///
189    /// assert_eq!(mutex.get_cloned(), 7);
190    /// ```
191    #[unstable(feature = "lock_value_accessors", issue = "133407")]
192    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
193    pub fn get_cloned(&self) -> T
194    where
195        T: Clone,
196    {
197        self.lock().clone()
198    }
199
200    /// Sets the contained value.
201    ///
202    /// # Examples
203    ///
204    /// ```
205    /// #![feature(nonpoison_mutex)]
206    /// #![feature(lock_value_accessors)]
207    ///
208    /// use std::sync::nonpoison::Mutex;
209    ///
210    /// let mut mutex = Mutex::new(7);
211    ///
212    /// assert_eq!(mutex.get_cloned(), 7);
213    /// mutex.set(11);
214    /// assert_eq!(mutex.get_cloned(), 11);
215    /// ```
216    #[unstable(feature = "lock_value_accessors", issue = "133407")]
217    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
218    pub fn set(&self, value: T) {
219        if mem::needs_drop::<T>() {
220            // If the contained value has a non-trivial destructor, we
221            // call that destructor after the lock has been released.
222            drop(self.replace(value))
223        } else {
224            *self.lock() = value;
225        }
226    }
227
228    /// Replaces the contained value with `value`, and returns the old contained value.
229    ///
230    /// # Examples
231    ///
232    /// ```
233    /// #![feature(nonpoison_mutex)]
234    /// #![feature(lock_value_accessors)]
235    ///
236    /// use std::sync::nonpoison::Mutex;
237    ///
238    /// let mut mutex = Mutex::new(7);
239    ///
240    /// assert_eq!(mutex.replace(11), 7);
241    /// assert_eq!(mutex.get_cloned(), 11);
242    /// ```
243    #[unstable(feature = "lock_value_accessors", issue = "133407")]
244    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
245    pub fn replace(&self, value: T) -> T {
246        let mut guard = self.lock();
247        mem::replace(&mut *guard, value)
248    }
249}
250
251impl<T: ?Sized> Mutex<T> {
252    /// Acquires a mutex, blocking the current thread until it is able to do so.
253    ///
254    /// This function will block the local thread until it is available to acquire
255    /// the mutex. Upon returning, the thread is the only thread with the lock
256    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
257    /// the guard goes out of scope, the mutex will be unlocked.
258    ///
259    /// The exact behavior on locking a mutex in the thread which already holds
260    /// the lock is left unspecified. However, this function will not return on
261    /// the second call (it might panic or deadlock, for example).
262    ///
263    /// # Panics
264    ///
265    /// This function might panic when called if the lock is already held by
266    /// the current thread.
267    ///
268    /// # Examples
269    ///
270    /// ```
271    /// #![feature(nonpoison_mutex)]
272    ///
273    /// use std::sync::{Arc, nonpoison::Mutex};
274    /// use std::thread;
275    ///
276    /// let mutex = Arc::new(Mutex::new(0));
277    /// let c_mutex = Arc::clone(&mutex);
278    ///
279    /// thread::spawn(move || {
280    ///     *c_mutex.lock() = 10;
281    /// }).join().expect("thread::spawn failed");
282    /// assert_eq!(*mutex.lock(), 10);
283    /// ```
284    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
285    pub fn lock(&self) -> MutexGuard<'_, T> {
286        unsafe {
287            self.inner.lock();
288            MutexGuard::new(self)
289        }
290    }
291
292    /// Attempts to acquire this lock.
293    ///
294    /// This function does not block. If the lock could not be acquired at this time, then
295    /// [`WouldBlock`] is returned. Otherwise, an RAII guard is returned.
296    ///
297    /// The lock will be unlocked when the guard is dropped.
298    ///
299    /// # Errors
300    ///
301    /// If the mutex could not be acquired because it is already locked, then this call will return
302    /// the [`WouldBlock`] error.
303    ///
304    /// # Examples
305    ///
306    /// ```
307    /// use std::sync::{Arc, Mutex};
308    /// use std::thread;
309    ///
310    /// let mutex = Arc::new(Mutex::new(0));
311    /// let c_mutex = Arc::clone(&mutex);
312    ///
313    /// thread::spawn(move || {
314    ///     let mut lock = c_mutex.try_lock();
315    ///     if let Ok(ref mut mutex) = lock {
316    ///         **mutex = 10;
317    ///     } else {
318    ///         println!("try_lock failed");
319    ///     }
320    /// }).join().expect("thread::spawn failed");
321    /// assert_eq!(*mutex.lock().unwrap(), 10);
322    /// ```
323    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
324    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>> {
325        unsafe { if self.inner.try_lock() { Ok(MutexGuard::new(self)) } else { Err(WouldBlock) } }
326    }
327
328    /// Consumes this mutex, returning the underlying data.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// #![feature(nonpoison_mutex)]
334    ///
335    /// use std::sync::nonpoison::Mutex;
336    ///
337    /// let mutex = Mutex::new(0);
338    /// assert_eq!(mutex.into_inner(), 0);
339    /// ```
340    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
341    pub fn into_inner(self) -> T
342    where
343        T: Sized,
344    {
345        self.data.into_inner()
346    }
347
348    /// Returns a mutable reference to the underlying data.
349    ///
350    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
351    /// take place -- the mutable borrow statically guarantees no locks exist.
352    ///
353    /// # Examples
354    ///
355    /// ```
356    /// #![feature(nonpoison_mutex)]
357    ///
358    /// use std::sync::nonpoison::Mutex;
359    ///
360    /// let mut mutex = Mutex::new(0);
361    /// *mutex.get_mut() = 10;
362    /// assert_eq!(*mutex.lock(), 10);
363    /// ```
364    #[unstable(feature = "nonpoison_mutex", issue = "134645")]
365    pub fn get_mut(&mut self) -> &mut T {
366        self.data.get_mut()
367    }
368
369    /// Returns a raw pointer to the underlying data.
370    ///
371    /// The returned pointer is always non-null and properly aligned, but it is
372    /// the user's responsibility to ensure that any reads and writes through it
373    /// are properly synchronized to avoid data races, and that it is not read
374    /// or written through after the mutex is dropped.
375    #[unstable(feature = "mutex_data_ptr", issue = "140368")]
376    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
377    pub fn data_ptr(&self) -> *mut T {
378        self.data.get()
379    }
380}
381
382#[unstable(feature = "nonpoison_mutex", issue = "134645")]
383impl<T> From<T> for Mutex<T> {
384    /// Creates a new mutex in an unlocked state ready for use.
385    /// This is equivalent to [`Mutex::new`].
386    fn from(t: T) -> Self {
387        Mutex::new(t)
388    }
389}
390
391#[unstable(feature = "nonpoison_mutex", issue = "134645")]
392impl<T: ?Sized + Default> Default for Mutex<T> {
393    /// Creates a `Mutex<T>`, with the `Default` value for T.
394    fn default() -> Mutex<T> {
395        Mutex::new(Default::default())
396    }
397}
398
399#[unstable(feature = "nonpoison_mutex", issue = "134645")]
400impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
401    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
402        let mut d = f.debug_struct("Mutex");
403        match self.try_lock() {
404            Ok(guard) => {
405                d.field("data", &&*guard);
406            }
407            Err(WouldBlock) => {
408                d.field("data", &"<locked>");
409            }
410        }
411        d.finish_non_exhaustive()
412    }
413}
414
415impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
416    unsafe fn new(lock: &'mutex Mutex<T>) -> MutexGuard<'mutex, T> {
417        return MutexGuard { lock };
418    }
419}
420
421#[unstable(feature = "nonpoison_mutex", issue = "134645")]
422impl<T: ?Sized> Deref for MutexGuard<'_, T> {
423    type Target = T;
424
425    fn deref(&self) -> &T {
426        unsafe { &*self.lock.data.get() }
427    }
428}
429
430#[unstable(feature = "nonpoison_mutex", issue = "134645")]
431impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
432    fn deref_mut(&mut self) -> &mut T {
433        unsafe { &mut *self.lock.data.get() }
434    }
435}
436
437#[unstable(feature = "nonpoison_mutex", issue = "134645")]
438impl<T: ?Sized> Drop for MutexGuard<'_, T> {
439    #[inline]
440    fn drop(&mut self) {
441        unsafe {
442            self.lock.inner.unlock();
443        }
444    }
445}
446
447#[unstable(feature = "nonpoison_mutex", issue = "134645")]
448impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
449    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450        fmt::Debug::fmt(&**self, f)
451    }
452}
453
454#[unstable(feature = "nonpoison_mutex", issue = "134645")]
455impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
456    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
457        (**self).fmt(f)
458    }
459}
460
461impl<'a, T: ?Sized> MutexGuard<'a, T> {
462    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
463    /// an enum variant.
464    ///
465    /// The `Mutex` is already locked, so this cannot fail.
466    ///
467    /// This is an associated function that needs to be used as
468    /// `MutexGuard::map(...)`. A method would interfere with methods of the
469    /// same name on the contents of the `MutexGuard` used through `Deref`.
470    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
471    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
472    pub fn map<U, F>(orig: Self, f: F) -> MappedMutexGuard<'a, U>
473    where
474        F: FnOnce(&mut T) -> &mut U,
475        U: ?Sized,
476    {
477        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
478        // was created, and have been upheld throughout `map` and/or `filter_map`.
479        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
480        // passed to it. If the closure panics, the guard will be dropped.
481        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
482        let orig = ManuallyDrop::new(orig);
483        MappedMutexGuard { data, inner: &orig.lock.inner, _variance: PhantomData }
484    }
485
486    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
487    /// original guard is returned as an `Err(...)` if the closure returns
488    /// `None`.
489    ///
490    /// The `Mutex` is already locked, so this cannot fail.
491    ///
492    /// This is an associated function that needs to be used as
493    /// `MutexGuard::filter_map(...)`. A method would interfere with methods of the
494    /// same name on the contents of the `MutexGuard` used through `Deref`.
495    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
496    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
497    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
498    where
499        F: FnOnce(&mut T) -> Option<&mut U>,
500        U: ?Sized,
501    {
502        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
503        // was created, and have been upheld throughout `map` and/or `filter_map`.
504        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
505        // passed to it. If the closure panics, the guard will be dropped.
506        match f(unsafe { &mut *orig.lock.data.get() }) {
507            Some(data) => {
508                let data = NonNull::from(data);
509                let orig = ManuallyDrop::new(orig);
510                Ok(MappedMutexGuard { data, inner: &orig.lock.inner, _variance: PhantomData })
511            }
512            None => Err(orig),
513        }
514    }
515}
516
517#[unstable(feature = "mapped_lock_guards", issue = "117108")]
518impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
519    type Target = T;
520
521    fn deref(&self) -> &T {
522        unsafe { self.data.as_ref() }
523    }
524}
525
526#[unstable(feature = "mapped_lock_guards", issue = "117108")]
527impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
528    fn deref_mut(&mut self) -> &mut T {
529        unsafe { self.data.as_mut() }
530    }
531}
532
533#[unstable(feature = "mapped_lock_guards", issue = "117108")]
534impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
535    #[inline]
536    fn drop(&mut self) {
537        unsafe {
538            self.inner.unlock();
539        }
540    }
541}
542
543#[unstable(feature = "mapped_lock_guards", issue = "117108")]
544impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
545    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
546        fmt::Debug::fmt(&**self, f)
547    }
548}
549
550#[unstable(feature = "mapped_lock_guards", issue = "117108")]
551impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
552    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
553        (**self).fmt(f)
554    }
555}
556
557impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
558    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data, e.g.
559    /// an enum variant.
560    ///
561    /// The `Mutex` is already locked, so this cannot fail.
562    ///
563    /// This is an associated function that needs to be used as
564    /// `MappedMutexGuard::map(...)`. A method would interfere with methods of the
565    /// same name on the contents of the `MutexGuard` used through `Deref`.
566    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
567    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
568    pub fn map<U, F>(mut orig: Self, f: F) -> MappedMutexGuard<'a, U>
569    where
570        F: FnOnce(&mut T) -> &mut U,
571        U: ?Sized,
572    {
573        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
574        // was created, and have been upheld throughout `map` and/or `filter_map`.
575        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
576        // passed to it. If the closure panics, the guard will be dropped.
577        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
578        let orig = ManuallyDrop::new(orig);
579        MappedMutexGuard { data, inner: orig.inner, _variance: PhantomData }
580    }
581
582    /// Makes a [`MappedMutexGuard`] for a component of the borrowed data. The
583    /// original guard is returned as an `Err(...)` if the closure returns
584    /// `None`.
585    ///
586    /// The `Mutex` is already locked, so this cannot fail.
587    ///
588    /// This is an associated function that needs to be used as
589    /// `MappedMutexGuard::filter_map(...)`. A method would interfere with methods of the
590    /// same name on the contents of the `MutexGuard` used through `Deref`.
591    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
592    // #[unstable(feature = "nonpoison_mutex", issue = "134645")]
593    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
594    where
595        F: FnOnce(&mut T) -> Option<&mut U>,
596        U: ?Sized,
597    {
598        // SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
599        // was created, and have been upheld throughout `map` and/or `filter_map`.
600        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
601        // passed to it. If the closure panics, the guard will be dropped.
602        match f(unsafe { orig.data.as_mut() }) {
603            Some(data) => {
604                let data = NonNull::from(data);
605                let orig = ManuallyDrop::new(orig);
606                Ok(MappedMutexGuard { data, inner: orig.inner, _variance: PhantomData })
607            }
608            None => Err(orig),
609        }
610    }
611}