Skip to content

Commit 19ab767

Browse files
committed
use generic function instead of macro
Also cleans up some other test documentation.
1 parent 6312ee4 commit 19ab767

File tree

2 files changed

+61
-58
lines changed

2 files changed

+61
-58
lines changed

library/std/tests/sync/lib.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,54 +33,54 @@ mod rwlock;
3333
#[path = "../common/mod.rs"]
3434
mod common;
3535

36-
// A macro that generates two test cases for both the poison and nonpoison locks.
37-
//
38-
// To write a test that tests both `poison` and `nonpoison` locks, import any of the types
39-
// under both `poison` and `nonpoison` using the module name `locks` instead. For example, write
40-
// `use locks::Mutex;` instead of `use std::sync::poiosn::Mutex`. This will import the correct type
41-
// for each test variant.
42-
//
43-
// Write a test as normal in the `test_body`, but instead of calling `unwrap` on `poison` methods
44-
// that return a `LockResult` or similar, call the macro `maybe_unwrap!(...)` on the result.
45-
//
46-
// For example, call `maybe_unwrap!(mutex.lock())` instead of `mutex.lock().unwrap()` or
47-
// `maybe_unwrap!(rwlock.read())` instead of `rwlock.read().unwrap()`.
48-
//
49-
// For the `poison` types, `maybe_unwrap!` will simply unwrap the `Result` (usually this is a form
50-
// of `LockResult`, but it could also be other kinds of results). For the `nonpoison` types, it is a
51-
// no-op.
52-
//
53-
// The `poison` test will have the same `name`, but with a suffix of `_unwrap_poisoned`.
54-
#[macro_export]
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_`.
5559
macro_rules! nonpoison_and_poison_unwrap_test {
5660
(
5761
name: $name:ident,
5862
test_body: {$($test_body:tt)*}
5963
) => {
6064
// Creates the nonpoison test.
6165
#[test]
62-
fn $name() {
66+
fn ${concat(nonpoison_, $name)}() {
67+
#[allow(unused_imports)]
68+
use ::std::convert::identity as maybe_unwrap;
6369
use ::std::sync::nonpoison as locks;
6470

65-
#[allow(unused_macros)]
66-
macro_rules! maybe_unwrap {
67-
($e:expr) => { $e };
68-
}
69-
7071
$($test_body)*
7172
}
7273

7374
// Creates the poison test with the suffix `_unwrap_poisoned`.
7475
#[test]
75-
fn ${concat($name, _unwrap_poisoned)}() {
76+
fn ${concat(poison_, $name)}() {
77+
#[allow(unused_imports)]
78+
use super::result_unwrap as maybe_unwrap;
7679
use ::std::sync::poison as locks;
7780

78-
#[allow(unused_macros)]
79-
macro_rules! maybe_unwrap {
80-
($e:expr) => { ::std::result::Result::unwrap($e) };
81-
}
82-
8381
$($test_body)*
8482
}
8583
}
8684
}
85+
86+
use nonpoison_and_poison_unwrap_test;

library/std/tests/sync/mutex.rs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ nonpoison_and_poison_unwrap_test!(
1717
use locks::Mutex;
1818

1919
let m = Mutex::new(());
20-
drop(maybe_unwrap!(m.lock()));
21-
drop(maybe_unwrap!(m.lock()));
20+
drop(maybe_unwrap(m.lock()));
21+
drop(maybe_unwrap(m.lock()));
2222
}
2323
);
2424

@@ -34,7 +34,7 @@ nonpoison_and_poison_unwrap_test!(
3434

3535
fn inc(m: &Mutex<u32>) {
3636
for _ in 0..J {
37-
*maybe_unwrap!(m.lock()) += 1;
37+
*maybe_unwrap(m.lock()) += 1;
3838
}
3939
}
4040

@@ -58,7 +58,7 @@ nonpoison_and_poison_unwrap_test!(
5858
for _ in 0..2 * K {
5959
rx.recv().unwrap();
6060
}
61-
assert_eq!(*maybe_unwrap!(m.lock()), J * K * 2);
61+
assert_eq!(*maybe_unwrap(m.lock()), J * K * 2);
6262
}
6363
);
6464

@@ -96,7 +96,7 @@ nonpoison_and_poison_unwrap_test!(
9696
use locks::Mutex;
9797

9898
let m = Mutex::new(NonCopy(10));
99-
assert_eq!(maybe_unwrap!(m.into_inner()), NonCopy(10));
99+
assert_eq!(maybe_unwrap(m.into_inner()), NonCopy(10));
100100
}
101101
);
102102

@@ -116,7 +116,7 @@ nonpoison_and_poison_unwrap_test!(
116116
let m = Mutex::new(Foo(num_drops.clone()));
117117
assert_eq!(num_drops.load(Ordering::SeqCst), 0);
118118
{
119-
let _inner = maybe_unwrap!(m.into_inner());
119+
let _inner = maybe_unwrap(m.into_inner());
120120
assert_eq!(num_drops.load(Ordering::SeqCst), 0);
121121
}
122122
assert_eq!(num_drops.load(Ordering::SeqCst), 1);
@@ -129,8 +129,8 @@ nonpoison_and_poison_unwrap_test!(
129129
use locks::Mutex;
130130

131131
let mut m = Mutex::new(NonCopy(10));
132-
*maybe_unwrap!(m.get_mut()) = NonCopy(20);
133-
assert_eq!(maybe_unwrap!(m.into_inner()), NonCopy(20));
132+
*maybe_unwrap(m.get_mut()) = NonCopy(20);
133+
assert_eq!(maybe_unwrap(m.into_inner()), NonCopy(20));
134134
}
135135
);
136136

@@ -144,7 +144,7 @@ nonpoison_and_poison_unwrap_test!(
144144

145145
let m = Mutex::new(Cloneable(10));
146146

147-
assert_eq!(maybe_unwrap!(m.get_cloned()), Cloneable(10));
147+
assert_eq!(maybe_unwrap(m.get_cloned()), Cloneable(10));
148148
}
149149
);
150150

@@ -159,16 +159,17 @@ nonpoison_and_poison_unwrap_test!(
159159
{
160160
let m = Mutex::new(init());
161161

162-
assert_eq!(*maybe_unwrap!(m.lock()), init());
163-
maybe_unwrap!(m.set(value()));
164-
assert_eq!(*maybe_unwrap!(m.lock()), value());
162+
assert_eq!(*maybe_unwrap(m.lock()), init());
163+
maybe_unwrap(m.set(value()));
164+
assert_eq!(*maybe_unwrap(m.lock()), value());
165165
}
166166

167167
inner(|| NonCopy(10), || NonCopy(20));
168168
inner(|| NonCopyNeedsDrop(10), || NonCopyNeedsDrop(20));
169169
}
170170
);
171171

172+
// Ensure that old values that are replaced by `set` are correctly dropped.
172173
nonpoison_and_poison_unwrap_test!(
173174
name: test_set_drop,
174175
test_body: {
@@ -186,7 +187,7 @@ nonpoison_and_poison_unwrap_test!(
186187
assert_eq!(num_drops.load(Ordering::SeqCst), 0);
187188

188189
let different = Foo(Arc::new(AtomicUsize::new(42)));
189-
maybe_unwrap!(m.set(different));
190+
maybe_unwrap(m.set(different));
190191
assert_eq!(num_drops.load(Ordering::SeqCst), 1);
191192
}
192193
);
@@ -202,9 +203,9 @@ nonpoison_and_poison_unwrap_test!(
202203
{
203204
let m = Mutex::new(init());
204205

205-
assert_eq!(*maybe_unwrap!(m.lock()), init());
206-
assert_eq!(maybe_unwrap!(m.replace(value())), init());
207-
assert_eq!(*maybe_unwrap!(m.lock()), value());
206+
assert_eq!(*maybe_unwrap(m.lock()), init());
207+
assert_eq!(maybe_unwrap(m.replace(value())), init());
208+
assert_eq!(*maybe_unwrap(m.lock()), value());
208209
}
209210

210211
inner(|| NonCopy(10), || NonCopy(20));
@@ -257,8 +258,8 @@ nonpoison_and_poison_unwrap_test!(
257258
let arc2 = Arc::new(Mutex::new(arc));
258259
let (tx, rx) = channel();
259260
let _t = thread::spawn(move || {
260-
let lock = maybe_unwrap!(arc2.lock());
261-
let lock2 = maybe_unwrap!(lock.lock());
261+
let lock = maybe_unwrap(arc2.lock());
262+
let lock2 = maybe_unwrap(lock.lock());
262263
assert_eq!(*lock2, 1);
263264
tx.send(()).unwrap();
264265
});
@@ -273,12 +274,12 @@ nonpoison_and_poison_unwrap_test!(
273274

274275
let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
275276
{
276-
let b = &mut *maybe_unwrap!(mutex.lock());
277+
let b = &mut *maybe_unwrap(mutex.lock());
277278
b[0] = 4;
278279
b[2] = 5;
279280
}
280281
let comp: &[i32] = &[4, 2, 5];
281-
assert_eq!(&*maybe_unwrap!(mutex.lock()), comp);
282+
assert_eq!(&*maybe_unwrap(mutex.lock()), comp);
282283
}
283284
);
284285

@@ -289,16 +290,18 @@ nonpoison_and_poison_unwrap_test!(
289290

290291
let arr = [0; 4];
291292
let lock = Mutex::new(arr);
292-
let guard = maybe_unwrap!(lock.lock());
293+
let guard = maybe_unwrap(lock.lock());
293294
let guard = MutexGuard::map(guard, |arr| &mut arr[..2]);
294295
let mut guard = MappedMutexGuard::map(guard, |slice| &mut slice[1..]);
295296
assert_eq!(guard.len(), 1);
296297
guard[0] = 42;
297298
drop(guard);
298-
assert_eq!(*maybe_unwrap!(lock.lock()), [0, 42, 0, 0]);
299+
assert_eq!(*maybe_unwrap(lock.lock()), [0, 42, 0, 0]);
299300
}
300301
);
301302

303+
// Ensures that both mutex types are able to be locked even after threads that hold the guards
304+
// panic. This should be true even for the `nonpoison::Mutex`.
302305
#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
303306
nonpoison_and_poison_unwrap_test!(
304307
name: test_panics,
@@ -308,21 +311,21 @@ nonpoison_and_poison_unwrap_test!(
308311
let mutex = Mutex::new(42);
309312

310313
let catch_unwind_result1 = panic::catch_unwind(AssertUnwindSafe(|| {
311-
let _guard1 = maybe_unwrap!(mutex.lock());
314+
let _guard1 = maybe_unwrap(mutex.lock());
312315

313316
panic!("test panic with mutex once");
314317
}));
315318
assert!(catch_unwind_result1.is_err());
316319

317320
let catch_unwind_result2 = panic::catch_unwind(AssertUnwindSafe(|| {
318-
let _guard2 = maybe_unwrap!(mutex.lock());
321+
let _guard2 = maybe_unwrap(mutex.lock());
319322

320323
panic!("test panic with mutex twice");
321324
}));
322325
assert!(catch_unwind_result2.is_err());
323326

324327
let catch_unwind_result3 = panic::catch_unwind(AssertUnwindSafe(|| {
325-
let _guard3 = maybe_unwrap!(mutex.lock());
328+
let _guard3 = maybe_unwrap(mutex.lock());
326329

327330
panic!("test panic with mutex thrice");
328331
}));
@@ -344,14 +347,14 @@ nonpoison_and_poison_unwrap_test!(
344347
}
345348
impl Drop for Unwinder {
346349
fn drop(&mut self) {
347-
*maybe_unwrap!(self.i.lock()) += 1;
350+
*maybe_unwrap(self.i.lock()) += 1;
348351
}
349352
}
350353
let _u = Unwinder { i: arc2 };
351354
panic!();
352355
})
353356
.join();
354-
let lock = maybe_unwrap!(arc.lock());
357+
let lock = maybe_unwrap(arc.lock());
355358
assert_eq!(*lock, 2);
356359
}
357360
);

0 commit comments

Comments
 (0)