From 7cefa8f9959565acc6e3606cfa6aa1376c9f862f Mon Sep 17 00:00:00 2001 From: Robin Raymond Date: Sat, 7 May 2022 17:15:03 +0000 Subject: [PATCH] Make RwLockReadGuard covariant --- library/std/src/sync/rwlock.rs | 9 +++++---- library/std/src/sync/rwlock/tests.rs | 14 +++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 9517e7e1f03..efd2771fa1c 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -101,7 +101,8 @@ unsafe impl Sync for RwLock {} #[stable(feature = "rust1", since = "1.0.0")] #[clippy::has_significant_drop] pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { - lock: &'a RwLock, + inner_lock: &'a sys::MovableRwLock, + data: &'a T, } #[stable(feature = "rust1", since = "1.0.0")] @@ -510,7 +511,7 @@ impl From for RwLock { impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { unsafe fn new(lock: &'rwlock RwLock) -> LockResult> { - poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { lock }) + poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { inner_lock: &lock.inner, data: &*lock.data.get() }) } } @@ -553,7 +554,7 @@ impl Deref for RwLockReadGuard<'_, T> { type Target = T; fn deref(&self) -> &T { - unsafe { &*self.lock.data.get() } + self.data } } @@ -577,7 +578,7 @@ impl DerefMut for RwLockWriteGuard<'_, T> { impl Drop for RwLockReadGuard<'_, T> { fn drop(&mut self) { unsafe { - self.lock.inner.read_unlock(); + self.inner_lock.read_unlock(); } } } diff --git a/library/std/src/sync/rwlock/tests.rs b/library/std/src/sync/rwlock/tests.rs index 53aa2b1e38a..1ffa13f8321 100644 --- a/library/std/src/sync/rwlock/tests.rs +++ b/library/std/src/sync/rwlock/tests.rs @@ -1,6 +1,6 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; use crate::sync::mpsc::channel; -use crate::sync::{Arc, RwLock, TryLockError}; +use crate::sync::{Arc, RwLock, TryLockError, RwLockReadGuard}; use crate::thread; use rand::{self, Rng}; @@ -245,3 +245,15 @@ fn test_get_mut_poison() { Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {x:?}"), } } + +#[test] +fn test_read_guard_covariance() { + fn do_stuff<'a>(_: RwLockReadGuard<'_, &'a i32>, _: &'a i32) {} + let j: i32 = 5; + let lock = RwLock::new(&j); + { + let i = 6; + do_stuff(lock.read().unwrap(), &i); + } + drop(lock); +}