std/sync/poison/
rwlock.rs

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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy