about summary refs log tree commit diff
path: root/library/std/tests/sync/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/tests/sync/lib.rs')
-rw-r--r--library/std/tests/sync/lib.rs55
1 files changed, 55 insertions, 0 deletions
diff --git a/library/std/tests/sync/lib.rs b/library/std/tests/sync/lib.rs
index 51190f0894f..94f1fe96b6a 100644
--- a/library/std/tests/sync/lib.rs
+++ b/library/std/tests/sync/lib.rs
@@ -6,7 +6,10 @@
 #![feature(reentrant_lock)]
 #![feature(rwlock_downgrade)]
 #![feature(std_internals)]
+#![feature(sync_nonpoison)]
+#![feature(nonpoison_mutex)]
 #![allow(internal_features)]
+#![feature(macro_metavar_expr_concat)] // For concatenating identifiers in macros.
 
 mod barrier;
 mod condvar;
@@ -29,3 +32,55 @@ mod rwlock;
 
 #[path = "../common/mod.rs"]
 mod common;
+
+#[track_caller]
+fn result_unwrap<T, E: std::fmt::Debug>(x: Result<T, E>) -> T {
+    x.unwrap()
+}
+
+/// A macro that generates two test cases for both the poison and nonpoison locks.
+///
+/// To write a test that tests both `poison` and `nonpoison` locks, import any of the types
+/// under both `poison` and `nonpoison` using the module name `locks` instead. For example, write
+/// `use locks::Mutex;` instead of `use std::sync::poiosn::Mutex`. This will import the correct type
+/// for each test variant.
+///
+/// Write a test as normal in the `test_body`, but instead of calling `unwrap` on `poison` methods
+/// that return a `LockResult` or similar, call the function `maybe_unwrap(...)` on the result.
+///
+/// For example, call `maybe_unwrap(mutex.lock())` instead of `mutex.lock().unwrap()` or
+/// `maybe_unwrap(rwlock.read())` instead of `rwlock.read().unwrap()`.
+///
+/// For the `poison` types, `maybe_unwrap` will simply unwrap the `Result` (usually this is a form
+/// of `LockResult`, but it could also be other kinds of results). For the `nonpoison` types, it is
+/// a no-op (the identity function).
+///
+/// The test names will be prefiex with `poison_` or `nonpoison_`.
+macro_rules! nonpoison_and_poison_unwrap_test {
+    (
+        name: $name:ident,
+        test_body: {$($test_body:tt)*}
+    ) => {
+        // Creates the nonpoison test.
+        #[test]
+        fn ${concat(nonpoison_, $name)}() {
+            #[allow(unused_imports)]
+            use ::std::convert::identity as maybe_unwrap;
+            use ::std::sync::nonpoison as locks;
+
+            $($test_body)*
+        }
+
+        // Creates the poison test with the suffix `_unwrap_poisoned`.
+        #[test]
+        fn ${concat(poison_, $name)}() {
+            #[allow(unused_imports)]
+            use super::result_unwrap as maybe_unwrap;
+            use ::std::sync::poison as locks;
+
+            $($test_body)*
+        }
+    }
+}
+
+use nonpoison_and_poison_unwrap_test;