implied_bounds/helper_trait.rs
1pub
2trait HasAssoc<T : ?Sized> {
3 type Impls : ?Sized;
4}
5
6impl<T : ?Sized, Self_ : ?Sized> HasAssoc<T> for Self_ {
7 type Impls = T;
8}
9
10/// Helper trait for the implied/entailed bounds trick.
11///
12/// # Usage:
13///
14/// When you have:
15///
16/// ```rust
17/// // this clause is not entailed
18/// // vvvvvvvv
19/// trait SomeTrait<T : Clone>
20/// where
21/// // And neither is this one.
22/// Self::SomeGat<true> : Send,
23/// {
24/// type SomeGat<const IS_SEND: bool>;
25/// // …
26/// }
27/// ```
28///
29/// instead, write:
30///
31/// ```rust
32/// use ::implied_bounds::ImpliedPredicate;
33///
34/// trait SomeTrait<T>
35/// :
36/// ImpliedPredicate<T, Impls : Clone> +
37/// ImpliedPredicate<Self::SomeGat<true>, Impls : Send> +
38/// {
39/// type SomeGat<const IS_SEND: bool>;
40/// // …
41/// }
42/// ```
43///
44/// # Convenience macro
45///
46/// Since this usage is not only not the most obvious to write, but more importantly, not very
47/// readable afterwards, this crate exposes a helper convenience macro which shall do this
48/// mechanical transformation in your stead; in an automated, reliable, and predictable manner.
49///
50/// ```rust
51/// use ::implied_bounds::implied_bounds;
52///
53/// #[implied_bounds] // 👈
54/// trait SomeTrait<T : Clone>
55/// where
56/// Self::SomeGat<true> : Send,
57/// {
58/// type SomeGat<const IS_SEND: bool>;
59/// // …
60/// }
61/// ```
62///
63/// And _voilà _ 😙👌
64pub
65trait ImpliedPredicate<T : ?Sized>
66:
67 HasAssoc<T, Impls = T> +
68{}
69
70impl<T : ?Sized, Self_ : ?Sized> ImpliedPredicate<T> for Self_ {}