diff --git a/rust-version b/rust-version index 4577339061..dafb049cc5 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -a09c668c965f735f4cd59e7158662b9daa0b71ba +8aab472d52ba7314dc193c73abcd384e2586123c diff --git a/tests/pass/concurrency/sync.rs b/tests/pass/concurrency/sync.rs index 5b7805ba22..396c1a97e0 100644 --- a/tests/pass/concurrency/sync.rs +++ b/tests/pass/concurrency/sync.rs @@ -35,7 +35,7 @@ fn check_conditional_variables_notify_one() { let pair2 = pair.clone(); // Spawn a new thread. - thread::spawn(move || { + let t = thread::spawn(move || { thread::yield_now(); let (lock, cvar) = &*pair2; let mut started = lock.lock().unwrap(); @@ -50,6 +50,8 @@ fn check_conditional_variables_notify_one() { while !*started { started = cvar.wait(started).unwrap(); } + + t.join().unwrap(); } /// Test that waiting on a conditional variable with a timeout does not @@ -191,51 +193,6 @@ fn check_once() { } } -fn check_rwlock_unlock_bug1() { - // There was a bug where when un-read-locking an rwlock that still has other - // readers waiting, we'd accidentally also let a writer in. - // That caused an ICE. - let l = Arc::new(RwLock::new(0)); - - let r1 = l.read().unwrap(); - let r2 = l.read().unwrap(); - - // Make a waiting writer. - let l2 = l.clone(); - thread::spawn(move || { - let mut w = l2.write().unwrap(); - *w += 1; - }); - thread::yield_now(); - - drop(r1); - assert_eq!(*r2, 0); - thread::yield_now(); - thread::yield_now(); - thread::yield_now(); - assert_eq!(*r2, 0); - drop(r2); -} - -fn check_rwlock_unlock_bug2() { - // There was a bug where when un-read-locking an rwlock by letting the last reader leaver, - // we'd forget to wake up a writer. - // That meant the writer thread could never run again. - let l = Arc::new(RwLock::new(0)); - - let r = l.read().unwrap(); - - // Make a waiting writer. - let l2 = l.clone(); - let h = thread::spawn(move || { - let _w = l2.write().unwrap(); - }); - thread::yield_now(); - - drop(r); - h.join().unwrap(); -} - fn park_timeout() { let start = Instant::now(); @@ -277,8 +234,6 @@ fn main() { check_rwlock_write(); check_rwlock_read_no_deadlock(); check_once(); - check_rwlock_unlock_bug1(); - check_rwlock_unlock_bug2(); park_timeout(); park_unpark(); check_condvar(); diff --git a/tests/pass/concurrency/sync_nopreempt.rs b/tests/pass/concurrency/sync_nopreempt.rs index 8895d62df9..391f65ae5a 100644 --- a/tests/pass/concurrency/sync_nopreempt.rs +++ b/tests/pass/concurrency/sync_nopreempt.rs @@ -2,7 +2,7 @@ // We are making scheduler assumptions here. // compile-flags: -Zmiri-strict-provenance -Zmiri-preemption-rate=0 -use std::sync::{Arc, Condvar, Mutex}; +use std::sync::{Arc, Condvar, Mutex, RwLock}; use std::thread; fn check_conditional_variables_notify_all() { @@ -35,6 +35,53 @@ fn check_conditional_variables_notify_all() { } } +fn check_rwlock_unlock_bug1() { + // There was a bug where when un-read-locking an rwlock that still has other + // readers waiting, we'd accidentally also let a writer in. + // That caused an ICE. + let l = Arc::new(RwLock::new(0)); + + let r1 = l.read().unwrap(); + let r2 = l.read().unwrap(); + + // Make a waiting writer. + let l2 = l.clone(); + thread::spawn(move || { + let mut w = l2.write().unwrap(); + *w += 1; + }); + thread::yield_now(); + + drop(r1); + assert_eq!(*r2, 0); + thread::yield_now(); + thread::yield_now(); + thread::yield_now(); + assert_eq!(*r2, 0); + drop(r2); +} + +fn check_rwlock_unlock_bug2() { + // There was a bug where when un-read-locking an rwlock by letting the last reader leaver, + // we'd forget to wake up a writer. + // That meant the writer thread could never run again. + let l = Arc::new(RwLock::new(0)); + + let r = l.read().unwrap(); + + // Make a waiting writer. + let l2 = l.clone(); + let h = thread::spawn(move || { + let _w = l2.write().unwrap(); + }); + thread::yield_now(); + + drop(r); + h.join().unwrap(); +} + fn main() { check_conditional_variables_notify_all(); + check_rwlock_unlock_bug1(); + check_rwlock_unlock_bug2(); } diff --git a/tests/pass/concurrency/sync_singlethread.rs b/tests/pass/concurrency/sync_singlethread.rs index 5663e1c142..3301715554 100644 --- a/tests/pass/concurrency/sync_singlethread.rs +++ b/tests/pass/concurrency/sync_singlethread.rs @@ -1,9 +1,11 @@ use std::hint; +use std::mem; use std::sync::atomic; use std::sync::{Mutex, TryLockError}; fn main() { test_mutex_stdlib(); + leak_mutex_guard(); test_rwlock_stdlib(); test_spin_loop_hint(); test_thread_yield_now(); @@ -19,6 +21,12 @@ fn test_mutex_stdlib() { drop(m); } +fn leak_mutex_guard() { + // Test for https://github.com/rust-lang/rust/issues/85434 + let m = Mutex::new(5i32); + mem::forget(m.lock()); +} + fn test_rwlock_stdlib() { use std::sync::RwLock; let rw = RwLock::new(0);