about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-25 13:03:53 +0000
committerbors <bors@rust-lang.org>2022-06-25 13:03:53 +0000
commit00ce47209dfdd8ef8871c6ec804f0e0e04d10702 (patch)
tree1abaa350d2c066595ae08a0f5b82a64b1ad86a56 /src
parent1aabd8a4a6e1871f14e804302bd60dfcbffd5761 (diff)
parent5656de73d9541175e7dc20923995c54c0868ded6 (diff)
downloadrust-00ce47209dfdd8ef8871c6ec804f0e0e04d10702.tar.gz
rust-00ce47209dfdd8ef8871c6ec804f0e0e04d10702.zip
Auto merge of #96820 - r-raymond:master, r=cuviper
Make RwLockReadGuard covariant

Hi, first time contributor here, if anything is not as expected, please let me know.

`RwLockReadGoard`'s type constructor is invariant. Since it behaves like a smart pointer to an immutable reference, there is no reason that it should not be covariant. Take e.g.

```
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);
}
```
where the compiler complains that &i doesn't live long enough. If `RwLockReadGuard` is covariant, then the above code is accepted because the lifetime can be shorter than `'a`.

In order for `RwLockReadGuard` to be covariant, it can't contain a full reference to the `RwLock`, which can never be covariant (because it exposes a mutable reference to the underlying data structure). By reducing the data structure to the required pieces of `RwLock`, the rest falls in place.

If there is a better way to do a test that tests successful compilation, please let me know.

Fixes #80392
Diffstat (limited to 'src')
-rw-r--r--src/test/codegen/noalias-rwlockreadguard.rs14
-rw-r--r--src/test/debuginfo/rwlock-read.rs7
2 files changed, 16 insertions, 5 deletions
diff --git a/src/test/codegen/noalias-rwlockreadguard.rs b/src/test/codegen/noalias-rwlockreadguard.rs
new file mode 100644
index 00000000000..7f7b46c85a8
--- /dev/null
+++ b/src/test/codegen/noalias-rwlockreadguard.rs
@@ -0,0 +1,14 @@
+// compile-flags: -O -C no-prepopulate-passes -Z mutable-noalias=yes
+
+#![crate_type = "lib"]
+
+use std::sync::{RwLock, RwLockReadGuard};
+
+// Make sure that `RwLockReadGuard` does not get a `noalias` attribute, because
+// the `RwLock` might alias writes after it is dropped.
+
+// CHECK-LABEL: @maybe_aliased(
+// CHECK-NOT: noalias
+// CHECK-SAME: %_data
+#[no_mangle]
+pub unsafe fn maybe_aliased(_: RwLockReadGuard<'_, i32>, _data: &RwLock<i32>) {}
diff --git a/src/test/debuginfo/rwlock-read.rs b/src/test/debuginfo/rwlock-read.rs
index e1c10a4d37f..ed9aae16b0d 100644
--- a/src/test/debuginfo/rwlock-read.rs
+++ b/src/test/debuginfo/rwlock-read.rs
@@ -15,11 +15,8 @@
 //
 // cdb-command:dx r
 // cdb-check:r                [Type: std::sync::rwlock::RwLockReadGuard<i32>]
-// cdb-check:    [...] lock             : [...] [Type: std::sync::rwlock::RwLock<i32> *]
-//
-// cdb-command:dx r.lock->data,d
-// cdb-check:r.lock->data,d   : 0 [Type: core::cell::UnsafeCell<i32>]
-// cdb-check:    [<Raw View>]     [Type: core::cell::UnsafeCell<i32>]
+// cdb-check:    [...] data             : NonNull([...]: 0) [Type: core::ptr::non_null::NonNull<i32>]
+// cdb-check:    [...] inner_lock       : [...] [Type: std::sys_common::rwlock::MovableRwLock *]
 
 #[allow(unused_variables)]