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 [`try_map`] methods
151/// on [`RwLockReadGuard`].
152///
153/// [`map`]: RwLockReadGuard::map
154/// [`try_map`]: RwLockReadGuard::try_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 [`try_map`] methods
180/// on [`RwLockWriteGuard`].
181///
182/// [`map`]: RwLockWriteGuard::map
183/// [`try_map`]: RwLockWriteGuard::try_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
639#[stable(feature = "rust1", since = "1.0.0")]
640impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
641    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
642        let mut d = f.debug_struct("RwLock");
643        match self.try_read() {
644            Ok(guard) => {
645                d.field("data", &&*guard);
646            }
647            Err(TryLockError::Poisoned(err)) => {
648                d.field("data", &&**err.get_ref());
649            }
650            Err(TryLockError::WouldBlock) => {
651                d.field("data", &format_args!("<locked>"));
652            }
653        }
654        d.field("poisoned", &self.poison.get());
655        d.finish_non_exhaustive()
656    }
657}
658
659#[stable(feature = "rw_lock_default", since = "1.10.0")]
660impl<T: Default> Default for RwLock<T> {
661    /// Creates a new `RwLock<T>`, with the `Default` value for T.
662    fn default() -> RwLock<T> {
663        RwLock::new(Default::default())
664    }
665}
666
667#[stable(feature = "rw_lock_from", since = "1.24.0")]
668impl<T> From<T> for RwLock<T> {
669    /// Creates a new instance of an `RwLock<T>` which is unlocked.
670    /// This is equivalent to [`RwLock::new`].
671    fn from(t: T) -> Self {
672        RwLock::new(t)
673    }
674}
675
676impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
677    /// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
678    ///
679    /// # Safety
680    ///
681    /// This function is safe if and only if the same thread has successfully and safely called
682    /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
683    /// instantiating this object.
684    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
685        poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
686            data: unsafe { NonNull::new_unchecked(lock.data.get()) },
687            inner_lock: &lock.inner,
688        })
689    }
690}
691
692impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
693    /// Creates a new instance of `RwLockWriteGuard<T>` from a `RwLock<T>`.
694    // SAFETY: if and only if `lock.inner.write()` (or `lock.inner.try_write()`) has been
695    // successfully called from the same thread before instantiating this object.
696    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
697        poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
698    }
699}
700
701#[stable(feature = "std_debug", since = "1.16.0")]
702impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
703    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
704        (**self).fmt(f)
705    }
706}
707
708#[stable(feature = "std_guard_impls", since = "1.20.0")]
709impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
710    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711        (**self).fmt(f)
712    }
713}
714
715#[stable(feature = "std_debug", since = "1.16.0")]
716impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
717    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
718        (**self).fmt(f)
719    }
720}
721
722#[stable(feature = "std_guard_impls", since = "1.20.0")]
723impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
724    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
725        (**self).fmt(f)
726    }
727}
728
729#[unstable(feature = "mapped_lock_guards", issue = "117108")]
730impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
731    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732        (**self).fmt(f)
733    }
734}
735
736#[unstable(feature = "mapped_lock_guards", issue = "117108")]
737impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
738    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
739        (**self).fmt(f)
740    }
741}
742
743#[unstable(feature = "mapped_lock_guards", issue = "117108")]
744impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
745    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
746        (**self).fmt(f)
747    }
748}
749
750#[unstable(feature = "mapped_lock_guards", issue = "117108")]
751impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
752    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753        (**self).fmt(f)
754    }
755}
756
757#[stable(feature = "rust1", since = "1.0.0")]
758impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
759    type Target = T;
760
761    fn deref(&self) -> &T {
762        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
763        unsafe { self.data.as_ref() }
764    }
765}
766
767#[stable(feature = "rust1", since = "1.0.0")]
768impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
769    type Target = T;
770
771    fn deref(&self) -> &T {
772        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
773        unsafe { &*self.lock.data.get() }
774    }
775}
776
777#[stable(feature = "rust1", since = "1.0.0")]
778impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
779    fn deref_mut(&mut self) -> &mut T {
780        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
781        unsafe { &mut *self.lock.data.get() }
782    }
783}
784
785#[unstable(feature = "mapped_lock_guards", issue = "117108")]
786impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
787    type Target = T;
788
789    fn deref(&self) -> &T {
790        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
791        // was created, and have been upheld throughout `map` and/or `try_map`.
792        unsafe { self.data.as_ref() }
793    }
794}
795
796#[unstable(feature = "mapped_lock_guards", issue = "117108")]
797impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
798    type Target = T;
799
800    fn deref(&self) -> &T {
801        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
802        // was created, and have been upheld throughout `map` and/or `try_map`.
803        unsafe { self.data.as_ref() }
804    }
805}
806
807#[unstable(feature = "mapped_lock_guards", issue = "117108")]
808impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
809    fn deref_mut(&mut self) -> &mut T {
810        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
811        // was created, and have been upheld throughout `map` and/or `try_map`.
812        unsafe { self.data.as_mut() }
813    }
814}
815
816#[stable(feature = "rust1", since = "1.0.0")]
817impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
818    fn drop(&mut self) {
819        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
820        unsafe {
821            self.inner_lock.read_unlock();
822        }
823    }
824}
825
826#[stable(feature = "rust1", since = "1.0.0")]
827impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
828    fn drop(&mut self) {
829        self.lock.poison.done(&self.poison);
830        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
831        unsafe {
832            self.lock.inner.write_unlock();
833        }
834    }
835}
836
837#[unstable(feature = "mapped_lock_guards", issue = "117108")]
838impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
839    fn drop(&mut self) {
840        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
841        // was created, and have been upheld throughout `map` and/or `try_map`.
842        unsafe {
843            self.inner_lock.read_unlock();
844        }
845    }
846}
847
848#[unstable(feature = "mapped_lock_guards", issue = "117108")]
849impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
850    fn drop(&mut self) {
851        self.poison_flag.done(&self.poison);
852        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
853        // was created, and have been upheld throughout `map` and/or `try_map`.
854        unsafe {
855            self.inner_lock.write_unlock();
856        }
857    }
858}
859
860impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
861    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data, e.g.
862    /// an enum variant.
863    ///
864    /// The `RwLock` is already locked for reading, so this cannot fail.
865    ///
866    /// This is an associated function that needs to be used as
867    /// `RwLockReadGuard::map(...)`. A method would interfere with methods of
868    /// the same name on the contents of the `RwLockReadGuard` used through
869    /// `Deref`.
870    ///
871    /// # Panics
872    ///
873    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
874    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
875    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
876    where
877        F: FnOnce(&T) -> &U,
878        U: ?Sized,
879    {
880        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
881        // was created, and have been upheld throughout `map` and/or `try_map`.
882        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
883        // passed to it. If the closure panics, the guard will be dropped.
884        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
885        let orig = ManuallyDrop::new(orig);
886        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
887    }
888
889    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data. The
890    /// original guard is returned as an `Err(...)` if the closure returns
891    /// `None`.
892    ///
893    /// The `RwLock` is already locked for reading, so this cannot fail.
894    ///
895    /// This is an associated function that needs to be used as
896    /// `RwLockReadGuard::try_map(...)`. A method would interfere with methods
897    /// of the same name on the contents of the `RwLockReadGuard` used through
898    /// `Deref`.
899    ///
900    /// # Panics
901    ///
902    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
903    #[doc(alias = "filter_map")]
904    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
905    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
906    where
907        F: FnOnce(&T) -> Option<&U>,
908        U: ?Sized,
909    {
910        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
911        // was created, and have been upheld throughout `map` and/or `try_map`.
912        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
913        // passed to it. If the closure panics, the guard will be dropped.
914        match f(unsafe { orig.data.as_ref() }) {
915            Some(data) => {
916                let data = NonNull::from(data);
917                let orig = ManuallyDrop::new(orig);
918                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
919            }
920            None => Err(orig),
921        }
922    }
923}
924
925impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
926    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data,
927    /// e.g. an enum variant.
928    ///
929    /// The `RwLock` is already locked for reading, so this cannot fail.
930    ///
931    /// This is an associated function that needs to be used as
932    /// `MappedRwLockReadGuard::map(...)`. A method would interfere with
933    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
934    /// used through `Deref`.
935    ///
936    /// # Panics
937    ///
938    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
939    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
940    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
941    where
942        F: FnOnce(&T) -> &U,
943        U: ?Sized,
944    {
945        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
946        // was created, and have been upheld throughout `map` and/or `try_map`.
947        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
948        // passed to it. If the closure panics, the guard will be dropped.
949        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
950        let orig = ManuallyDrop::new(orig);
951        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
952    }
953
954    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data.
955    /// The original guard is returned as an `Err(...)` if the closure returns
956    /// `None`.
957    ///
958    /// The `RwLock` is already locked for reading, so this cannot fail.
959    ///
960    /// This is an associated function that needs to be used as
961    /// `MappedRwLockReadGuard::try_map(...)`. A method would interfere with
962    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
963    /// used through `Deref`.
964    ///
965    /// # Panics
966    ///
967    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
968    #[doc(alias = "filter_map")]
969    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
970    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
971    where
972        F: FnOnce(&T) -> Option<&U>,
973        U: ?Sized,
974    {
975        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
976        // was created, and have been upheld throughout `map` and/or `try_map`.
977        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
978        // passed to it. If the closure panics, the guard will be dropped.
979        match f(unsafe { orig.data.as_ref() }) {
980            Some(data) => {
981                let data = NonNull::from(data);
982                let orig = ManuallyDrop::new(orig);
983                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
984            }
985            None => Err(orig),
986        }
987    }
988}
989
990impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
991    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data, e.g.
992    /// an enum variant.
993    ///
994    /// The `RwLock` is already locked for writing, so this cannot fail.
995    ///
996    /// This is an associated function that needs to be used as
997    /// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
998    /// the same name on the contents of the `RwLockWriteGuard` used through
999    /// `Deref`.
1000    ///
1001    /// # Panics
1002    ///
1003    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1004    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1005    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1006    where
1007        F: FnOnce(&mut T) -> &mut U,
1008        U: ?Sized,
1009    {
1010        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1011        // was created, and have been upheld throughout `map` and/or `try_map`.
1012        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1013        // passed to it. If the closure panics, the guard will be dropped.
1014        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
1015        let orig = ManuallyDrop::new(orig);
1016        MappedRwLockWriteGuard {
1017            data,
1018            inner_lock: &orig.lock.inner,
1019            poison_flag: &orig.lock.poison,
1020            poison: orig.poison.clone(),
1021            _variance: PhantomData,
1022        }
1023    }
1024
1025    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data. The
1026    /// original guard is returned as an `Err(...)` if the closure returns
1027    /// `None`.
1028    ///
1029    /// The `RwLock` is already locked for writing, so this cannot fail.
1030    ///
1031    /// This is an associated function that needs to be used as
1032    /// `RwLockWriteGuard::try_map(...)`. A method would interfere with methods
1033    /// of the same name on the contents of the `RwLockWriteGuard` used through
1034    /// `Deref`.
1035    ///
1036    /// # Panics
1037    ///
1038    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1039    #[doc(alias = "filter_map")]
1040    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1041    pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1042    where
1043        F: FnOnce(&mut T) -> Option<&mut U>,
1044        U: ?Sized,
1045    {
1046        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1047        // was created, and have been upheld throughout `map` and/or `try_map`.
1048        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1049        // passed to it. If the closure panics, the guard will be dropped.
1050        match f(unsafe { &mut *orig.lock.data.get() }) {
1051            Some(data) => {
1052                let data = NonNull::from(data);
1053                let orig = ManuallyDrop::new(orig);
1054                Ok(MappedRwLockWriteGuard {
1055                    data,
1056                    inner_lock: &orig.lock.inner,
1057                    poison_flag: &orig.lock.poison,
1058                    poison: orig.poison.clone(),
1059                    _variance: PhantomData,
1060                })
1061            }
1062            None => Err(orig),
1063        }
1064    }
1065
1066    /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
1067    ///
1068    /// This method will atomically change the state of the [`RwLock`] from exclusive mode into
1069    /// shared mode. This means that it is impossible for a writing thread to get in between a
1070    /// thread calling `downgrade` and the same thread reading whatever it wrote while it had the
1071    /// [`RwLock`] in write mode.
1072    ///
1073    /// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
1074    /// locked for writing, so this method cannot fail.
1075    ///
1076    /// # Example
1077    ///
1078    /// ```
1079    /// #![feature(rwlock_downgrade)]
1080    /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
1081    ///
1082    /// // The inner value starts as 0.
1083    /// let rw = Arc::new(RwLock::new(0));
1084    ///
1085    /// // Put the lock in write mode.
1086    /// let mut main_write_guard = rw.write().unwrap();
1087    ///
1088    /// let evil = rw.clone();
1089    /// let handle = std::thread::spawn(move || {
1090    ///     // This will not return until the main thread drops the `main_read_guard`.
1091    ///     let mut evil_guard = evil.write().unwrap();
1092    ///
1093    ///     assert_eq!(*evil_guard, 1);
1094    ///     *evil_guard = 2;
1095    /// });
1096    ///
1097    /// // After spawning the writer thread, set the inner value to 1.
1098    /// *main_write_guard = 1;
1099    ///
1100    /// // Atomically downgrade the write guard into a read guard.
1101    /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
1102    ///
1103    /// // Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
1104    /// assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");
1105    ///
1106    /// // Clean up everything now
1107    /// drop(main_read_guard);
1108    /// handle.join().unwrap();
1109    ///
1110    /// let final_check = rw.read().unwrap();
1111    /// assert_eq!(*final_check, 2);
1112    /// ```
1113    #[unstable(feature = "rwlock_downgrade", issue = "128203")]
1114    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {
1115        let lock = s.lock;
1116
1117        // We don't want to call the destructor since that calls `write_unlock`.
1118        forget(s);
1119
1120        // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
1121        // mode, satisfying the `downgrade` contract.
1122        unsafe { lock.inner.downgrade() };
1123
1124        // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
1125        unsafe { RwLockReadGuard::new(lock).unwrap_or_else(PoisonError::into_inner) }
1126    }
1127}
1128
1129impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
1130    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data,
1131    /// e.g. an enum variant.
1132    ///
1133    /// The `RwLock` is already locked for writing, so this cannot fail.
1134    ///
1135    /// This is an associated function that needs to be used as
1136    /// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
1137    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1138    /// used through `Deref`.
1139    ///
1140    /// # Panics
1141    ///
1142    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1143    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1144    pub fn map<U, F>(mut orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1145    where
1146        F: FnOnce(&mut T) -> &mut U,
1147        U: ?Sized,
1148    {
1149        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1150        // was created, and have been upheld throughout `map` and/or `try_map`.
1151        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1152        // passed to it. If the closure panics, the guard will be dropped.
1153        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
1154        let orig = ManuallyDrop::new(orig);
1155        MappedRwLockWriteGuard {
1156            data,
1157            inner_lock: orig.inner_lock,
1158            poison_flag: orig.poison_flag,
1159            poison: orig.poison.clone(),
1160            _variance: PhantomData,
1161        }
1162    }
1163
1164    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data.
1165    /// The original guard is returned as an `Err(...)` if the closure returns
1166    /// `None`.
1167    ///
1168    /// The `RwLock` is already locked for writing, so this cannot fail.
1169    ///
1170    /// This is an associated function that needs to be used as
1171    /// `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with
1172    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1173    /// used through `Deref`.
1174    ///
1175    /// # Panics
1176    ///
1177    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1178    #[doc(alias = "filter_map")]
1179    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1180    pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1181    where
1182        F: FnOnce(&mut T) -> Option<&mut U>,
1183        U: ?Sized,
1184    {
1185        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1186        // was created, and have been upheld throughout `map` and/or `try_map`.
1187        // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1188        // passed to it. If the closure panics, the guard will be dropped.
1189        match f(unsafe { orig.data.as_mut() }) {
1190            Some(data) => {
1191                let data = NonNull::from(data);
1192                let orig = ManuallyDrop::new(orig);
1193                Ok(MappedRwLockWriteGuard {
1194                    data,
1195                    inner_lock: orig.inner_lock,
1196                    poison_flag: orig.poison_flag,
1197                    poison: orig.poison.clone(),
1198                    _variance: PhantomData,
1199                })
1200            }
1201            None => Err(orig),
1202        }
1203    }
1204}