66#![ feature( reentrant_lock) ]
77#![ feature( rwlock_downgrade) ]
88#![ feature( std_internals) ]
9+ #![ feature( sync_nonpoison) ]
10+ #![ feature( nonpoison_mutex) ]
911#![ allow( internal_features) ]
12+ #![ feature( macro_metavar_expr_concat) ] // For concatenating identifiers in macros.
1013
1114mod barrier;
1215mod condvar;
@@ -29,3 +32,55 @@ mod rwlock;
2932
3033#[ path = "../common/mod.rs" ]
3134mod common;
35+
36+ #[ track_caller]
37+ fn result_unwrap < T , E : std:: fmt:: Debug > ( x : Result < T , E > ) -> T {
38+ x. unwrap ( )
39+ }
40+
41+ /// A macro that generates two test cases for both the poison and nonpoison locks.
42+ ///
43+ /// To write a test that tests both `poison` and `nonpoison` locks, import any of the types
44+ /// under both `poison` and `nonpoison` using the module name `locks` instead. For example, write
45+ /// `use locks::Mutex;` instead of `use std::sync::poiosn::Mutex`. This will import the correct type
46+ /// for each test variant.
47+ ///
48+ /// Write a test as normal in the `test_body`, but instead of calling `unwrap` on `poison` methods
49+ /// that return a `LockResult` or similar, call the function `maybe_unwrap(...)` on the result.
50+ ///
51+ /// For example, call `maybe_unwrap(mutex.lock())` instead of `mutex.lock().unwrap()` or
52+ /// `maybe_unwrap(rwlock.read())` instead of `rwlock.read().unwrap()`.
53+ ///
54+ /// For the `poison` types, `maybe_unwrap` will simply unwrap the `Result` (usually this is a form
55+ /// of `LockResult`, but it could also be other kinds of results). For the `nonpoison` types, it is
56+ /// a no-op (the identity function).
57+ ///
58+ /// The test names will be prefiex with `poison_` or `nonpoison_`.
59+ macro_rules! nonpoison_and_poison_unwrap_test {
60+ (
61+ name: $name: ident,
62+ test_body: { $( $test_body: tt) * }
63+ ) => {
64+ // Creates the nonpoison test.
65+ #[ test]
66+ fn ${ concat( nonpoison_, $name) } ( ) {
67+ #[ allow( unused_imports) ]
68+ use :: std:: convert:: identity as maybe_unwrap;
69+ use :: std:: sync:: nonpoison as locks;
70+
71+ $( $test_body) *
72+ }
73+
74+ // Creates the poison test with the suffix `_unwrap_poisoned`.
75+ #[ test]
76+ fn ${ concat( poison_, $name) } ( ) {
77+ #[ allow( unused_imports) ]
78+ use super :: result_unwrap as maybe_unwrap;
79+ use :: std:: sync:: poison as locks;
80+
81+ $( $test_body) *
82+ }
83+ }
84+ }
85+
86+ use nonpoison_and_poison_unwrap_test;
0 commit comments