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