Skip to main content

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