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