about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Lifshay <programmerjake@gmail.com>2024-05-24 16:17:19 -0700
committerJacob Lifshay <programmerjake@gmail.com>2024-05-24 17:44:37 -0700
commitf4b9ac68f306f630b5167959d5ee90626a9d7d84 (patch)
treec9064fe5d46bcd34b78f263d07989926e5423477
parent36153f1a4e3162f0a143c7b3e468ecb3beb0008e (diff)
downloadrust-f4b9ac68f306f630b5167959d5ee90626a9d7d84.tar.gz
rust-f4b9ac68f306f630b5167959d5ee90626a9d7d84.zip
Add manual Sync impl for ReentrantLockGuard
Fixes: #125526
-rw-r--r--library/std/src/sync/reentrant_lock.rs3
-rw-r--r--tests/ui/sync/reentrantlockguard-sync.rs15
-rw-r--r--tests/ui/sync/reentrantlockguard-sync.stderr20
3 files changed, 38 insertions, 0 deletions
diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs
index 80b9e0cf152..f7fe8eb1c7f 100644
--- a/library/std/src/sync/reentrant_lock.rs
+++ b/library/std/src/sync/reentrant_lock.rs
@@ -117,6 +117,9 @@ pub struct ReentrantLockGuard<'a, T: ?Sized + 'a> {
 impl<T: ?Sized> !Send for ReentrantLockGuard<'_, T> {}
 
 #[unstable(feature = "reentrant_lock", issue = "121440")]
+unsafe impl<T: ?Sized + Sync> Sync for ReentrantLockGuard<'_, T> {}
+
+#[unstable(feature = "reentrant_lock", issue = "121440")]
 impl<T> ReentrantLock<T> {
     /// Creates a new re-entrant lock in an unlocked state ready for use.
     ///
diff --git a/tests/ui/sync/reentrantlockguard-sync.rs b/tests/ui/sync/reentrantlockguard-sync.rs
new file mode 100644
index 00000000000..84d5b1834a8
--- /dev/null
+++ b/tests/ui/sync/reentrantlockguard-sync.rs
@@ -0,0 +1,15 @@
+#![feature(reentrant_lock)]
+use std::sync::ReentrantLock;
+use std::cell::Cell;
+
+// ReentrantLockGuard<Cell<i32>> must not be Sync, that would be unsound.
+
+fn test_sync<T: Sync>(_t: T) {}
+
+fn main()
+{
+    let m = ReentrantLock::new(Cell::new(0i32));
+    let guard = m.lock();
+    test_sync(guard);
+    //~^ ERROR `Cell<i32>` cannot be shared between threads safely [E0277]
+}
diff --git a/tests/ui/sync/reentrantlockguard-sync.stderr b/tests/ui/sync/reentrantlockguard-sync.stderr
new file mode 100644
index 00000000000..ed2e3e2f112
--- /dev/null
+++ b/tests/ui/sync/reentrantlockguard-sync.stderr
@@ -0,0 +1,20 @@
+error[E0277]: `Cell<i32>` cannot be shared between threads safely
+  --> $DIR/reentrantlockguard-sync.rs:13:15
+   |
+LL |     test_sync(guard);
+   |     --------- ^^^^^ `Cell<i32>` cannot be shared between threads safely
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Sync` is not implemented for `Cell<i32>`, which is required by `ReentrantLockGuard<'_, Cell<i32>>: Sync`
+   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` or `std::sync::atomic::AtomicI32` instead
+   = note: required for `ReentrantLockGuard<'_, Cell<i32>>` to implement `Sync`
+note: required by a bound in `test_sync`
+  --> $DIR/reentrantlockguard-sync.rs:7:17
+   |
+LL | fn test_sync<T: Sync>(_t: T) {}
+   |                 ^^^^ required by this bound in `test_sync`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.