std/sync/poison/
rwlock.rs

1use crate::cell::UnsafeCell;
2use crate::fmt;
3use crate::marker::PhantomData;
4use crate::mem::{self, ManuallyDrop, forget};
5use crate::ops::{Deref, DerefMut};
6use crate::ptr::NonNull;
7use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison};
8use crate::sys::sync as sys;
9
10/// A reader-writer lock
11///
12/// This type of lock allows a number of readers or at most one writer at any
13/// point in time. The write portion of this lock typically allows modification
14/// of the underlying data (exclusive access) and the read portion of this lock
15/// typically allows for read-only access (shared access).
16///
17/// In comparison, a [`Mutex`] does not distinguish between readers or writers
18/// that acquire the lock, therefore blocking any threads waiting for the lock to
19/// become available. An `RwLock` will allow any number of readers to acquire the
20/// lock as long as a writer is not holding the lock.
21///
22/// The priority policy of the lock is dependent on the underlying operating
23/// system's implementation, and this type does not guarantee that any
24/// particular policy will be used. In particular, a writer which is waiting to
25/// acquire the lock in `write` might or might not block concurrent calls to
26/// `read`, e.g.:
27///
28/// <details><summary>Potential deadlock example</summary>
29///
30/// ```text
31/// // Thread 1              |  // Thread 2
32/// let _rg1 = lock.read();  |
33///                          |  // will block
34///                          |  let _wg = lock.write();
35/// // may deadlock          |
36/// let _rg2 = lock.read();  |
37/// ```
38///
39/// </details>
40///
41/// The type parameter `T` represents the data that this lock protects. It is
42/// required that `T` satisfies [`Send`] to be shared across threads and
43/// [`Sync`] to allow concurrent access through readers. The RAII guards
44/// returned from the locking methods implement [`Deref`] (and [`DerefMut`]
45/// for the `write` methods) to allow access to the content of the lock.
46///
47/// # Poisoning
48///
49/// An `RwLock`, like [`Mutex`], will become poisoned on a panic. Note, however,
50/// that an `RwLock` may only be poisoned if a panic occurs while it is locked
51/// exclusively (write mode). If a panic occurs in any reader, then the lock
52/// will not be poisoned.
53///
54/// # Examples
55///
56/// ```
57/// use std::sync::RwLock;
58///
59/// let lock = RwLock::new(5);
60///
61/// // many reader locks can be held at once
62/// {
63///     let r1 = lock.read().unwrap();
64///     let r2 = lock.read().unwrap();
65///     assert_eq!(*r1, 5);
66///     assert_eq!(*r2, 5);
67/// } // read locks are dropped at this point
68///
69/// // only one write lock may be held, however
70/// {
71///     let mut w = lock.write().unwrap();
72///     *w += 1;
73///     assert_eq!(*w, 6);
74/// } // write lock is dropped here
75/// ```
76///
77/// [`Mutex`]: super::Mutex
78#[stable(feature = "rust1", since = "1.0.0")]
79#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")]
80pub struct RwLock<T: ?Sized> {
81    inner: sys::RwLock,
82    poison: poison::Flag,
83    data: UnsafeCell<T>,
84}
85
86#[stable(feature = "rust1", since = "1.0.0")]
87unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
88#[stable(feature = "rust1", since = "1.0.0")]
89unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
90
91/// RAII structure used to release the shared read access of a lock when
92/// dropped.
93///
94/// This structure is created by the [`read`] and [`try_read`] methods on
95/// [`RwLock`].
96///
97/// [`read`]: RwLock::read
98/// [`try_read`]: RwLock::try_read
99#[must_use = "if unused the RwLock will immediately unlock"]
100#[must_not_suspend = "holding a RwLockReadGuard across suspend \
101                      points can cause deadlocks, delays, \
102                      and cause Futures to not implement `Send`"]
103#[stable(feature = "rust1", since = "1.0.0")]
104#[clippy::has_significant_drop]
105#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockReadGuard")]
106pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
107    // NB: we use a pointer instead of `&'a T` to avoid `noalias` violations, because a
108    // `RwLockReadGuard` argument doesn't hold immutability for its whole scope, only until it drops.
109    // `NonNull` is also covariant over `T`, just like we would have with `&T`. `NonNull`
110    // is preferable over `const* T` to allow for niche optimization.
111    data: NonNull<T>,
112    inner_lock: &'a sys::RwLock,
113}
114
115#[stable(feature = "rust1", since = "1.0.0")]
116impl<T: ?Sized> !Send for RwLockReadGuard<'_, T> {}
117
118#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
119unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
120
121/// RAII structure used to release the exclusive write access of a lock when
122/// dropped.
123///
124/// This structure is created by the [`write`] and [`try_write`] methods
125/// on [`RwLock`].
126///
127/// [`write`]: RwLock::write
128/// [`try_write`]: RwLock::try_write
129#[must_use = "if unused the RwLock will immediately unlock"]
130#[must_not_suspend = "holding a RwLockWriteGuard across suspend \
131                      points can cause deadlocks, delays, \
132                      and cause Future's to not implement `Send`"]
133#[stable(feature = "rust1", since = "1.0.0")]
134#[clippy::has_significant_drop]
135#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockWriteGuard")]
136pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
137    lock: &'a RwLock<T>,
138    poison: poison::Guard,
139}
140
141#[stable(feature = "rust1", since = "1.0.0")]
142impl<T: ?Sized> !Send for RwLockWriteGuard<'_, T> {}
143
144#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
145unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
146
147/// RAII structure used to release the shared read access of a lock when
148/// dropped, which can point to a subfield of the protected data.
149///
150/// This structure is created by the [`map`] and [`filter_map`] methods
151/// on [`RwLockReadGuard`].
152///
153/// [`map`]: RwLockReadGuard::map
154/// [`filter_map`]: RwLockReadGuard::filter_map
155#[must_use = "if unused the RwLock will immediately unlock"]
156#[must_not_suspend = "holding a MappedRwLockReadGuard across suspend \
157                      points can cause deadlocks, delays, \
158                      and cause Futures to not implement `Send`"]
159#[unstable(feature = "mapped_lock_guards", issue = "117108")]
160#[clippy::has_significant_drop]
161pub struct MappedRwLockReadGuard<'a, T: ?Sized + 'a> {
162    // NB: we use a pointer instead of `&'a T` to avoid `noalias` violations, because a
163    // `MappedRwLockReadGuard` argument doesn't hold immutability for its whole scope, only until it drops.
164    // `NonNull` is also covariant over `T`, just like we would have with `&T`. `NonNull`
165    // is preferable over `const* T` to allow for niche optimization.
166    data: NonNull<T>,
167    inner_lock: &'a sys::RwLock,
168}
169
170#[unstable(feature = "mapped_lock_guards", issue = "117108")]
171impl<T: ?Sized> !Send for MappedRwLockReadGuard<'_, T> {}
172
173#[unstable(feature = "mapped_lock_guards", issue = "117108")]
174unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
175
176/// RAII structure used to release the exclusive write access of a lock when
177/// dropped, which can point to a subfield of the protected data.
178///
179/// This structure is created by the [`map`] and [`filter_map`] methods
180/// on [`RwLockWriteGuard`].
181///
182/// [`map`]: RwLockWriteGuard::map
183/// [`filter_map`]: RwLockWriteGuard::filter_map
184#[must_use = "if unused the RwLock will immediately unlock"]
185#[must_not_suspend = "holding a MappedRwLockWriteGuard across suspend \
186                      points can cause deadlocks, delays, \
187                      and cause Future's to not implement `Send`"]
188#[unstable(feature = "mapped_lock_guards", issue = "117108")]
189#[clippy::has_significant_drop]
190pub struct MappedRwLockWriteGuard<'a, T: ?Sized + 'a> {
191    // NB: we use a pointer instead of `&'a mut T` to avoid `noalias` violations, because a
192    // `MappedRwLockWriteGuard` argument doesn't hold uniqueness for its whole scope, only until it drops.
193    // `NonNull` is covariant over `T`, so we add a `PhantomData<&'a mut T>` field
194    // below for the correct variance over `T` (invariance).
195    data: NonNull<T>,
196    inner_lock: &'a sys::RwLock,
197    poison_flag: &'a poison::Flag,
198    poison: poison::Guard,
199    _variance: PhantomData<&'a mut T>,
200}
201
202#[unstable(feature = "mapped_lock_guards", issue = "117108")]
203impl<T: ?Sized> !Send for MappedRwLockWriteGuard<'_, T> {}
204
205#[unstable(feature = "mapped_lock_guards", issue = "117108")]
206unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockWriteGuard<'_, T> {}
207
208impl<T> RwLock<T> {
209    /// Creates a new instance of an `RwLock<T>` which is unlocked.
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use std::sync::RwLock;
215    ///
216    /// let lock = RwLock::new(5);
217    /// ```
218    #[stable(feature = "rust1", since = "1.0.0")]
219    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
220    #[inline]
221    pub const fn new(t: T) -> RwLock<T> {
222        RwLock { inner: sys::RwLock::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
223    }
224
225    /// Returns the contained value by cloning it.
226    ///
227    /// # Errors
228    ///
229    /// This function will return an error if the `RwLock` is poisoned. An
230    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
231    /// lock.
232    ///
233    /// # Examples
234    ///
235    /// ```
236    /// #![feature(lock_value_accessors)]
237    ///
238    /// use std::sync::RwLock;
239    ///
240    /// let mut lock = RwLock::new(7);
241    ///
242    /// assert_eq!(lock.get_cloned().unwrap(), 7);
243    /// ```
244    #[unstable(feature = "lock_value_accessors", issue = "133407")]
245    pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
246    where
247        T: Clone,
248    {
249        match self.read() {
250            Ok(guard) => Ok((*guard).clone()),
251            Err(_) => Err(PoisonError::new(())),
252        }
253    }
254
255    /// Sets the contained value.
256    ///
257    /// # Errors
258    ///
259    /// This function will return an error containing the provided `value` if
260    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
261    /// panics while holding an exclusive lock.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// #![feature(lock_value_accessors)]
267    ///
268    /// use std::sync::RwLock;
269    ///
270    /// let mut lock = RwLock::new(7);
271    ///
272    /// assert_eq!(lock.get_cloned().unwrap(), 7);
273    /// lock.set(11).unwrap();
274    /// assert_eq!(lock.get_cloned().unwrap(), 11);
275    /// ```
276    #[unstable(feature = "lock_value_accessors", issue = "133407")]
277    pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
278        if mem::needs_drop::<T>() {
279            // If the contained value has non-trivial destructor, we
280            // call that destructor after the lock being released.
281            self.replace(value).map(drop)
282        } else {
283            match self.write() {
284                Ok(mut guard) => {
285                    *guard = value;
286
287                    Ok(())
288                }
289                Err(_) => Err(PoisonError::new(value)),
290            }
291        }
292    }
293
294    /// Replaces the contained value with `value`, and returns the old contained value.
295    ///
296    /// # Errors
297    ///
298    /// This function will return an error containing the provided `value` if
299    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
300    /// panics while holding an exclusive lock.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// #![feature(lock_value_accessors)]
306    ///
307    /// use std::sync::RwLock;
308    ///
309    /// let mut lock = RwLock::new(7);
310    ///
311    /// assert_eq!(lock.replace(11).unwrap(), 7);
312    /// assert_eq!(lock.get_cloned().unwrap(), 11);
313    /// ```
314    #[unstable(feature = "lock_value_accessors", issue = "133407")]
315    pub fn replace(&self, value: T) -> LockResult<T> {
316        match self.write() {
317            Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
318            Err(_) => Err(PoisonError::new(value)),
319        }
320    }
321}
322
323impl<T: ?Sized> RwLock<T> {
324    /// Locks this `RwLock` with shared read access, blocking the current thread
325    /// until it can be acquired.
326    ///
327    /// The calling thread will be blocked until there are no more writers which
328    /// hold the lock. There may be other readers currently inside the lock when
329    /// this method returns. This method does not provide any guarantees with
330    /// respect to the ordering of whether contentious readers or writers will
331    /// acquire the lock first.
332    ///
333    /// Returns an RAII guard which will release this thread's shared access
334    /// once it is dropped.
335    ///
336    /// # Errors
337    ///
338    /// This function will return an error if the `RwLock` is poisoned. An
339    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
340    /// lock. The failure will occur immediately after the lock has been
341    /// acquired. The acquired lock guard will be contained in the returned
342    /// error.
343    ///
344    /// # Panics
345    ///
346    /// This function might panic when called if the lock is already held by the current thread.
347    ///
348    /// # Examples
349    ///
350    /// ```
351    /// use std::sync::{Arc, RwLock};
352    /// use std::thread;
353    ///
354    /// let lock = Arc::new(RwLock::new(1));
355    /// let c_lock = Arc::clone(&lock);
356    ///
357    /// let n = lock.read().unwrap();
358    /// assert_eq!(*n, 1);
359    ///
360    /// thread::spawn(move || {
361    ///     let r = c_lock.read();
362    ///     assert!(r.is_ok());
363    /// }).join().unwrap();
364    /// ```
365    #[inline]
366    #[stable(feature = "rust1", since = "1.0.0")]
367    pub fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
368        unsafe {
369            self.inner.read();
370            RwLockReadGuard::new(self)
371        }
372    }
373
374    /// Attempts to acquire this `RwLock` with shared read access.
375    ///
376    /// If the access could not be granted at this time, then `Err` is returned.
377    /// Otherwise, an RAII guard is returned which will release the shared access
378    /// when it is dropped.
379    ///
380    /// This function does not block.
381    ///
382    /// This function does not provide any guarantees with respect to the ordering
383    /// of whether contentious readers or writers will acquire the lock first.
384    ///
385    /// # Errors
386    ///
387    /// This function will return the [`Poisoned`] error if the `RwLock` is
388    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
389    /// an exclusive lock. `Poisoned` will only be returned if the lock would
390    /// have otherwise been acquired. An acquired lock guard will be contained
391    /// in the returned error.
392    ///
393    /// This function will return the [`WouldBlock`] error if the `RwLock` could
394    /// not be acquired because it was already locked exclusively.
395    ///
396    /// [`Poisoned`]: TryLockError::Poisoned
397    /// [`WouldBlock`]: TryLockError::WouldBlock
398    ///
399    /// # Examples
400    ///
401    /// ```
402    /// use std::sync::RwLock;
403    ///
404    /// let lock = RwLock::new(1);
405    ///
406    /// match lock.try_read() {
407    ///     Ok(n) => assert_eq!(*n, 1),
408    ///     Err(_) => unreachable!(),
409    /// };
410    /// ```
411    #[inline]
412    #[stable(feature = "rust1", since = "1.0.0")]
413    pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>> {
414        unsafe {
415            if self.inner.try_read() {
416                Ok(RwLockReadGuard::new(self)?)
417            } else {
418                Err(TryLockError::WouldBlock)
419            }
420        }
421    }
422
423    /// Locks this `RwLock` with exclusive write access, blocking the current
424    /// thread until it can be acquired.
425    ///
426    /// This function will not return while other writers or other readers
427    /// currently have access to the lock.
428    ///
429    /// Returns an RAII guard which will drop the write access of this `RwLock`
430    /// when dropped.
431    ///
432    /// # Errors
433    ///
434    /// This function will return an error if the `RwLock` is poisoned. An
435    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
436    /// lock. An error will be returned when the lock is acquired. The acquired
437    /// lock guard will be contained in the returned error.
438    ///
439    /// # Panics
440    ///
441    /// This function might panic when called if the lock is already held by the current thread.
442    ///
443    /// # Examples
444    ///
445    /// ```
446    /// use std::sync::RwLock;
447    ///
448    /// let lock = RwLock::new(1);
449    ///
450    /// let mut n = lock.write().unwrap();
451    /// *n = 2;
452    ///
453    /// assert!(lock.try_read().is_err());
454    /// ```
455    #[inline]
456    #[stable(feature = "rust1", since = "1.0.0")]
457    pub fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
458        unsafe {
459            self.inner.write();
460            RwLockWriteGuard::new(self)
461        }
462    }
463
464    /// Attempts to lock this `RwLock` with exclusive write access.
465    ///
466    /// If the lock could not be acquired at this time, then `Err` is returned.
467    /// Otherwise, an RAII guard is returned which will release the lock when
468    /// it is dropped.
469    ///
470    /// This function does not block.
471    ///
472    /// This function does not provide any guarantees with respect to the ordering
473    /// of whether contentious readers or writers will acquire the lock first.
474    ///
475    /// # Errors
476    ///
477    /// This function will return the [`Poisoned`] error if the `RwLock` is
478    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
479    /// an exclusive lock. `Poisoned` will only be returned if the lock would
480    /// have otherwise been acquired. An acquired lock guard will be contained
481    /// in the returned error.
482    ///
483    /// This function will return the [`WouldBlock`] error if the `RwLock` could
484    /// not be acquired because it was already locked exclusively.
485    ///
486    /// [`Poisoned`]: TryLockError::Poisoned
487    /// [`WouldBlock`]: TryLockError::WouldBlock
488    ///
489    ///
490    /// # Examples
491    ///
492    /// ```
493    /// use std::sync::RwLock;
494    ///
495    /// let lock = RwLock::new(1);
496    ///
497    /// let n = lock.read().unwrap();
498    /// assert_eq!(*n, 1);
499    ///
500    /// assert!(lock.try_write().is_err());
501    /// ```
502    #[inline]
503    #[stable(feature = "rust1", since = "1.0.0")]
504    pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'_, T>> {
505        unsafe {
506            if self.inner.try_write() {
507                Ok(RwLockWriteGuard::new(self)?)
508            } else {
509                Err(TryLockError::WouldBlock)
510            }
511        }
512    }
513
514    /// Determines whether the lock is poisoned.
515    ///
516    /// If another thread is active, the lock can still become poisoned at any
517    /// time. You should not trust a `false` value for program correctness
518    /// without additional synchronization.
519    ///
520    /// # Examples
521    ///
522    /// ```
523    /// use std::sync::{Arc, RwLock};
524    /// use std::thread;
525    ///
526    /// let lock = Arc::new(RwLock::new(0));
527    /// let c_lock = Arc::clone(&lock);
528    ///
529    /// let _ = thread::spawn(move || {
530    ///     let _lock = c_lock.write().unwrap();
531    ///     panic!(); // the lock gets poisoned
532    /// }).join();
533    /// assert_eq!(lock.is_poisoned(), true);
534    /// ```
535    #[inline]
536    #[stable(feature = "sync_poison", since = "1.2.0")]
537    pub fn is_poisoned(&self) -> bool {
538        self.poison.get()
539    }
540
541    /// Clear the poisoned state from a lock.
542    ///
543    /// If the lock is poisoned, it will remain poisoned until this function is called. This allows
544    /// recovering from a poisoned state and marking that it has recovered. For example, if the
545    /// value is overwritten by a known-good value, then the lock can be marked as un-poisoned. Or
546    /// possibly, the value could be inspected to determine if it is in a consistent state, and if
547    /// so the poison is removed.
548    ///
549    /// # Examples
550    ///
551    /// ```
552    /// use std::sync::{Arc, RwLock};
553    /// use std::thread;
554    ///
555    /// let lock = Arc::new(RwLock::new(0));
556    /// let c_lock = Arc::clone(&lock);
557    ///
558    /// let _ = thread::spawn(move || {
559    ///     let _lock = c_lock.write().unwrap();
560    ///     panic!(); // the lock gets poisoned
561    /// }).join();
562    ///
563    /// assert_eq!(lock.is_poisoned(), true);
564    /// let guard = lock.write().unwrap_or_else(|mut e| {
565    ///     **e.get_mut() = 1;
566    ///     lock.clear_poison();
567    ///     e.into_inner()
568    /// });
569    /// assert_eq!(lock.is_poisoned(), false);
570    /// assert_eq!(*guard, 1);
571    /// ```
572    #[inline]
573    #[stable(feature = "mutex_unpoison", since = "1.77.0")]
574    pub fn clear_poison(&self) {
575        self.poison.clear();
576    }
577
578    /// Consumes this `RwLock`, returning the underlying data.
579    ///
580    /// # Errors
581    ///
582    /// This function will return an error containing the underlying data if
583    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
584    /// panics while holding an exclusive lock. An error will only be returned
585    /// if the lock would have otherwise been acquired.
586    ///
587    /// # Examples
588    ///
589    /// ```
590    /// use std::sync::RwLock;
591    ///
592    /// let lock = RwLock::new(String::new());
593    /// {
594    ///     let mut s = lock.write().unwrap();
595    ///     *s = "modified".to_owned();
596    /// }
597    /// assert_eq!(lock.into_inner().unwrap(), "modified");
598    /// ```
599    #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
600    pub fn into_inner(self) -> LockResult<T>
601    where
602        T: Sized,
603    {
604        let data = self.data.into_inner();
605        poison::map_result(self.poison.borrow(), |()| data)
606    }
607
608    /// Returns a mutable reference to the underlying data.
609    ///
610    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
611    /// take place -- the mutable borrow statically guarantees no new locks can be acquired
612    /// while this reference exists. Note that this method does not clear any previously abandoned locks
613    /// (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
614    ///
615    /// # Errors
616    ///
617    /// This function will return an error containing a mutable reference to
618    /// the underlying data if the `RwLock` is poisoned. An `RwLock` is
619    /// poisoned whenever a writer panics while holding an exclusive lock.
620    /// An error will only be returned if the lock would have otherwise been
621    /// acquired.
622    ///
623    /// # Examples
624    ///
625    /// ```
626    /// use std::sync::RwLock;
627    ///
628    /// let mut lock = RwLock::new(0);
629    /// *lock.get_mut().unwrap() = 10;
630    /// assert_eq!(*lock.read().unwrap(), 10);
631    /// ```
632    #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
633    pub fn get_mut(&mut self) -> LockResult<&mut T> {
634        let data = self.data.get_mut();
635        poison::map_result(self.poison.borrow(), |()| data)
636    }
637
638    /// Returns a raw pointer to the underlying data.
639    ///
640    /// The returned pointer is always non-null and properly aligned, but it is
641    /// the user's responsibility to ensure that any reads and writes through it
642    /// are properly synchronized to avoid data races, and that it is not read
643    /// or written through after the lock is dropped.
644    #[unstable(feature = "rwlock_data_ptr", issue = "140368")]
645    pub fn data_ptr(&self) -> *mut T {
646        self.data.get()
647    }
648}
649
650#[stable(feature = "rust1", since = "1.0.0")]
651impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
652    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653        let mut d = f.debug_struct("RwLock");
654        match self.try_read() {
655            Ok(guard) => {
656                d.field("data", &&*guard);
657            }
658            Err(TryLockError::Poisoned(err)) => {
659                d.field("data", &&**err.get_ref());
660            }
661            Err(TryLockError::WouldBlock) => {
662                d.field("data", &format_args!("<locked>"));
663            }
664        }
665        d.field("poisoned", &self.poison.get());
666        d.finish_non_exhaustive()
667    }
668}
669
670#[stable(feature = "rw_lock_default", since = "1.10.0")]
671impl<T: Default> Default for RwLock<T> {
672    /// Creates a new `RwLock<T>`, with the `Default` value for T.
673    fn default() -> RwLock<T> {
674        RwLock::new(Default::default())
675    }
676}
677
678#[stable(feature = "rw_lock_from", since = "1.24.0")]
679impl<T> From<T> for RwLock<T> {
680    /// Creates a new instance of an `RwLock<T>` which is unlocked.
681    /// This is equivalent to [`RwLock::new`].
682    fn from(t: T) -> Self {
683        RwLock::new(t)
684    }
685}
686
687impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
688    /// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
689    ///
690    /// # Safety
691    ///
692    /// This function is safe if and only if the same thread has successfully and safely called
693    /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
694    /// instantiating this object.
695    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
696        poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
697            data: unsafe { NonNull::new_unchecked(lock.data.get()) },
698            inner_lock: &lock.inner,
699        })
700    }
701}
702
703impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
704    /// Creates a new instance of `RwLockWriteGuard<T>` from a `RwLock<T>`.
705    // SAFETY: if and only if `lock.inner.write()` (or `lock.inner.try_write()`) has been
706    // successfully called from the same thread before instantiating this object.
707    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
708        poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
709    }
710}
711
712#[stable(feature = "std_debug", since = "1.16.0")]
713impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
714    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
715        (**self).fmt(f)
716    }
717}
718
719#[stable(feature = "std_guard_impls", since = "1.20.0")]
720impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
721    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
722        (**self).fmt(f)
723    }
724}
725
726#[stable(feature = "std_debug", since = "1.16.0")]
727impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
728    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
729        (**self).fmt(f)
730    }
731}
732
733#[stable(feature = "std_guard_impls", since = "1.20.0")]
734impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
735    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
736        (**self).fmt(f)
737    }
738}
739
740#[unstable(feature = "mapped_lock_guards", issue = "117108")]
741impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
742    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743        (**self).fmt(f)
744    }
745}
746
747#[unstable(feature = "mapped_lock_guards", issue = "117108")]
748impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
749    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
750        (**self).fmt(f)
751    }
752}
753
754#[unstable(feature = "mapped_lock_guards", issue = "117108")]
755impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
756    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
757        (**self).fmt(f)
758    }
759}
760
761#[unstable(feature = "mapped_lock_guards", issue = "117108")]
762impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
763    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
764        (**self).fmt(f)
765    }
766}
767
768#[stable(feature = "rust1", since = "1.0.0")]
769impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
770    type Target = T;
771
772    fn deref(&self) -> &T {
773        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
774        unsafe { self.data.as_ref() }
775    }
776}
777
778#[stable(feature = "rust1", since = "1.0.0")]
779impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
780    type Target = T;
781
782    fn deref(&self) -> &T {
783        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
784        unsafe { &*self.lock.data.get() }
785    }
786}
787
788#[stable(feature = "rust1", since = "1.0.0")]
789impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
790    fn deref_mut(&mut self) -> &mut T {
791        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
792        unsafe { &mut *self.lock.data.get() }
793    }
794}
795
796#[unstable(feature = "mapped_lock_guards", issue = "117108")]
797impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
798    type Target = T;
799
800    fn deref(&self) -> &T {
801        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
802        // was created, and have been upheld throughout `map` and/or `filter_map`.
803        unsafe { self.data.as_ref() }
804    }
805}
806
807#[unstable(feature = "mapped_lock_guards", issue = "117108")]
808impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
809    type Target = T;
810
811    fn deref(&self) -> &T {
812        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
813        // was created, and have been upheld throughout `map` and/or `filter_map`.
814        unsafe { self.data.as_ref() }
815    }
816}
817
818#[unstable(feature = "mapped_lock_guards", issue = "117108")]
819impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
820    fn deref_mut(&mut self) -> &mut T {
821        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
822        // was created, and have been upheld throughout `map` and/or `filter_map`.
823        unsafe { self.data.as_mut() }
824    }
825}
826
827#[stable(feature = "rust1", since = "1.0.0")]
828impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
829    fn drop(&mut self) {
830        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
831        unsafe {
832            self.inner_lock.read_unlock();
833        }
834    }
835}
836
837#[stable(feature = "rust1", since = "1.0.0")]
838impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
839    fn drop(&mut self) {
840        self.lock.poison.done(&self.poison);
841        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
842        unsafe {
843            self.lock.inner.write_unlock();
844        }
845    }
846}
847
848#[unstable(feature = "mapped_lock_guards", issue = "117108")]
849impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
850    fn drop(&mut self) {
851        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
852        // was created, and have been upheld throughout `map` and/or `filter_map`.
853        unsafe {
854            self.inner_lock.read_unlock();
855        }
856    }
857}
858
859#[unstable(feature = "mapped_lock_guards", issue = "117108")]
860impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
861    fn drop(&mut self) {
862        self.poison_flag.done(&self.poison);
863        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
864        // was created, and have been upheld throughout `map` and/or `filter_map`.
865        unsafe {
866            self.inner_lock.write_unlock();
867        }
868    }
869}
870
871impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
872    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data, e.g.
873    /// an enum variant.
874    ///
875    /// The `RwLock` is already locked for reading, so this cannot fail.
876    ///
877    /// This is an associated function that needs to be used as
878    /// `RwLockReadGuard::map(...)`. A method would interfere with methods of
879    /// the same name on the contents of the `RwLockReadGuard` used through
880    /// `Deref`.
881    ///
882    /// # Panics
883    ///
884    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
885    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
886    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
887    where
888        F: FnOnce(&T) -> &U,
889        U: ?Sized,
890    {
891        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
892        // was created, and have been upheld throughout `map` and/or `filter_map`.
893        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
894        // passed to it. If the closure panics, the guard will be dropped.
895        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
896        let orig = ManuallyDrop::new(orig);
897        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
898    }
899
900    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data. The
901    /// original guard is returned as an `Err(...)` if the closure returns
902    /// `None`.
903    ///
904    /// The `RwLock` is already locked for reading, so this cannot fail.
905    ///
906    /// This is an associated function that needs to be used as
907    /// `RwLockReadGuard::filter_map(...)`. A method would interfere with methods
908    /// of the same name on the contents of the `RwLockReadGuard` used through
909    /// `Deref`.
910    ///
911    /// # Panics
912    ///
913    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
914    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
915    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
916    where
917        F: FnOnce(&T) -> Option<&U>,
918        U: ?Sized,
919    {
920        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
921        // was created, and have been upheld throughout `map` and/or `filter_map`.
922        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
923        // passed to it. If the closure panics, the guard will be dropped.
924        match f(unsafe { orig.data.as_ref() }) {
925            Some(data) => {
926                let data = NonNull::from(data);
927                let orig = ManuallyDrop::new(orig);
928                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
929            }
930            None => Err(orig),
931        }
932    }
933}
934
935impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
936    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data,
937    /// e.g. an enum variant.
938    ///
939    /// The `RwLock` is already locked for reading, so this cannot fail.
940    ///
941    /// This is an associated function that needs to be used as
942    /// `MappedRwLockReadGuard::map(...)`. A method would interfere with
943    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
944    /// used through `Deref`.
945    ///
946    /// # Panics
947    ///
948    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
949    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
950    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
951    where
952        F: FnOnce(&T) -> &U,
953        U: ?Sized,
954    {
955        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
956        // was created, and have been upheld throughout `map` and/or `filter_map`.
957        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
958        // passed to it. If the closure panics, the guard will be dropped.
959        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
960        let orig = ManuallyDrop::new(orig);
961        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
962    }
963
964    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data.
965    /// The original guard is returned as an `Err(...)` if the closure returns
966    /// `None`.
967    ///
968    /// The `RwLock` is already locked for reading, so this cannot fail.
969    ///
970    /// This is an associated function that needs to be used as
971    /// `MappedRwLockReadGuard::filter_map(...)`. A method would interfere with
972    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
973    /// used through `Deref`.
974    ///
975    /// # Panics
976    ///
977    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
978    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
979    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
980    where
981        F: FnOnce(&T) -> Option<&U>,
982        U: ?Sized,
983    {
984        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
985        // was created, and have been upheld throughout `map` and/or `filter_map`.
986        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
987        // passed to it. If the closure panics, the guard will be dropped.
988        match f(unsafe { orig.data.as_ref() }) {
989            Some(data) => {
990                let data = NonNull::from(data);
991                let orig = ManuallyDrop::new(orig);
992                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
993            }
994            None => Err(orig),
995        }
996    }
997}
998
999impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
1000    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data, e.g.
1001    /// an enum variant.
1002    ///
1003    /// The `RwLock` is already locked for writing, so this cannot fail.
1004    ///
1005    /// This is an associated function that needs to be used as
1006    /// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
1007    /// the same name on the contents of the `RwLockWriteGuard` used through
1008    /// `Deref`.
1009    ///
1010    /// # Panics
1011    ///
1012    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1013    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1014    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1015    where
1016        F: FnOnce(&mut T) -> &mut U,
1017        U: ?Sized,
1018    {
1019        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1020        // was created, and have been upheld throughout `map` and/or `filter_map`.
1021        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1022        // passed to it. If the closure panics, the guard will be dropped.
1023        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
1024        let orig = ManuallyDrop::new(orig);
1025        MappedRwLockWriteGuard {
1026            data,
1027            inner_lock: &orig.lock.inner,
1028            poison_flag: &orig.lock.poison,
1029            poison: orig.poison.clone(),
1030            _variance: PhantomData,
1031        }
1032    }
1033
1034    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data. The
1035    /// original guard is returned as an `Err(...)` if the closure returns
1036    /// `None`.
1037    ///
1038    /// The `RwLock` is already locked for writing, so this cannot fail.
1039    ///
1040    /// This is an associated function that needs to be used as
1041    /// `RwLockWriteGuard::filter_map(...)`. A method would interfere with methods
1042    /// of the same name on the contents of the `RwLockWriteGuard` used through
1043    /// `Deref`.
1044    ///
1045    /// # Panics
1046    ///
1047    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1048    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1049    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1050    where
1051        F: FnOnce(&mut T) -> Option<&mut U>,
1052        U: ?Sized,
1053    {
1054        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1055        // was created, and have been upheld throughout `map` and/or `filter_map`.
1056        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1057        // passed to it. If the closure panics, the guard will be dropped.
1058        match f(unsafe { &mut *orig.lock.data.get() }) {
1059            Some(data) => {
1060                let data = NonNull::from(data);
1061                let orig = ManuallyDrop::new(orig);
1062                Ok(MappedRwLockWriteGuard {
1063                    data,
1064                    inner_lock: &orig.lock.inner,
1065                    poison_flag: &orig.lock.poison,
1066                    poison: orig.poison.clone(),
1067                    _variance: PhantomData,
1068                })
1069            }
1070            None => Err(orig),
1071        }
1072    }
1073
1074    /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
1075    ///
1076    /// This method will atomically change the state of the [`RwLock`] from exclusive mode into
1077    /// shared mode. This means that it is impossible for a writing thread to get in between a
1078    /// thread calling `downgrade` and the same thread reading whatever it wrote while it had the
1079    /// [`RwLock`] in write mode.
1080    ///
1081    /// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
1082    /// locked for writing, so this method cannot fail.
1083    ///
1084    /// # Example
1085    ///
1086    /// ```
1087    /// #![feature(rwlock_downgrade)]
1088    /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
1089    ///
1090    /// // The inner value starts as 0.
1091    /// let rw = Arc::new(RwLock::new(0));
1092    ///
1093    /// // Put the lock in write mode.
1094    /// let mut main_write_guard = rw.write().unwrap();
1095    ///
1096    /// let evil = rw.clone();
1097    /// let handle = std::thread::spawn(move || {
1098    ///     // This will not return until the main thread drops the `main_read_guard`.
1099    ///     let mut evil_guard = evil.write().unwrap();
1100    ///
1101    ///     assert_eq!(*evil_guard, 1);
1102    ///     *evil_guard = 2;
1103    /// });
1104    ///
1105    /// // After spawning the writer thread, set the inner value to 1.
1106    /// *main_write_guard = 1;
1107    ///
1108    /// // Atomically downgrade the write guard into a read guard.
1109    /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
1110    ///
1111    /// // Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
1112    /// assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");
1113    ///
1114    /// // Clean up everything now
1115    /// drop(main_read_guard);
1116    /// handle.join().unwrap();
1117    ///
1118    /// let final_check = rw.read().unwrap();
1119    /// assert_eq!(*final_check, 2);
1120    /// ```
1121    #[unstable(feature = "rwlock_downgrade", issue = "128203")]
1122    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {
1123        let lock = s.lock;
1124
1125        // We don't want to call the destructor since that calls `write_unlock`.
1126        forget(s);
1127
1128        // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
1129        // mode, satisfying the `downgrade` contract.
1130        unsafe { lock.inner.downgrade() };
1131
1132        // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
1133        unsafe { RwLockReadGuard::new(lock).unwrap_or_else(PoisonError::into_inner) }
1134    }
1135}
1136
1137impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
1138    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data,
1139    /// e.g. an enum variant.
1140    ///
1141    /// The `RwLock` is already locked for writing, so this cannot fail.
1142    ///
1143    /// This is an associated function that needs to be used as
1144    /// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
1145    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1146    /// used through `Deref`.
1147    ///
1148    /// # Panics
1149    ///
1150    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1151    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1152    pub fn map<U, F>(mut orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1153    where
1154        F: FnOnce(&mut T) -> &mut U,
1155        U: ?Sized,
1156    {
1157        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1158        // was created, and have been upheld throughout `map` and/or `filter_map`.
1159        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1160        // passed to it. If the closure panics, the guard will be dropped.
1161        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
1162        let orig = ManuallyDrop::new(orig);
1163        MappedRwLockWriteGuard {
1164            data,
1165            inner_lock: orig.inner_lock,
1166            poison_flag: orig.poison_flag,
1167            poison: orig.poison.clone(),
1168            _variance: PhantomData,
1169        }
1170    }
1171
1172    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data.
1173    /// The original guard is returned as an `Err(...)` if the closure returns
1174    /// `None`.
1175    ///
1176    /// The `RwLock` is already locked for writing, so this cannot fail.
1177    ///
1178    /// This is an associated function that needs to be used as
1179    /// `MappedRwLockWriteGuard::filter_map(...)`. A method would interfere with
1180    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1181    /// used through `Deref`.
1182    ///
1183    /// # Panics
1184    ///
1185    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1186    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1187    pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1188    where
1189        F: FnOnce(&mut T) -> Option<&mut U>,
1190        U: ?Sized,
1191    {
1192        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1193        // was created, and have been upheld throughout `map` and/or `filter_map`.
1194        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1195        // passed to it. If the closure panics, the guard will be dropped.
1196        match f(unsafe { orig.data.as_mut() }) {
1197            Some(data) => {
1198                let data = NonNull::from(data);
1199                let orig = ManuallyDrop::new(orig);
1200                Ok(MappedRwLockWriteGuard {
1201                    data,
1202                    inner_lock: orig.inner_lock,
1203                    poison_flag: orig.poison_flag,
1204                    poison: orig.poison.clone(),
1205                    _variance: PhantomData,
1206                })
1207            }
1208            None => Err(orig),
1209        }
1210    }
1211}