1#![no_std]
2#![deny(warnings)]
3#![doc(test(attr(deny(warnings))))]
4#![doc(test(attr(allow(dead_code))))]
5#![doc(test(attr(allow(unused_variables))))]
6
7#[doc(hidden)]
8pub use core::compile_error as std_compile_error;
9#[doc(hidden)]
10pub use core::concat as std_concat;
11#[doc(hidden)]
12pub use core::stringify as std_stringify;
13
14#[macro_export]
86macro_rules! parse {
87 (
88 $callback:path { $($callback_args:tt)* } < $($token:tt)*
89 ) => {
90 $crate::parse_generics_impl! { [$crate::parse_callback] [$callback [$($callback_args)*]] [] [] [$($token)*] }
91 };
92 (
93 $callback:path { $($callback_args:tt)* } $($token:tt)*
94 ) => {
95 $crate::allow_where_clause_impl! { [$crate::parse_callback] [$callback [$($callback_args)*]] [] [$($token)*] }
96 };
97}
98
99#[doc(hidden)]
101#[macro_export]
102macro_rules! parse_callback {
103 (
104 $callback:path
105 [$($callback_args:tt)*]
106 [
107 [$([$([$($g:tt)*])*])?]
108 [$([$([$($r:tt)*])*])?]
109 [$($w:tt)*]
110 $($extra:tt)*
111 ]
112 $($rest:tt)*
113 ) => {
114 $callback ! {
115 $($callback_args)*
116 [ $(< $($($g)*),+ >)? ]
117 [ $(< $($($r)*),+ >)? ]
118 [$($w)*]
119 $($rest)*
120 }
121 };
122}
123
124#[macro_export]
203macro_rules! parse_raw {
204 (
205 $callback:path { $($callback_args:tt)* } < $($token:tt)*
206 ) => {
207 $crate::parse_generics_impl! { [$callback] [$($callback_args)*] [] [] [$($token)*] }
208 };
209 (
210 $callback:path { $($callback_args:tt)* } $($token:tt)*
211 ) => {
212 $crate::allow_where_clause_impl! { [$callback] [$($callback_args)*] [] [$($token)*] }
213 };
214}
215
216#[doc(hidden)]
217#[macro_export]
218macro_rules! parse_generics_impl {
219 (
220 [$callback:path]
221 [$($callback_args:tt)*]
222 [$($g:tt)*]
223 [$($r:tt)*]
224 [const $param:ident $($token:tt)*]
225 ) => {
226 $crate::parse_generics_impl! {
227 @param
228 [[const $param] [$param]]
229 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
230 [$($token)*]
231 }
232 };
233 (
234 [$callback:path]
235 [$($callback_args:tt)*]
236 [$($g:tt)*]
237 [$($r:tt)*]
238 [$param:ident $($token:tt)*]
239 ) => {
240 $crate::parse_generics_impl! {
241 @param
242 [[$param] [$param]]
243 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
244 [$($token)*]
245 }
246 };
247 (
248 [$callback:path]
249 [$($callback_args:tt)*]
250 [$($g:tt)*]
251 [$($r:tt)*]
252 [$param:lifetime $($token:tt)*]
253 ) => {
254 $crate::parse_generics_impl! {
255 @param
256 [[$param] [$param]]
257 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
258 [$($token)*]
259 }
260 };
261 (
262 [$callback:path]
263 [$($callback_args:tt)*]
264 [$($g:tt)*]
265 [$($r:tt)*]
266 [> $($token:tt)*]
267 ) => {
268 $crate::parse_generics_impl! {
269 @done
270 [$callback] [$($callback_args)*]
271 [$($g)*]
272 [$($r)*]
273 []
274 [$($token)*]
275 }
276 };
277 (
278 [$callback:path]
279 [$($callback_args:tt)*]
280 [$($g:tt)*]
281 [$($r:tt)*]
282 [$x:tt $($token:tt)*]
283 ) => {
284 $crate::std_compile_error!($crate::std_concat!(
285 "unexpected token '",
286 $crate::std_stringify!($x),
287 "', expected ident, or lifetime"
288 ));
289 };
290 (
291 [$callback:path]
292 [$($callback_args:tt)*]
293 [$($([$($g:tt)*])+)?]
294 [$($r:tt)*]
295 []
296 ) => {
297 $crate::std_compile_error!($crate::std_concat!(
298 "missing '>' after '",
299 $crate::std_stringify!( < $($($($g)*),+ ,)? ),
300 "'"
301 ));
302 };
303 (
304 @param
305 [[$($gparam:tt)*] [$($rparam:tt)*]]
306 [$callback:path]
307 [$($callback_args:tt)*]
308 [$($g:tt)*]
309 [$($r:tt)*]
310 [ : $($token:tt)*]
311 ) => {
312 $crate::parse_generics_impl! {
313 @constrained_param [:]
314 [[$($gparam)*] [$($rparam)*]]
315 [] []
316 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
317 [$($token)*]
318 }
319 };
320 (
321 @param
322 [[$($gparam:tt)*] [$($rparam:tt)*]]
323 [$callback:path]
324 [$($callback_args:tt)*]
325 [$($g:tt)*]
326 [$($r:tt)*]
327 [ = $($token:tt)*]
328 ) => {
329 $crate::parse_generics_impl! {
330 @constrained_param [=]
331 [[$($gparam)*] [$($rparam)*]]
332 [] []
333 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
334 [$($token)*]
335 }
336 };
337 (
338 @param
339 [[$($gparam:tt)*] [$($rparam:tt)*]]
340 [$callback:path]
341 [$($callback_args:tt)*]
342 [$($g:tt)*]
343 [$($r:tt)*]
344 [ > $($token:tt)*]
345 ) => {
346 $crate::parse_generics_impl! {
347 @done
348 [$callback] [$($callback_args)*]
349 [$($g)* [$($gparam)*]]
350 [$($r)* [$($rparam)*]]
351 []
352 [$($token)*]
353 }
354 };
355 (
356 @param
357 [[$($gparam:tt)*] [$($rparam:tt)*]]
358 [$callback:path]
359 [$($callback_args:tt)*]
360 [$($g:tt)*]
361 [$($r:tt)*]
362 [ >> $($token:tt)*]
363 ) => {
364 $crate::parse_generics_impl! {
365 @done
366 [$callback] [$($callback_args)*]
367 [$($g)* [$($gparam)*]]
368 [$($r)* [$($rparam)*]]
369 []
370 [ > $($token)*]
371 }
372 };
373 (
374 @param
375 [[$($gparam:tt)*] [$($rparam:tt)*]]
376 [$callback:path]
377 [$($callback_args:tt)*]
378 [$($g:tt)*]
379 [$($r:tt)*]
380 [ , > $($token:tt)*]
381 ) => {
382 $crate::parse_generics_impl! {
383 @done
384 [$callback] [$($callback_args)*]
385 [$($g)* [$($gparam)*]]
386 [$($r)* [$($rparam)*]]
387 []
388 [$($token)*]
389 }
390 };
391 (
392 @param
393 [[$($gparam:tt)*] [$($rparam:tt)*]]
394 [$callback:path]
395 [$($callback_args:tt)*]
396 [$($g:tt)*]
397 [$($r:tt)*]
398 [ , >> $($token:tt)*]
399 ) => {
400 $crate::parse_generics_impl! {
401 @done
402 [$callback] [$($callback_args)*]
403 [$($g)* [$($gparam)*]]
404 [$($r)* [$($rparam)*]]
405 []
406 [ > $($token)*]
407 }
408 };
409 (
410 @param
411 [[$($gparam:tt)*] [$($rparam:tt)*]]
412 [$callback:path]
413 [$($callback_args:tt)*]
414 [$($g:tt)*]
415 [$($r:tt)*]
416 [ , $($token:tt)*]
417 ) => {
418 $crate::parse_generics_impl! {
419 [$callback] [$($callback_args)*]
420 [$($g)* [$($gparam)*]]
421 [$($r)* [$($rparam)*]]
422 [$($token)*]
423 }
424 };
425 (
426 @param
427 [[$($gparam:tt)*] [$($rparam:tt)*]]
428 [$callback:path]
429 [$($callback_args:tt)*]
430 [$($g:tt)*]
431 [$($r:tt)*]
432 [$x:tt $($token:tt)*]
433 ) => {
434 $crate::std_compile_error!($crate::std_concat!(
435 "unexpected token '",
436 $crate::std_stringify!($x),
437 "', expected ':', '=', ',', or '>'"
438 ));
439 };
440 (
441 @param
442 [[$([$($gparam:tt)*])*] [$($rparam:tt)*]]
443 [$callback:path]
444 [$($callback_args:tt)*]
445 [$($([$($g:tt)*])+)?]
446 [$($r:tt)*]
447 []
448 ) => {
449 $crate::std_compile_error!($crate::std_concat!(
450 "missing '>' after '",
451 $crate::std_stringify!( < $($($($g)*),+ ,)? $([$($gparam)*])* ),
452 "'"
453 ));
454 };
455 (
456 @constrained_param [$kind:tt]
457 [[$($gparam:tt)*] [$($rparam:tt)*]]
458 [$($constraint:tt)*] [$($value:tt)*]
459 [$callback:path]
460 [$($callback_args:tt)*]
461 [$($g:tt)*]
462 [$($r:tt)*]
463 [ < $($token:tt)*]
464 ) => {
465 $crate::parse_generics_impl! {
466 @angles_in_constraint [$kind]
467 [[$($gparam)*] [$($rparam)*]]
468 [$($constraint)*] [$($value)*]
469 [] []
470 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
471 [$($token)*]
472 }
473 };
474 (
475 @constrained_param [$kind:tt]
476 [[$($gparam:tt)*] [$($rparam:tt)*]]
477 [$($constraint:tt)*] [$($value:tt)*]
478 [$callback:path]
479 [$($callback_args:tt)*]
480 [$($g:tt)*]
481 [$($r:tt)*]
482 [ << $($token:tt)*]
483 ) => {
484 $crate::parse_generics_impl! {
485 @angles_in_constraint [$kind]
486 [[$($gparam)*] [$($rparam)*]]
487 [$($constraint)*] [$($value)*]
488 [] []
489 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
490 [ < $($token)*]
491 }
492 };
493 (
494 @constrained_param [$kind:tt]
495 [[$($gparam:tt)*] [$($rparam:tt)*]]
496 [$($constraint:tt)*] [$($value:tt)*]
497 [$callback:path]
498 [$($callback_args:tt)*]
499 [$($g:tt)*]
500 [$($r:tt)*]
501 [ > $($token:tt)*]
502 ) => {
503 $crate::parse_generics_impl! {
504 @done
505 [$callback] [$($callback_args)*]
506 [$($g)* [$($gparam)* : $($constraint)*]]
507 [$($r)* [$($rparam)*]]
508 []
509 [$($token)*]
510 }
511 };
512 (
513 @constrained_param [$kind:tt]
514 [[$($gparam:tt)*] [$($rparam:tt)*]]
515 [$($constraint:tt)*] [$($value:tt)*]
516 [$callback:path]
517 [$($callback_args:tt)*]
518 [$($g:tt)*]
519 [$($r:tt)*]
520 [ >> $($token:tt)*]
521 ) => {
522 $crate::parse_generics_impl! {
523 @done
524 [$callback] [$($callback_args)*]
525 [$($g)* [$($gparam)* : $($constraint)*]]
526 [$($r)* [$($rparam)*]]
527 []
528 [ > $($token)*]
529 }
530 };
531 (
532 @constrained_param [$kind:tt]
533 [[$($gparam:tt)*] [$($rparam:tt)*]]
534 [$($constraint:tt)*] [$($value:tt)*]
535 [$callback:path]
536 [$($callback_args:tt)*]
537 [$($g:tt)*]
538 [$($r:tt)*]
539 [ , > $($token:tt)*]
540 ) => {
541 $crate::parse_generics_impl! {
542 @done
543 [$callback] [$($callback_args)*]
544 [$($g)* [$($gparam)* : $($constraint)*]]
545 [$($r)* [$($rparam)*]]
546 []
547 [$($token)*]
548 }
549 };
550 (
551 @constrained_param [$kind:tt]
552 [[$($gparam:tt)*] [$($rparam:tt)*]]
553 [$($constraint:tt)*] [$($value:tt)*]
554 [$callback:path]
555 [$($callback_args:tt)*]
556 [$($g:tt)*]
557 [$($r:tt)*]
558 [ , >> $($token:tt)*]
559 ) => {
560 $crate::parse_generics_impl! {
561 @done
562 [$callback] [$($callback_args)*]
563 [$($g)* [$($gparam)* : $($constraint)*]]
564 [$($r)* [$($rparam)*]]
565 []
566 [ > $($token)*]
567 }
568 };
569 (
570 @constrained_param [$kind:tt]
571 [[$($gparam:tt)*] [$($rparam:tt)*]]
572 [$($constraint:tt)*] [$($value:tt)*]
573 [$callback:path]
574 [$($callback_args:tt)*]
575 [$($g:tt)*]
576 [$($r:tt)*]
577 [ , $($token:tt)*]
578 ) => {
579 $crate::parse_generics_impl! {
580 [$callback] [$($callback_args)*]
581 [$($g)* [$($gparam)* : $($constraint)*]]
582 [$($r)* [$($rparam)*]]
583 [$($token)*]
584 }
585 };
586 (
587 @constrained_param [:]
588 [[$($gparam:tt)*] [$($rparam:tt)*]]
589 [$($constraint:tt)*] [$($value:tt)*]
590 [$callback:path]
591 [$($callback_args:tt)*]
592 [$($g:tt)*]
593 [$($r:tt)*]
594 [ = $($token:tt)*]
595 ) => {
596 $crate::parse_generics_impl! {
597 @constrained_param [=]
598 [[$($gparam)*] [$($rparam)*]]
599 [$($constraint)*] [$($value)*]
600 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
601 [$($token)*]
602 }
603 };
604 (
605 @constrained_param [:]
606 [[$($gparam:tt)*] [$($rparam:tt)*]]
607 [$($constraint:tt)*] [$($value:tt)*]
608 [$callback:path]
609 [$($callback_args:tt)*]
610 [$($g:tt)*]
611 [$($r:tt)*]
612 [ $x:tt $($token:tt)*]
613 ) => {
614 $crate::parse_generics_impl! {
615 @constrained_param [:]
616 [[$($gparam)*] [$($rparam)*]]
617 [$($constraint)* $x] [$($value)*]
618 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
619 [$($token)*]
620 }
621 };
622 (
623 @constrained_param [=]
624 [[$($gparam:tt)*] [$($rparam:tt)*]]
625 [$($constraint:tt)*] [$($value:tt)*]
626 [$callback:path]
627 [$($callback_args:tt)*]
628 [$($g:tt)*]
629 [$($r:tt)*]
630 [ $x:tt $($token:tt)*]
631 ) => {
632 $crate::parse_generics_impl! {
633 @constrained_param [=]
634 [[$($gparam)*] [$($rparam)*]]
635 [$($constraint)*] [$($value)* $x]
636 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
637 [$($token)*]
638 }
639 };
640 (
641 @constrained_param [$kind:tt]
642 [[$($gparam:tt)*] [$($rparam:tt)*]]
643 [$($($constraint:tt)+)?] [$($($value:tt)+)?]
644 [$callback:path]
645 [$($callback_args:tt)*]
646 [$($g:tt)*]
647 [$($r:tt)*]
648 []
649 ) => {
650 $crate::std_compile_error!($crate::std_concat!(
651 "missing '>' after '",
652 $crate::std_stringify!( < $($($($g)*),+ ,)? $($gparam)* $( : $($constraint)+)? $( = $($value)+)? ),
653 "'"
654 ));
655 };
656 (
657 @angles_in_constraint [:]
658 [[$($gparam:tt)*] [$($rparam:tt)*]]
659 [$($constraint:tt)*] [$($value:tt)*]
660 [$($inside_angles:tt)*]
661 []
662 [$callback:path]
663 [$($callback_args:tt)*]
664 [$($g:tt)*]
665 [$($r:tt)*]
666 [ > $($token:tt)*]
667 ) => {
668 $crate::parse_generics_impl! {
669 @constrained_param [:]
670 [[$($gparam)*] [$($rparam)*]]
671 [$($constraint)* < $($inside_angles)* > ] [$($value)*]
672 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
673 [$($token)*]
674 }
675 };
676 (
677 @angles_in_constraint [=]
678 [[$($gparam:tt)*] [$($rparam:tt)*]]
679 [$($constraint:tt)*] [$($value:tt)*]
680 [$($inside_angles:tt)*]
681 []
682 [$callback:path]
683 [$($callback_args:tt)*]
684 [$($g:tt)*]
685 [$($r:tt)*]
686 [ > $($token:tt)*]
687 ) => {
688 $crate::parse_generics_impl! {
689 @constrained_param [=]
690 [[$($gparam)*] [$($rparam)*]]
691 [$($constraint)*] [$($value)* < $($inside_angles)* > ]
692 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
693 [$($token)*]
694 }
695 };
696 (
697 @angles_in_constraint [:]
698 [[$($gparam:tt)*] [$($rparam:tt)*]]
699 [$($constraint:tt)*] [$($value:tt)*]
700 [$($inside_angles:tt)*]
701 []
702 [$callback:path]
703 [$($callback_args:tt)*]
704 [$($g:tt)*]
705 [$($r:tt)*]
706 [ >> $($token:tt)*]
707 ) => {
708 $crate::parse_generics_impl! {
709 @constrained_param [:]
710 [[$($gparam)*] [$($rparam)*]]
711 [$($constraint)* < $($inside_angles)* > ] [$($value)*]
712 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
713 [ > $($token)*]
714 }
715 };
716 (
717 @angles_in_constraint [=]
718 [[$($gparam:tt)*] [$($rparam:tt)*]]
719 [$($constraint:tt)*] [$($value:tt)*]
720 [$($inside_angles:tt)*]
721 []
722 [$callback:path]
723 [$($callback_args:tt)*]
724 [$($g:tt)*]
725 [$($r:tt)*]
726 [ >> $($token:tt)*]
727 ) => {
728 $crate::parse_generics_impl! {
729 @constrained_param [=]
730 [[$($gparam)*] [$($rparam)*]]
731 [$($constraint)*] [$($value)* < $($inside_angles)* > ]
732 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
733 [ > $($token)*]
734 }
735 };
736 (
737 @angles_in_constraint [$kind:tt]
738 [[$($gparam:tt)*] [$($rparam:tt)*]]
739 [$($constraint:tt)*] [$($value:tt)*]
740 [$($inside_angles:tt)*]
741 [[$($parent_level:tt)*] $([$($outer_levels:tt)*])*]
742 [$callback:path]
743 [$($callback_args:tt)*]
744 [$($g:tt)*]
745 [$($r:tt)*]
746 [ > $($token:tt)*]
747 ) => {
748 $crate::parse_generics_impl! {
749 @angles_in_constraint [$kind]
750 [[$($gparam)*] [$($rparam)*]]
751 [$($constraint)*] [$($value)*]
752 [$($parent_level)* < $($inside_angles)* > ]
753 [$([$($outer_levels)*])*]
754 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
755 [$($token)*]
756 }
757 };
758 (
759 @angles_in_constraint [$kind:tt]
760 [[$($gparam:tt)*] [$($rparam:tt)*]]
761 [$($constraint:tt)*] [$($value:tt)*]
762 [$($inside_angles:tt)*]
763 [[$($parent_level:tt)*] $([$($outer_levels:tt)*])*]
764 [$callback:path]
765 [$($callback_args:tt)*]
766 [$($g:tt)*]
767 [$($r:tt)*]
768 [ >> $($token:tt)*]
769 ) => {
770 $crate::parse_generics_impl! {
771 @angles_in_constraint [$kind]
772 [[$($gparam)*] [$($rparam)*]]
773 [$($constraint)*] [$($value)*]
774 [$($parent_level)* < $($inside_angles)* > ]
775 [$([$($outer_levels)*])*]
776 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
777 [ > $($token)*]
778 }
779 };
780 (
781 @angles_in_constraint [$kind:tt]
782 [[$($gparam:tt)*] [$($rparam:tt)*]]
783 [$($constraint:tt)*] [$($value:tt)*]
784 [$($inside_angles:tt)*]
785 [$([$($outer_levels:tt)*])*]
786 [$callback:path]
787 [$($callback_args:tt)*]
788 [$($g:tt)*]
789 [$($r:tt)*]
790 [ < $($token:tt)*]
791 ) => {
792 $crate::parse_generics_impl! {
793 @angles_in_constraint [$kind]
794 [[$($gparam)*] [$($rparam)*]]
795 [$($constraint)*] [$($value)*]
796 []
797 [[$($inside_angles:tt)*] $([$($outer_levels)*])*]
798 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
799 [$($token)*]
800 }
801 };
802 (
803 @angles_in_constraint [$kind:tt]
804 [[$($gparam:tt)*] [$($rparam:tt)*]]
805 [$($constraint:tt)*] [$($value:tt)*]
806 [$($inside_angles:tt)*]
807 [$([$($outer_levels:tt)*])*]
808 [$callback:path]
809 [$($callback_args:tt)*]
810 [$($g:tt)*]
811 [$($r:tt)*]
812 [ << $($token:tt)*]
813 ) => {
814 $crate::parse_generics_impl! {
815 @angles_in_constraint [$kind]
816 [[$($gparam)*] [$($rparam)*]]
817 [$($constraint)*] [$($value)*]
818 []
819 [[$($inside_angles:tt)*] $([$($outer_levels)*])*]
820 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
821 [ < $($token)*]
822 }
823 };
824 (
825 @angles_in_constraint [$kind:tt]
826 [[$($gparam:tt)*] [$($rparam:tt)*]]
827 [$($constraint:tt)*] [$($value:tt)*]
828 [$($inside_angles:tt)*]
829 [$([$($outer_levels:tt)*])*]
830 [$callback:path]
831 [$($callback_args:tt)*]
832 [$($g:tt)*]
833 [$($r:tt)*]
834 [$x:tt $($token:tt)*]
835 ) => {
836 $crate::parse_generics_impl! {
837 @angles_in_constraint [$kind]
838 [[$($gparam)*] [$($rparam)*]]
839 [$($constraint)*] [$($value)*]
840 [$($inside_angles)* $x]
841 [$([$($outer_levels)*])*]
842 [$callback] [$($callback_args)*] [$($g)*] [$($r)*]
843 [$($token)*]
844 }
845 };
846 (
847 @angles_in_constraint [:]
848 [[$($gparam:tt)*] [$($rparam:tt)*]]
849 [$($constraint:tt)*] [$($($value:tt)+)?]
850 [$($inside_angles:tt)*]
851 [$([$($outer_levels:tt)*])*]
852 [$callback:path]
853 [$($callback_args:tt)*]
854 [$($([$($g:tt)*])+)?]
855 [$($r:tt)*]
856 []
857 ) => {
858 $crate::std_compile_error!($crate::std_concat!(
859 "missing '>' after '",
860 $crate::std_stringify!(
861 < $($($($g)*),+ ,)? $($gparam)*
862 : $($constraint)* $( < $($outer_levels)* )* < $($inside_angles)*
863 $( = $($value)+)?
864 ),
865 "'"
866 ));
867 };
868 (
869 @angles_in_constraint [=]
870 [[$($gparam:tt)*] [$($rparam:tt)*]]
871 [$($($constraint:tt)+)?] [$($value:tt)*]
872 [$($inside_angles:tt)*]
873 [$([$($outer_levels:tt)*])*]
874 [$callback:path]
875 [$($callback_args:tt)*]
876 [$($([$($g:tt)*])+)?]
877 [$($r:tt)*]
878 []
879 ) => {
880 $crate::std_compile_error!($crate::std_concat!(
881 "missing '>' after '",
882 $crate::std_stringify!(
883 < $($($($g)*),+ ,)? $($gparam)*
884 $( : $($constraint)+)?
885 = $($value)* $( < $($outer_levels)* )* < $($inside_angles)*
886 ),
887 "'"
888 ));
889 };
890 (
891 @done
892 [$callback:path]
893 [$($callback_args:tt)*]
894 [$($g:tt)*]
895 [$($r:tt)*]
896 [$($inter:tt)*]
897 [ ; $($token:tt)*]
898 ) => {
899 $callback ! {
900 $($callback_args)*
901 [
902 [ [$($g)*] ]
903 [ [$($r)*] ]
904 []
905 $crate $crate
906 ]
907 $($inter)* ; $($token)*
908 }
909 };
910 (
911 @done
912 [$callback:path]
913 [$($callback_args:tt)*]
914 [$($g:tt)*]
915 [$($r:tt)*]
916 [$($inter:tt)*]
917 [ $( { $($body:tt)* } $($token:tt)* )? ]
918 ) => {
919 $callback ! {
920 $($callback_args)*
921 [
922 [ [$($g)*] ]
923 [ [$($r)*] ]
924 []
925 $crate $crate
926 ]
927 $($inter)* $( { $($body)* } $($token)* )?
928 }
929 };
930 (
931 @done
932 [$callback:path]
933 [$($callback_args:tt)*]
934 [$($g:tt)*]
935 [$($r:tt)*]
936 [$($inter:tt)*]
937 [where $($token:tt)*]
938 ) => {
939 $crate::parse_where_clause_impl! {
940 [$callback]
941 [$($callback_args)*]
942 [ [$($g)*] ]
943 [ [$($r)*] ]
944 [] [$($inter)*] [$($token)*]
945 }
946 };
947 (
948 @done
949 [$callback:path]
950 [$($callback_args:tt)*]
951 [$($g:tt)*]
952 [$($r:tt)*]
953 [$($inter:tt)*]
954 [$token:tt $($other_tokens:tt)*]
955 ) => {
956 $crate::parse_generics_impl! {
957 @done
958 [$callback] [$($callback_args)*]
959 [$($g)*]
960 [$($r)*]
961 [$($inter)* $token]
962 [$($other_tokens)*]
963 }
964 };
965}
966
967#[doc(hidden)]
968#[macro_export]
969macro_rules! parse_where_clause_impl {
970 (
971 [$callback:path]
972 [$($callback_args:tt)*]
973 [$($g:tt)*] [$($r:tt)*]
974 [$($($w:tt)+)?]
975 [$($inter:tt)*]
976 [ ; $($token:tt)* ]
977 ) => {
978 $callback ! {
979 $($callback_args)*
980 [
981 [$($g)*]
982 [$($r)*]
983 [$(where $($w)+)?]
984 $crate $crate
985 ]
986 $($inter)* ; $($token)*
987 }
988 };
989 (
990 [$callback:path]
991 [$($callback_args:tt)*]
992 [$($g:tt)*] [$($r:tt)*]
993 [$($($w:tt)+)?]
994 [$($inter:tt)*]
995 [ $( { $($body:tt)* } $($token:tt)* )? ]
996 ) => {
997 $callback ! {
998 $($callback_args)*
999 [
1000 [$($g)*]
1001 [$($r)*]
1002 [$(where $($w)+)?]
1003 $crate $crate
1004 ]
1005 $($inter)* $( { $($body)* } $($token)* )?
1006 }
1007 };
1008 (
1009 [$callback:path]
1010 [$($callback_args:tt)*]
1011 [$($g:tt)*] [$($r:tt)*]
1012 [$($w:tt)*]
1013 [$($inter:tt)*]
1014 [$token:tt $($other_tokens:tt)*]
1015 ) => {
1016 $crate::parse_where_clause_impl! {
1017 [$callback]
1018 [$($callback_args)*]
1019 [$($g)*] [$($r)*]
1020 [$($w)* $token]
1021 [$($inter)*]
1022 [$($other_tokens)*]
1023 }
1024 };
1025}
1026
1027#[doc(hidden)]
1028#[macro_export]
1029macro_rules! allow_where_clause_impl {
1030 (
1031 [$callback:path]
1032 [$($callback_args:tt)*]
1033 [$($inter:tt)*]
1034 [ ; $($token:tt)*]
1035 ) => {
1036 $callback ! {
1037 $($callback_args)*
1038 [
1039 []
1040 []
1041 []
1042 $crate $crate
1043 ]
1044 $($inter)* ; $($token)*
1045 }
1046 };
1047 (
1048 [$callback:path]
1049 [$($callback_args:tt)*]
1050 [$($inter:tt)*]
1051 [ $( { $($body:tt)* } $($token:tt)* )? ]
1052 ) => {
1053 $callback ! {
1054 $($callback_args)*
1055 [
1056 []
1057 []
1058 []
1059 $crate $crate
1060 ]
1061 $($inter)* $( { $($body)* } $($token)* )?
1062 }
1063 };
1064 (
1065 [$callback:path]
1066 [$($callback_args:tt)*]
1067 [$($inter:tt)*]
1068 [where $($token:tt)*]
1069 ) => {
1070 $crate::parse_where_clause_impl! {
1071 [$callback]
1072 [$($callback_args)*]
1073 [] []
1074 []
1075 [$($inter)*]
1076 [$($token)*]
1077 }
1078 };
1079 (
1080 [$callback:path]
1081 [$($callback_args:tt)*]
1082 [$($inter:tt)*]
1083 [$token:tt $($other_tokens:tt)*]
1084 ) => {
1085 $crate::allow_where_clause_impl! {
1086 [$callback] [$($callback_args)*]
1087 [$($inter)* $token]
1088 [$($other_tokens)*]
1089 }
1090 };
1091}
1092
1093#[macro_export]
1095macro_rules! concat {
1096 (
1097 $callback:path { $($callback_args:tt)* }
1098 $($([$($g:tt)*] [$($r:tt)*] [$($w:tt)*]),+ $(,)?)?
1099 ) => {
1100 $crate::concat_impl! {
1101 [$callback] [$($callback_args)*]
1102 [$($([$($g)*])+)?] [$($([$($r)*])+)?] [$($([$($w)*])+)?]
1103 }
1104 };
1105}
1106
1107#[doc(hidden)]
1108#[macro_export]
1109macro_rules! concat_impl {
1110 (
1111 [$callback:path] [$($callback_args:tt)*]
1112 [$($g:tt)*] [$($r:tt)*] [$($w:tt)*]
1113 ) => {
1114 $crate::concat_g_impl! {
1115 @list
1116 [$crate::concat_impl] [@g [$callback] [$($callback_args)*] [$($r)*] [$($w)*]]
1117 [$($g)*]
1118 [] []
1119 }
1120 };
1121 (
1122 @g
1123 [$callback:path] [$($callback_args:tt)*] [$($r:tt)*] [$($w:tt)*]
1124 [$($g:tt)*]
1125 ) => {
1126 $crate::concat_r_impl! {
1127 @list
1128 [$crate::concat_impl] [@r [$callback] [$($callback_args)*] [$($g)*] [$($w)*]]
1129 [$($r)*]
1130 [] []
1131 }
1132 };
1133 (
1134 @r
1135 [$callback:path] [$($callback_args:tt)*] [$($g:tt)*] [$($w:tt)*]
1136 [$($r:tt)*]
1137 ) => {
1138 $crate::concat_w_impl! {
1139 @list
1140 [$crate::concat_impl] [@w [$callback] [$($callback_args)*] [$($g)*] [$($r)*]]
1141 [$($w)*]
1142 []
1143 }
1144 };
1145 (
1146 @w
1147 [$callback:path] [$($callback_args:tt)*] [$($g:tt)*] [$($r:tt)*]
1148 [$($w:tt)*]
1149 ) => {
1150 $callback ! {
1151 $($callback_args)*
1152 [$($g)*] [$($r)*] [$($w)*]
1153 }
1154 };
1155}
1156
1157#[doc(hidden)]
1158#[macro_export]
1159macro_rules! concat_g_impl {
1160 (
1161 @list
1162 [$callback:path] [$($callback_args:tt)*]
1163 [[] $($list:tt)*]
1164 [$($lifetimes:tt)*] [$($types:tt)*]
1165 ) => {
1166 $crate::concat_g_impl! {
1167 @list
1168 [$callback] [$($callback_args)*]
1169 [$($list)*]
1170 [$($lifetimes)*] [$($types)*]
1171 }
1172 };
1173 (
1174 @list
1175 [$callback:path] [$($callback_args:tt)*]
1176 [[ < $($item:tt)* ] $($list:tt)*]
1177 [$($lifetimes:tt)*] [$($types:tt)*]
1178 ) => {
1179 $crate::concat_g_impl! {
1180 @item
1181 [$callback] [$($callback_args)*] [$($list)*]
1182 [$($lifetimes)*] [$($types)*]
1183 []
1184 [$($item)*]
1185 }
1186 };
1187 (
1188 @list
1189 [$callback:path] [$($callback_args:tt)*]
1190 [[$($item:tt)*] $($list:tt)*]
1191 [$($lifetimes:tt)*] [$($types:tt)*]
1192 ) => {
1193 $crate::std_compile_error!($crate::std_concat!(
1194 "invalid generics '",
1195 $crate::std_stringify!($($item:tt)*),
1196 "'"
1197 ));
1198 };
1199 (
1200 @list
1201 [$callback:path] [$($callback_args:tt)*]
1202 []
1203 [] []
1204 ) => {
1205 $callback ! {
1206 $($callback_args)*
1207 []
1208 }
1209 };
1210 (
1211 @list
1212 [$callback:path] [$($callback_args:tt)*]
1213 []
1214 [$([$($lifetime:tt)*])+] []
1215 ) => {
1216 $callback ! {
1217 $($callback_args)*
1218 [ < $($($lifetime)*),+ > ]
1219 }
1220 };
1221 (
1222 @list
1223 [$callback:path] [$($callback_args:tt)*]
1224 []
1225 [] [$([$($ty:tt)*])+]
1226 ) => {
1227 $callback ! {
1228 $($callback_args)*
1229 [ < $($($ty)*),+ > ]
1230 }
1231 };
1232 (
1233 @list
1234 [$callback:path] [$($callback_args:tt)*]
1235 []
1236 [$([$($lifetime:tt)*])+] [$([$($ty:tt)*])+]
1237 ) => {
1238 $callback ! {
1239 $($callback_args)*
1240 [ < $($($lifetime)*),+ , $($($ty)*),+ > ]
1241 }
1242 };
1243 (
1244 @item
1245 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1246 [$($lifetimes:tt)*] [$($types:tt)*]
1247 [$lifetime:lifetime $($constraint:tt)*]
1248 [, $($tail:tt)*]
1249 ) => {
1250 $crate::concat_g_impl! {
1251 @item
1252 [$callback] [$($callback_args)*] [$($list)*]
1253 [$($lifetimes)* [$lifetime $($constraint)*]] [$($types)*]
1254 []
1255 [$($tail)*]
1256 }
1257 };
1258 (
1259 @item
1260 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1261 [$($lifetimes:tt)*] [$($types:tt)*]
1262 [$ty:ident $($constraint:tt)*]
1263 [, $($tail:tt)*]
1264 ) => {
1265 $crate::concat_g_impl! {
1266 @item
1267 [$callback] [$($callback_args)*] [$($list)*]
1268 [$($lifetimes)*] [$($types)* [$ty $($constraint)*]]
1269 []
1270 [$($tail)*]
1271 }
1272 };
1273 (
1274 @item
1275 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1276 [$($lifetimes:tt)*] [$($types:tt)*]
1277 [$($param:tt)*]
1278 [ < $($tail:tt)*]
1279 ) => {
1280 $crate::concat_g_impl! {
1281 @angles
1282 [$callback] [$($callback_args)*] [$($list)*]
1283 [$($lifetimes)*] [$($types)*] [$($param)*]
1284 []
1285 []
1286 [$($tail)*]
1287 }
1288 };
1289 (
1290 @item
1291 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1292 [$($lifetimes:tt)*] [$($types:tt)*]
1293 [$lifetime:lifetime $($constraint:tt)*]
1294 [ > ]
1295 ) => {
1296 $crate::concat_g_impl! {
1297 @list
1298 [$callback] [$($callback_args)*]
1299 [$($list)*]
1300 [$($lifetimes)* [$lifetime $($constraint)*]] [$($types)*]
1301 }
1302 };
1303 (
1304 @item
1305 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1306 [$($lifetimes:tt)*] [$($types:tt)*]
1307 [$ty:ident $($constraint:tt)*]
1308 [ > ]
1309 ) => {
1310 $crate::concat_g_impl! {
1311 @list
1312 [$callback] [$($callback_args)*]
1313 [$($list)*]
1314 [$($lifetimes)*] [$($types)* [$ty $($constraint)*]]
1315 }
1316 };
1317 (
1318 @item
1319 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1320 [$($lifetimes:tt)*] [$($types:tt)*]
1321 []
1322 [ > ]
1323 ) => {
1324 $crate::concat_g_impl! {
1325 @list
1326 [$callback] [$($callback_args)*]
1327 [$($list)*]
1328 [$($lifetimes)*] [$($types)*]
1329 }
1330 };
1331 (
1332 @item
1333 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1334 [$($lifetimes:tt)*] [$($types:tt)*]
1335 [$($param:tt)*]
1336 [ > $($tail:tt)+ ]
1337 ) => {
1338 $crate::std_compile_error!($crate::std_concat!(
1339 "invalid generics '",
1340 $crate::std_stringify!($($tail:tt)+),
1341 "'"
1342 ));
1343 };
1344 (
1345 @item
1346 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1347 [$($lifetimes:tt)*] [$($types:tt)*]
1348 [$($param:tt)*]
1349 [$token:tt $($tail:tt)*]
1350 ) => {
1351 $crate::concat_g_impl! {
1352 @item
1353 [$callback] [$($callback_args)*] [$($list)*]
1354 [$($lifetimes)*] [$($types)*]
1355 [$($param)* $token]
1356 [$($tail)*]
1357 }
1358 };
1359 (
1360 @item
1361 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1362 [$($lifetimes:tt)*] [$($types:tt)*]
1363 [$($param:tt)*]
1364 []
1365 ) => {
1366 $crate::std_compile_error!("invalid generics");
1367 };
1368 (
1369 @angles
1370 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1371 [$($lifetimes:tt)*] [$($types:tt)*] [$($param:tt)*]
1372 [$($outer_levels:tt)*]
1373 [$($content:tt)*]
1374 [ < $($tail:tt)*]
1375 ) => {
1376 $crate::concat_g_impl! {
1377 @angles
1378 [$callback] [$($callback_args)*] [$($list)*]
1379 [$($lifetimes)*] [$($types)*] [$($param)*]
1380 [[$($content)*] $($outer_levels)*]
1381 []
1382 [$($tail)*]
1383 }
1384 };
1385 (
1386 @angles
1387 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1388 [$($lifetimes:tt)*] [$($types:tt)*] [$($param:tt)*]
1389 [[$($outer_level:tt)*] $($other_outer_levels:tt)*]
1390 [$($content:tt)*]
1391 [ > $($tail:tt)*]
1392 ) => {
1393 $crate::concat_g_impl! {
1394 @angles
1395 [$callback] [$($callback_args)*] [$($list)*]
1396 [$($lifetimes)*] [$($types)*] [$($param)*]
1397 [$($other_outer_levels)*]
1398 [$($outer_level)* < $($content)* > ]
1399 [$($tail)*]
1400 }
1401 };
1402 (
1403 @angles
1404 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1405 [$($lifetimes:tt)*] [$($types:tt)*] [$($param:tt)*]
1406 []
1407 [$($content:tt)*]
1408 [ > $($tail:tt)*]
1409 ) => {
1410 $crate::concat_g_impl! {
1411 @item
1412 [$callback] [$($callback_args)*] [$($list)*]
1413 [$($lifetimes)*] [$($types)*]
1414 [$($param)* < $($content)* > ]
1415 [$($tail)*]
1416 }
1417 };
1418 (
1419 @angles
1420 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1421 [$($lifetimes:tt)*] [$($types:tt)*] [$($param:tt)*]
1422 [$($outer_levels:tt)*]
1423 [$($content:tt)*]
1424 [ $token:tt $($tail:tt)*]
1425 ) => {
1426 $crate::concat_g_impl! {
1427 @angles
1428 [$callback] [$($callback_args)*] [$($list)*]
1429 [$($lifetimes)*] [$($types)*] [$($param)*]
1430 [$($outer_levels)*]
1431 [$($content)* $token]
1432 [$($tail)*]
1433 }
1434 };
1435 (
1436 @angles
1437 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1438 [$($lifetimes:tt)*] [$($types:tt)*] [$($param:tt)*]
1439 [$($outer_levels:tt)*]
1440 [$($content:tt)*]
1441 []
1442 ) => {
1443 $crate::std_compile_error!("invalid generics");
1444 };
1445}
1446
1447#[doc(hidden)]
1448#[macro_export]
1449macro_rules! concat_r_impl {
1450 (
1451 @list
1452 [$callback:path] [$($callback_args:tt)*]
1453 [[] $($list:tt)*]
1454 [$($lifetimes:tt)*] [$($types:tt)*]
1455 ) => {
1456 $crate::concat_r_impl! {
1457 @list
1458 [$callback] [$($callback_args)*]
1459 [$($list)*]
1460 [$($lifetimes)*] [$($types)*]
1461 }
1462 };
1463 (
1464 @list
1465 [$callback:path] [$($callback_args:tt)*]
1466 [[ < $($item:tt)* ] $($list:tt)*]
1467 [$($lifetimes:tt)*] [$($types:tt)*]
1468 ) => {
1469 $crate::concat_r_impl! {
1470 @item
1471 [$callback] [$($callback_args)*] [$($list)*]
1472 [$($lifetimes)*] [$($types)*]
1473 [, $($item)*]
1474 }
1475 };
1476 (
1477 @list
1478 [$callback:path] [$($callback_args:tt)*]
1479 [[$($item:tt)*] $($list:tt)*]
1480 [$($lifetimes:tt)*] [$($types:tt)*]
1481 ) => {
1482 $crate::std_compile_error!("invalid generics");
1483 };
1484 (
1485 @list
1486 [$callback:path] [$($callback_args:tt)*]
1487 []
1488 [] []
1489 ) => {
1490 $callback ! {
1491 $($callback_args)*
1492 []
1493 }
1494 };
1495 (
1496 @list
1497 [$callback:path] [$($callback_args:tt)*]
1498 []
1499 [$([$($lifetime:tt)*])+] []
1500 ) => {
1501 $callback ! {
1502 $($callback_args)*
1503 [ < $($($lifetime)*),+ > ]
1504 }
1505 };
1506 (
1507 @list
1508 [$callback:path] [$($callback_args:tt)*]
1509 []
1510 [] [$([$($ty:tt)*])+]
1511 ) => {
1512 $callback ! {
1513 $($callback_args)*
1514 [ < $($($ty)*),+ > ]
1515 }
1516 };
1517 (
1518 @list
1519 [$callback:path] [$($callback_args:tt)*]
1520 []
1521 [$([$($lifetime:tt)*])+] [$([$($ty:tt)*])+]
1522 ) => {
1523 $callback ! {
1524 $($callback_args)*
1525 [ < $($($lifetime)*),+ , $($($ty)*),+ > ]
1526 }
1527 };
1528 (
1529 @item
1530 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1531 [$($lifetimes:tt)*] [$($types:tt)*]
1532 [, $lifetime:lifetime $($tail:tt)*]
1533 ) => {
1534 $crate::concat_r_impl! {
1535 @item
1536 [$callback] [$($callback_args)*] [$($list)*]
1537 [$($lifetimes)* [$lifetime]] [$($types)*]
1538 [$($tail)*]
1539 }
1540 };
1541 (
1542 @item
1543 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1544 [$($lifetimes:tt)*] [$($types:tt)*]
1545 [, $ty:ident $($tail:tt)*]
1546 ) => {
1547 $crate::concat_r_impl! {
1548 @item
1549 [$callback] [$($callback_args)*] [$($list)*]
1550 [$($lifetimes)*] [$($types)* [$ty]]
1551 [$($tail)*]
1552 }
1553 };
1554 (
1555 @item
1556 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1557 [$($lifetimes:tt)*] [$($types:tt)*]
1558 [ $(,)? > ]
1559 ) => {
1560 $crate::concat_r_impl! {
1561 @list
1562 [$callback] [$($callback_args)*]
1563 [$($list)*]
1564 [$($lifetimes)*] [$($types)*]
1565 }
1566 };
1567 (
1568 @item
1569 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1570 [$($lifetimes:tt)*] [$($types:tt)*]
1571 [$($tail:tt)*]
1572 ) => {
1573 $crate::std_compile_error!($crate::std_concat!(
1574 "invalid generics '",
1575 $crate::std_stringify!($($tail:tt)+),
1576 "'"
1577 ));
1578 };
1579}
1580
1581#[doc(hidden)]
1582#[macro_export]
1583macro_rules! concat_w_impl {
1584 (
1585 @list
1586 [$callback:path] [$($callback_args:tt)*]
1587 [[] $($list:tt)*]
1588 [$($w:tt)*]
1589 ) => {
1590 $crate::concat_w_impl! {
1591 @list
1592 [$callback] [$($callback_args)*]
1593 [$($list)*]
1594 [$($w)*]
1595 }
1596 };
1597 (
1598 @list
1599 [$callback:path] [$($callback_args:tt)*]
1600 [[ where ] $($list:tt)*]
1601 [$($w:tt)*]
1602 ) => {
1603 $crate::concat_w_impl! {
1604 @list
1605 [$callback] [$($callback_args)*]
1606 [$($list)*]
1607 [$($w)*]
1608 }
1609 };
1610 (
1611 @list
1612 [$callback:path] [$($callback_args:tt)*]
1613 [[ where $($item:tt)* ] $($list:tt)*]
1614 [$($w:tt)*]
1615 ) => {
1616 $crate::concat_w_impl! {
1617 @item
1618 [$callback] [$($callback_args)*] [$($list)*]
1619 [$($w)*]
1620 []
1621 [$($item)*]
1622 }
1623 };
1624 (
1625 @list
1626 [$callback:path] [$($callback_args:tt)*]
1627 [[$($item:tt)*] $($list:tt)*]
1628 [$($w:tt)*]
1629 ) => {
1630 $crate::std_compile_error!($crate::std_concat!(
1631 "invalid generics '",
1632 $crate::std_stringify!($($item:tt)+),
1633 "'"
1634 ));
1635 };
1636 (
1637 @list
1638 [$callback:path] [$($callback_args:tt)*]
1639 []
1640 [$($([$($w:tt)*])+)?]
1641 ) => {
1642 $callback ! {
1643 $($callback_args)*
1644 [$(where $($($w)*),+)?]
1645 }
1646 };
1647 (
1648 @item
1649 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1650 [$($w:tt)*]
1651 [$($item:tt)*]
1652 [$(,)?]
1653 ) => {
1654 $crate::concat_w_impl! {
1655 @list
1656 [$callback] [$($callback_args)*]
1657 [$($list)*]
1658 [$($w)* [$($item)*]]
1659 }
1660 };
1661 (
1662 @item
1663 [$callback:path] [$($callback_args:tt)*] [$($list:tt)*]
1664 [$($w:tt)*]
1665 [$($item:tt)*]
1666 [$token:tt $($tail:tt)*]
1667 ) => {
1668 $crate::concat_w_impl! {
1669 @item
1670 [$callback] [$($callback_args)*] [$($list)*]
1671 [$($w)*]
1672 [$($item)* $token]
1673 [$($tail)*]
1674 }
1675 };
1676}
1677
1678#[cfg(test)]
1679mod tests {
1680 macro_rules! impl_test_trait {
1681 (
1682 struct $name:ident $($token:tt)*
1683 ) => {
1684 parse! {
1685 impl_test_trait {
1686 @impl struct $name
1687 }
1688 $($token)*
1689 }
1690 };
1691 (
1692 @impl struct $name:ident [$($g:tt)*] [$($r:tt)*] [$($w:tt)*] $($body:tt)*
1693 ) => {
1694 impl $($g)* TestTrait for $name $($r)* $($w)* { }
1695 };
1696 }
1697
1698 trait TestTrait { }
1699
1700 struct TestStruct { }
1701
1702 impl_test_trait! {
1703 struct TestStruct { }
1704 }
1705
1706 struct TestGenericStruct<'a, T: 'static> {
1707 a: &'a (),
1708 t: T,
1709 }
1710
1711 impl_test_trait! {
1712 struct TestGenericStruct<'a, T: 'static> { }
1713 }
1714
1715 struct TestGenericStructWithDefaultParameter<T=()>(T);
1716
1717 impl_test_trait! {
1718 struct TestGenericStructWithDefaultParameter<T=()>(T);
1719 }
1720
1721 struct TestGenericStructWithConstrainedDefaultParameter<T: 'static = ()>(T);
1722
1723 impl_test_trait! {
1724 struct TestGenericStructWithConstrainedDefaultParameter<T: 'static = ()>(T);
1725 }
1726
1727 #[test]
1728 fn it_works() {
1729 let test_struct = TestStruct { };
1730 let _: &dyn TestTrait = &test_struct;
1731 let test_generic_struct = TestGenericStruct {
1732 a: &(),
1733 t: ()
1734 };
1735 let _ = test_generic_struct.a;
1736 let _ = test_generic_struct.t;
1737 let _: &dyn TestTrait = &test_generic_struct;
1738 let test_generic_struct_ = TestGenericStructWithDefaultParameter(());
1739 let _: &dyn TestTrait = &test_generic_struct_;
1740 let _ = test_generic_struct_.0;
1741 let test_generic_struct__ = TestGenericStructWithConstrainedDefaultParameter(());
1742 let _: &dyn TestTrait = &test_generic_struct__;
1743 let _ = test_generic_struct__.0;
1744 }
1745
1746 macro_rules! impl_tr {
1747 (
1748 struct $name:ident $($token:tt)*
1749 ) => {
1750 parse! {
1751 impl_tr {
1752 @impl struct $name
1753 }
1754 $($token)*
1755 }
1756 };
1757 (
1758 @impl struct $name:ident [$($g:tt)*] [$($r:tt)*] [$($w:tt)*] become $tr:ident $($body:tt)*
1759 ) => {
1760 impl $($g)* $tr for $name $($r)* $($w)* { }
1761 };
1762 }
1763
1764 trait TestTrait2 { }
1765
1766 impl_tr! {
1767 struct TestStruct become TestTrait2 { }
1768 }
1769
1770 impl_tr! {
1771 struct TestGenericStruct<'a, T> become TestTrait2 where T: 'static { }
1772 }
1773
1774 macro_rules! struct_A {
1775 (
1776 ) => {
1777 concat_g_impl! {
1778 @list
1779 [struct_A] [@struct]
1780 [[ < 'a, 'b > ] [] [ < 'c, 'd, T: 'static, > ]]
1781 [] []
1782 }
1783 };
1784 (
1785 @struct [$($g:tt)*]
1786 ) => {
1787 struct A $($g)* {
1788 a: &'a (),
1789 b: &'b (),
1790 c: &'c (),
1791 d: &'d T,
1792 }
1793 };
1794 }
1795
1796 struct_A!();
1797
1798 #[test]
1799 fn run_concat_g_impl() {
1800 let x = A { a: &(), b: &(), c: &(), d: &0u16 };
1801 let _ = x.a;
1802 let _ = x.b;
1803 let _ = x.c;
1804 let _ = x.d;
1805 }
1806
1807 macro_rules! struct_B {
1808 (
1809 ) => {
1810 concat_r_impl! {
1811 @list
1812 [struct_B] [@struct]
1813 [[ < 'a, 'b > ] [] [ < 'c, 'd, T, > ]]
1814 [] []
1815 }
1816 };
1817 (
1818 @struct [$($g:tt)*]
1819 ) => {
1820 struct B $($g)* {
1821 a: &'a (),
1822 b: &'b (),
1823 c: &'c (),
1824 d: &'d T,
1825 }
1826 };
1827 }
1828
1829 struct_B!();
1830
1831 #[test]
1832 fn run_concat_r_impl() {
1833 let x = B { a: &(), b: &(), c: &(), d: &0u16 };
1834 let _ = x.a;
1835 let _ = x.b;
1836 let _ = x.c;
1837 let _ = x.d;
1838 }
1839}