rwlock.rs - source
Description: Source of the Rust file `library/std/src/sync/nonpoison/rwlock.rs`.

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