| #![feature(const_default)] | |
| #![feature(const_trait_impl)] | |
| #![feature(mapped_lock_guards)] | |
| #![feature(mpmc_channel)] | |
| #![feature(oneshot_channel)] | |
| #![feature(once_cell_try)] | |
| #![feature(lock_value_accessors)] | |
| #![feature(reentrant_lock)] | |
| #![feature(std_internals)] | |
| #![feature(sync_nonpoison)] | |
| #![feature(nonpoison_condvar)] | |
| #![feature(nonpoison_mutex)] | |
| #![feature(nonpoison_rwlock)] | |
| #![allow(internal_features)] | |
| #![feature(macro_metavar_expr_concat)] // For concatenating identifiers in macros. | |
| mod barrier; | |
| mod condvar; | |
| mod lazy_lock; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod mpmc; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod mpsc; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod mpsc_sync; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod mutex; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod once; | |
| mod once_lock; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod oneshot; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| mod reentrant_lock; | |
| #[cfg(not(any(target_os = "emscripten", target_os = "wasi")))] | |
| 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_`. | |
| /// | |
| /// Important: most attributes (except `cfg`) will not work properly! (They are only applied to the first test.) | |
| /// See <https://github.com/rust-lang/rust/pull/146433> for more information. | |
| 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; |