Skip to content

Commit 7cefa8f

Browse files
committed
Make RwLockReadGuard covariant
1 parent 6c9be6e commit 7cefa8f

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

library/std/src/sync/rwlock.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
101101
#[stable(feature = "rust1", since = "1.0.0")]
102102
#[clippy::has_significant_drop]
103103
pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
104-
lock: &'a RwLock<T>,
104+
inner_lock: &'a sys::MovableRwLock,
105+
data: &'a T,
105106
}
106107

107108
#[stable(feature = "rust1", since = "1.0.0")]
@@ -510,7 +511,7 @@ impl<T> From<T> for RwLock<T> {
510511

511512
impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
512513
unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
513-
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { lock })
514+
poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { inner_lock: &lock.inner, data: &*lock.data.get() })
514515
}
515516
}
516517

@@ -553,7 +554,7 @@ impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
553554
type Target = T;
554555

555556
fn deref(&self) -> &T {
556-
unsafe { &*self.lock.data.get() }
557+
self.data
557558
}
558559
}
559560

@@ -577,7 +578,7 @@ impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
577578
impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
578579
fn drop(&mut self) {
579580
unsafe {
580-
self.lock.inner.read_unlock();
581+
self.inner_lock.read_unlock();
581582
}
582583
}
583584
}

library/std/src/sync/rwlock/tests.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::sync::atomic::{AtomicUsize, Ordering};
22
use crate::sync::mpsc::channel;
3-
use crate::sync::{Arc, RwLock, TryLockError};
3+
use crate::sync::{Arc, RwLock, TryLockError, RwLockReadGuard};
44
use crate::thread;
55
use rand::{self, Rng};
66

@@ -245,3 +245,15 @@ fn test_get_mut_poison() {
245245
Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {x:?}"),
246246
}
247247
}
248+
249+
#[test]
250+
fn test_read_guard_covariance() {
251+
fn do_stuff<'a>(_: RwLockReadGuard<'_, &'a i32>, _: &'a i32) {}
252+
let j: i32 = 5;
253+
let lock = RwLock::new(&j);
254+
{
255+
let i = 6;
256+
do_stuff(lock.read().unwrap(), &i);
257+
}
258+
drop(lock);
259+
}

0 commit comments

Comments
 (0)