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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//! [`implied_bounds`]: `implied_bounds`
//! [`ImpliedPredicate`]: `ImpliedPredicate`
pub use ImpliedPredicate;
/// Convenience attribute macro to help one rewrite a `trait` definition as per the rules described
/// in the documentation of [`ImpliedPredicate`].
///
/// Indeed, that trait is very handy, but its usage is not only not the most obvious to write, but
/// more importantly, not very readable afterwards.
///
/// Since it is actually a very mechanical operation, it is a good fit for macro automation 🙂
///
/// ## Example
///
/// The following fails to compile:
///
/// ```rust ,compile_fail
/// trait Trait<U: Clone>
/// where
/// Self::Gat<true>: Send,
/// {
/// type Gat<const IS_SEND: bool>;
/// }
///
/// fn demo<T: Trait<U>, U>()
/// where
/// // ❌ Error, missing:
/// // U: Clone,
/// // T::Gat<true>: Send,
/// {}
/// ```
///
/// - Error message:
///
/// <details class="custom"><summary><span class="summary-box"><span>Click to show</span></span></summary>
///
/// ```rust ,ignore
/// # /*
/// error[E0277]: the trait bound `U: Clone` is not satisfied
/// --> src/_lib.rs:29:12
/// |
/// 10 | fn demo<T: Trait<U>, U>()
/// | ^^^^^^^^ the trait `Clone` is not implemented for `U`
/// |
/// note: required by a bound in `Trait`
/// --> src/_lib.rs:22:16
/// |
/// 3 | trait Trait<U: Clone>
/// | ^^^^^ required by this bound in `Trait`
/// help: consider restricting type parameter `U`
/// |
/// 10 | fn demo<T: Trait<U>, U: std::clone::Clone>()
/// | +++++++++++++++++++
///
/// error[E0277]: `<T as Trait<U>>::Gat<true>` cannot be sent between threads safely
/// --> src/_lib.rs:29:12
/// |
/// 10 | fn demo<T: Trait<U>, U>()
/// | ^^^^^^^^ `<T as Trait<U>>::Gat<true>` cannot be sent between threads safely
/// |
/// = help: the trait `Send` is not implemented for `<T as Trait<U>>::Gat<true>`
/// note: required by a bound in `Trait`
/// --> src/_lib.rs:24:22
/// |
/// 3 | trait Trait<U: Clone>
/// | ----- required by a bound in this trait
/// 4 | where
/// 5 | Self::Gat<true>: Send,
/// | ^^^^ required by this bound in `Trait`
/// help: consider further restricting the associated type
/// |
/// 11 | where <T as Trait<U>>::Gat<true>: Send
/// | ++++++++++++++++++++++++++++++++
/// # */
/// ```
///
/// </details>
///
/// You can easily fix this by slapping the <code>[#\[implied_bounds\]][`implied_bounds`]</code>
/// attribute on it:
///
/// ```rust
/// #[::implied_bounds::implied_bounds] // 👈
/// trait Trait<U: Clone>
/// where
/// Self::Gat<true>: Send,
/// {
/// type Gat<const IS_SEND: bool>;
/// }
///
/// fn demo<T: Trait<U>, U>()
/// where
/// // OK ✅
/// {}
/// ```
///
/// This shall not change anything for implementors (they have to abide by the provided
/// bounds/clauses/predicates no matter whether the
/// <code>[#\[implied_bounds\]][`implied_bounds`]</code> attribute is used or not, and it shall
/// suffice).
///
/// ## How does the macro work
///
/// - Tip: you can provide the `debug` arg to the attribute for it to highlight the non-implied
/// clauses it shall rewrite:
///
/// ```rust
/// # /*
/// // 👇
/// #[implied_bounds(debug)]
/// trait ...
/// # */
/// ```
///
/// The attribute identifies the non-implied clauses (bounds on generic type parameters, as well
/// as `where` clauses where the left-hand-side (bounded type) is not `Self`), and rewrites them
/// using [`ImpliedPredicate`], like this:
///
/// ```rust
/// use ::implied_bounds::*;
///
/// #[implied_bounds] // 👈
/// trait Trait<U: Clone>
/// where
/// Self::Gat<true>: Send,
/// {
/// type Gat<const IS_SEND: bool>;
/// }
/// ```
///
/// becomes:
///
/// ```rust
/// use ::implied_bounds::*;
///
/// trait Trait<U>
/// :
/// ImpliedPredicate<U, Impls: Clone> +
/// ImpliedPredicate<Self::Gat<true>, Impls: Send> +
/// {
/// type Gat<const IS_SEND: bool>;
/// }
/// ```
///
/// where [`ImpliedPredicate`] is a trivially-true / always-holding trait clause, on condition
/// that it be well-formed, _i.e._, on condition that the bounds on its `Impls` associated type
/// do hold, wherein its `Impls` associated type is defined to always be the same as the generic arg fed
/// to it:
///
/// ```rust
/// # /*
/// X : Bounds…
/// ⇔
/// ImpliedPredicate<X, Impls: Bounds…>
/// # */
/// ```
pub use implied_bounds;
// macro internals
/** Not part of the public API */ pub