about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRobin Raymond <robin@robinraymond.de>2022-05-07 17:15:03 +0000
committerRobin Raymond <robin@robinraymond.de>2022-06-19 09:21:28 +0200
commit7cefa8f9959565acc6e3606cfa6aa1376c9f862f (patch)
tree2097f377f9fcdadd4425b3f9310fc64e2ad2947b
parent6c9be6e4e9074ca58cef8b1ded299eff72e3ac52 (diff)
downloadrust-7cefa8f9959565acc6e3606cfa6aa1376c9f862f.tar.gz
rust-7cefa8f9959565acc6e3606cfa6aa1376c9f862f.zip
Make RwLockReadGuard covariant
-rw-r--r--library/std/src/sync/rwlock.rs9
-rw-r--r--library/std/src/sync/rwlock/tests.rs14
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<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[clippy::has_significant_drop]
 pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-    lock: &'a RwLock<T>,
+    inner_lock: &'a sys::MovableRwLock,
+    data: &'a T,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -510,7 +511,7 @@ impl<T> From<T> for RwLock<T> {
 
 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
     unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
-        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<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
     type Target = T;
 
     fn deref(&self) -> &T {
-        unsafe { &*self.lock.data.get() }
+        self.data
     }
 }
 
@@ -577,7 +578,7 @@ impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
 impl<T: ?Sized> 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);
+}