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
65
66
67
68
69
70
pub
/// Helper trait for the implied/entailed bounds trick.
///
/// # Usage:
///
/// When you have:
///
/// ```rust
/// // this clause is not entailed
/// // vvvvvvvv
/// trait SomeTrait<T : Clone>
/// where
/// // And neither is this one.
/// Self::SomeGat<true> : Send,
/// {
/// type SomeGat<const IS_SEND: bool>;
/// // …
/// }
/// ```
///
/// instead, write:
///
/// ```rust
/// use ::implied_bounds::ImpliedPredicate;
///
/// trait SomeTrait<T>
/// :
/// ImpliedPredicate<T, Impls : Clone> +
/// ImpliedPredicate<Self::SomeGat<true>, Impls : Send> +
/// {
/// type SomeGat<const IS_SEND: bool>;
/// // …
/// }
/// ```
///
/// # Convenience macro
///
/// Since this usage is not only not the most obvious to write, but more importantly, not very
/// readable afterwards, this crate exposes a helper convenience macro which shall do this
/// mechanical transformation in your stead; in an automated, reliable, and predictable manner.
///
/// ```rust
/// use ::implied_bounds::implied_bounds;
///
/// #[implied_bounds] // 👈
/// trait SomeTrait<T : Clone>
/// where
/// Self::SomeGat<true> : Send,
/// {
/// type SomeGat<const IS_SEND: bool>;
/// // …
/// }
/// ```
///
/// And _voilà _ 😙👌
pub