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}