konst_kernel/type_eq/
make_project_fn.rs

1#[macro_export]
2macro_rules! type_eq_projection_fn {
3    (
4        $(#[$attr:meta])*
5        $vis:vis
6        $(const $(@$is_const:ident@)?)?
7        fn $function:ident
8        (
9            $($type_param:ident)?
10            $(, $param:ident $(@$L_R_from_ctx:ident@)?: TypeEq<$L:ident, $R:ident>)?
11        )
12        ->
13        $(:: $(@$c2:ident@)?)? $($type_name:ident)::* <
14        $($gen_params:tt)*
15    ) => {
16        $crate::__mpf_assert_type_param_is_T!{ $($type_param)? }
17
18        $crate::__::__make_projection_parse_generics!{
19            (
20                ( $(($(@$L_R_from_ctx@)?))? (__L, __R,) )
21                ( $(($param, $L, $R))? (_, __L, __R) )
22                (
23                    $(#[$attr])*
24                    #[inline(always)]
25                    $vis $(const $($is_const)?)? fn $function
26                )
27                ( $(:: $($c2)?)? $($type_name)::* )
28            )
29
30            () // generic parameter
31            () // generic arguments
32
33            ($($gen_params)*)
34        }
35    };
36}
37
38macro_rules! __meta__make_projection_parse_generics {
39    (
40        $_:tt
41
42        repeat_punct( $(($punct:tt ($($prep:tt)*)))* )
43    ) => {
44        #[doc(hidden)]
45        #[macro_export]
46        macro_rules! __make_projection_parse_generics {
47            (
48                $fixed:tt
49                $gen_params:tt
50                $gen_args:tt
51                ( >  $_($rem:tt)*)
52            ) => {
53                $crate::__make_projection_fn!{
54                    $fixed
55                    $gen_params
56                    $gen_args
57                    ($_($rem)*)
58                }
59            };
60            $((
61                $fixed:tt
62
63                ($_($prev_gen_params:tt)*)
64                ($_($prev_gen_args:tt)*)
65
66                (
67                    $lt_param:lifetime $_(: $_( $lt_bound:lifetime $_(+)? )* )?
68                    $punct $_($rem:tt)*
69                )
70            ) => {
71                $crate::__::__make_projection_parse_generics!{
72                    $fixed
73
74                    (
75                        $_($prev_gen_params)*
76                        $lt_param $_(: $_( $lt_bound + )* )? ,
77                    )
78                    ($_($prev_gen_args)* $lt_param,)
79
80                    ( $($prep)*  $_($rem)* )
81                }
82            };)*
83            $((
84                $fixed:tt
85
86                ($_($prev_gen_params:tt)*)
87                ($_($prev_gen_args:tt)*)
88
89                (
90                    const $const_param:ident: $const_ty:ty
91                    $punct $_($rem:tt)*
92                )
93            ) => {
94                $crate::__::__make_projection_parse_generics!{
95                    $fixed
96
97                    ($_($prev_gen_params)* const $const_param: $const_ty,)
98                    ($_($prev_gen_args)* $const_param,)
99
100                    ( $($prep)*  $_($rem)* )
101                }
102            };)*
103            $((
104                (
105                    (($_($declared_replacement_ty_params:tt)*) $_($ignored0:tt)*)
106                    $rep_ty_param:tt
107                    $prefix:tt
108                    $type_name:tt
109                )
110
111                ($_($prev_gen_params:tt)*)
112                ($_($prev_gen_args:tt)*)
113
114                (
115                    T $_(:
116                        $_( $lt_bound:lifetime $_(+)? )*
117                        $_( ( $_($ty_bounds:tt)* ) )?
118                    )?
119                    $punct $_($rem:tt)*
120                )
121            )=>{
122                $_($_($crate::__mpf_assert_bound!{ $_($ty_bounds)* })?)?
123
124                $crate::__::__make_projection_parse_generics!{
125                    (
126                        (($_($declared_replacement_ty_params)*) $_($ignored0)*)
127                        $rep_ty_param
128                        $prefix
129                        $type_name
130                    )
131
132                    (
133                        $_($prev_gen_params)*
134                        $_($declared_replacement_ty_params)*
135                    )
136
137                    (
138                        @replaced( $_( $_( $lt_bound + )* $_($_( $ty_bounds )*)? )? );
139                        $_($prev_gen_args)* ;
140                    )
141
142                    ( $($prep)*  $_($rem)* )
143                }
144            };)*
145            $((
146                $fixed:tt
147
148                ($_($prev_gen_params:tt)*)
149                ($_($prev_gen_args:tt)*)
150
151                (
152                    $ty_param:ident $_(:
153                        $_( $lt_bound:lifetime $_(+)? )*
154                        $_( ( $_($ty_bounds:tt)* ) )?
155                    )?
156                    $punct $_($rem:tt)*
157                )
158            )=>{
159                $_($_($crate::__mpf_assert_bound!{ $_($ty_bounds)* })?)?
160
161                $crate::__::__make_projection_parse_generics!{
162                    $fixed
163
164                    (
165                        $_($prev_gen_params)*
166                        $ty_param $_(: $_( $lt_bound + )* $_($_( $ty_bounds )*)? )?,
167                    )
168                    ($_($prev_gen_args)* $ty_param,)
169
170                    ( $($prep)*  $_($rem)* )
171                }
172            };)*
173            (
174                $fixed:tt  $prev_gen_params:tt $prev_gen_args:tt
175
176                (
177                    $ty_param:ident:
178                        $_( $lt_bound:lifetime $_(+)? )*
179                        $_(::)? $ident:ident
180                    $_($rem:tt)*
181                )
182            )=>{
183                $crate::__::compile_error!{$crate::__::concat!(
184                    "trait bounds in parameter list must be wrapped in parentheses, context: `",
185                    stringify!($ty_param: $_( $lt_bound + )*  $ident),
186                    "`",
187                )}
188            };
189        }
190
191        #[doc(hidden)]
192        pub use __make_projection_parse_generics;
193    };
194}
195
196__meta__make_projection_parse_generics! {
197    $
198    repeat_punct(
199        (, ())
200        (> (>))
201    )
202}
203
204#[doc(hidden)]
205#[macro_export]
206macro_rules! __make_projection_fn {
207    (
208        (
209            $ignored0:tt
210            (($param:tt, $L:ident, $R:ident) $($ignored1:tt)*)
211            ($($prefix:tt)*)
212            ($($type_name:tt)*)
213        )
214
215        ($($gen_params:tt)*)
216
217        (
218            $(@replaced($($rep_ty_bound:tt)*);)*
219            $($lt_arg:lifetime,)*
220            $($gen_arg_before:ident,)*
221            $(;$($gen_arg_after:ident,)*)?
222        )
223
224        (
225            $(where $($where_preds:tt)* )?
226        )
227    ) => {
228        $crate::__assert_replaced_type_param_and_where_clause!{
229            ($(@replaced($($rep_ty_bound)*);)*)
230            ($( $($where_preds)* )?)
231
232            $($prefix)*
233            <$($gen_params)*> (
234                param: $crate::__::TypeEq<$L, $R>
235            ) -> $crate::__::TypeEq<
236                $($type_name)* <$($lt_arg,)* $($gen_arg_before,)* $L, $($($gen_arg_after,)*)?>,
237                $($type_name)* <$($lt_arg,)* $($gen_arg_before,)* $R, $($($gen_arg_after,)*)?>,
238            >
239            where
240                $L: $($($rep_ty_bound)*)?,
241                $R: $($($rep_ty_bound)*)?,
242                $($($where_preds)*)?
243            {
244                struct __Projector<T: ?Sized>($crate::__::PhantomData<T>);
245
246                impl<$($gen_params)*> $crate::__::TypeFn<$L>
247                for __Projector<
248                    $($type_name)* <
249                        $($lt_arg,)*
250                        $($gen_arg_before,)*
251                        $R,
252                        $($($gen_arg_after,)*)?
253                    >,
254                >
255                where
256                    $L: $($($rep_ty_bound)*)?,
257                    $R: $($($rep_ty_bound)*)?,
258                    $($($where_preds)*)?
259                {
260                    type Output = $($type_name)* <
261                        $($lt_arg,)*
262                        $($gen_arg_before,)*
263                        $L,
264                        $($($gen_arg_after,)*)?
265                    >;
266                }
267
268                param.project::<
269                    __Projector<
270                        $($type_name)* <
271                            $($lt_arg,)*
272                            $($gen_arg_before,)*
273                            $R,
274                            $($($gen_arg_after,)*)?
275                        >
276                    >
277                >()
278            }
279
280        }
281    };
282    ($($tt:tt)*) => {
283        $crate::__::compile_error!{
284            $crate::__::stringify!{$($tt)*}
285        }
286    };
287}
288
289#[doc(hidden)]
290#[macro_export]
291macro_rules! __assert_replaced_type_param_and_where_clause {
292    (() $where:tt $($token:tt)*) => {
293        $crate::__::compile_error!{
294            "expected a `T` type parameter in the return type"
295        }
296    };
297    (
298        (@replaced($($rep_ty_bound:tt)*);)
299        (
300            $($wc_lt:lifetime: $( $wc_lt_bound:lifetime $(+)? )*),*
301            $(,)?
302            $($wc_ty:ty : $($wc_ty_lt:lifetime $(+)?)* $($wc_ty_bound:path)?),*
303            $(,)?
304        )
305        $($token:tt)*
306    ) => {
307        $($token)*
308    };
309    (
310        $replaced:tt
311        $where:tt
312        $($token:tt)*
313    ) => {
314        $crate::__::compile_error!{"invalid where clause syntax"}
315    }
316}
317
318#[doc(hidden)]
319#[macro_export]
320macro_rules! __mpf_assert_bound {
321    ($bound:ty) => {};
322}
323
324#[doc(hidden)]
325#[macro_export]
326macro_rules! __mpf_assert_type_param_is_T {
327    (T) => {};
328    ($($tt:tt)*) => {
329        $crate::__::compile_error!{$crate::__::concat!(
330            "expected function parameter to be `T`, found: `",
331            $crate::__::stringify!($($tt)*),
332            "`",
333        )}
334    };
335}