1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Traits for describing the relationships between lock orders.
/// Indicates that `Self` is locked before `Other`.
///
/// Indicates that a lock corresponding to the lock level `Other` can be
/// acquired while a lock corresponding to the implementing type `Self` is
/// held.
///
/// This is similar to [`LockAfter`] but with inverted `Self` and `Other` types.
/// Like [`From`] and [`Into`], it allows writing `where` bounds more naturally.
/// This trait is blanket-implemented in terms of `LockAfter`.
/// Indicates that `Self` is locked after `Other`.
///
/// Indicates that a lock corresponding to the lock level for `Self` can be
/// acquired while a lock corresponding to the other lock level type `Other` is
/// held.
///
/// The trait bound `B: LockAfter<A>` indicates that, while a lock with level
/// `A` is held, a lock with level `B` can be acquired. The trait [`LockBefore`]
/// is blanket-implemented in terms of this trait, so `B: LockAfter<A>` implies
/// `A: LockBefore<B>`.
/// Implements [`LockAfter<L>`] transitively.
///
/// This:
/// ```
/// # use lock_ordering::{impl_transitive_lock_order, relation::LockAfter};
/// # enum A {}
/// # enum B {}
/// # impl LockAfter<A> for B {}
/// impl_transitive_lock_order!(A => B);
/// ```
/// expands to this:
/// ```
/// # use lock_ordering::relation::LockAfter;
/// # enum A {}
/// # enum B {}
/// # impl LockAfter<A> for B {}
/// impl<L> LockAfter<L> for B
/// where
/// A: LockAfter<L>,
/// B: LockAfter<A>,
/// {
/// }
/// ```
pub use impl_transitive_lock_order;