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