Make RwLockReadGuard covariant

This commit is contained in:
Robin Raymond 2022-05-07 17:15:03 +00:00
parent 6c9be6e4e9
commit 7cefa8f995
2 changed files with 18 additions and 5 deletions

View File

@ -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();
}
}
}

View File

@ -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);
}