tt_call/rust/
ty.rs

1/// Parse any syntactically valid Rust type.
2/// <sup>**[tt-call]**</sup>
3///
4/// This is the tt-call equivalent of Rust's `$:ty` fragment.
5///
6/// # Input
7///
8///   - `input = [{` tokens `}]`
9///
10/// # Output
11///
12///   - `type = [{` tokens of type `}]`
13///   - `rest = [{` remaining tokens after type `}]`
14///
15/// # Example
16///
17/// ```
18/// use tt_call::{parse_type, tt_call, tt_debug};
19///
20/// fn main() {
21///     tt_call! {
22///         macro = [{ parse_type }]
23///         input = [{ Vec<u8>, compressed=false }]
24///         ~~> tt_debug
25///     }
26/// }
27/// ```
28///
29/// The output is:
30///
31/// ```text
32/// type = [{ Vec < u8 > }]
33/// rest = [{ , compressed = false }]
34/// ```
35#[macro_export]
36macro_rules! parse_type {
37    {
38        $caller:tt
39        input = [{ $($tt:tt)* }]
40    } => {
41        $crate::private_parse_type! {
42            $caller
43            tokens = [{ $($tt)* }]
44            _tokens = [{ $($tt)* }]
45        }
46    };
47}
48
49#[doc(hidden)]
50#[macro_export]
51macro_rules! private_parse_type_with_plus {
52    // Entry point.
53    {
54        $caller:tt
55        input = [{ $($input:tt)* }]
56    } => {
57        $crate::private_parse_type_with_plus! {
58            $caller
59            pieces = [{ }]
60            tokens = [{ $($input)* }]
61        }
62    };
63
64    // There is at least one previously parsed piece, and next token is a
65    // lifetime.
66    {
67        $caller:tt
68        pieces = [{ $($pieces:tt)+ }]
69        tokens = [{ $lifetime:lifetime $($rest:tt)* }]
70    } => {
71        $crate::private_parse_type_with_plus! {
72            $caller
73            pieces = [{ $($pieces)* }]
74            type = [{ $lifetime }]
75            rest = [{ $($rest)* }]
76        }
77    };
78
79    // Next token is not a lifetime or this is the first piece. Parse as a type.
80    {
81        $caller:tt
82        pieces = [{ $($pieces:tt)* }]
83        tokens = [{ $($tokens:tt)* }]
84    } => {
85        $crate::tt_call! {
86            macro = [{ $crate::parse_type }]
87            input = [{ $($tokens)* }]
88            ~~> $crate::private_parse_type_with_plus! {
89                $caller
90                pieces = [{ $($pieces)* }]
91            }
92        }
93    };
94
95    // Return from parse_type. Dup the rest tokens.
96    {
97        $caller:tt
98        pieces = [{ $($pieces:tt)* }]
99        type = [{ $($ty:tt)* }]
100        rest = [{ $($rest:tt)* }]
101    } => {
102        $crate::private_parse_type_with_plus! {
103            $caller
104            pieces = [{ $($pieces)* }]
105            type = [{ $($ty)* }]
106            rest = [{ $($rest)* }]
107            _rest = [{ $($rest)* }]
108        }
109    };
110
111    // Most recently parsed type or lifetime is followed by a plus. Recurse.
112    {
113        $caller:tt
114        pieces = [{ $($pieces:tt)* }]
115        type = [{ $($ty:tt)* }]
116        rest = [{ + $($rest:tt)* }]
117        _rest = [{ $plus:tt $($dup:tt)* }]
118    } => {
119        $crate::private_parse_type_with_plus! {
120            $caller
121            pieces = [{ $($pieces)* $($ty)* $plus }]
122            tokens = [{ $($rest)* }]
123        }
124    };
125
126    // Not followed by a plus so the plus-separated type is done. Return.
127    {
128        $caller:tt
129        pieces = [{ $($pieces:tt)* }]
130        type = [{ $($ty:tt)* }]
131        rest = [{ $($rest:tt)* }]
132        _rest = [{ $($dup:tt)* }]
133    } => {
134        $crate::tt_return! {
135            $caller
136            type = [{ $($pieces)* $($ty)* }]
137            rest = [{ $($rest)* }]
138        }
139    };
140}
141
142#[doc(hidden)]
143#[macro_export]
144macro_rules! private_parse_type {
145    // First token is a nonempty bracketed group. Validate and return as slice
146    // or array.
147    {
148        $caller:tt
149        tokens = [{ [$($bracketed:tt)+] $($rest:tt)* }]
150        _tokens = [{ $original:tt $($dup:tt)* }]
151    } => {
152        $crate::tt_call! {
153            macro = [{ $crate::private_validate_inside_brackets }]
154            original = [{ $original }]
155            input = [{ $($bracketed)* }]
156            ~~> $crate::tt_return! {
157                $caller
158                type = [{ $original }]
159                rest = [{ $($rest)* }]
160            }
161        }
162    };
163
164    // Unexpected: first token is empty brackets
165    {
166        $caller:tt
167        tokens = [{ [] $($rest:tt)* }]
168        _tokens = [{ $first:tt $($dup:tt)* }]
169    } => {
170        $crate::private_unexpected_close_empty_square_brackets! {
171            $first
172        }
173    };
174
175    // First token is a parenthesized group. Validate and return as tuple type.
176    {
177        $caller:tt
178        tokens = [{ ($($parenthesized:tt)*) $($rest:tt)* }]
179        _tokens = [{ $original:tt $($dup:tt)* }]
180    } => {
181        $crate::tt_call! {
182            macro = [{ $crate::private_validate_inside_parens }]
183            input = [{ $($parenthesized)* }]
184            ~~> $crate::tt_return! {
185                $caller
186                type = [{ $original }]
187                rest = [{ $($rest)* }]
188            }
189        }
190    };
191
192    // First token is asterisk. Parse a pointer.
193    {
194        $caller:tt
195        tokens = [{ * $($rest:tt)+ }]
196        _tokens = [{ $asterisk:tt $($dup:tt)* }]
197    } => {
198        $crate::private_parse_pointer! {
199            $caller
200            pointer = [{ $asterisk }]
201            tokens = [{ $($rest)* }]
202        }
203    };
204
205    // First token is ampersand. Parse a reference.
206    {
207        $caller:tt
208        tokens = [{ & $($rest:tt)+ }]
209        _tokens = [{ $ampersand:tt $($dup:tt)* }]
210    } => {
211        $crate::private_parse_reference! {
212            $caller
213            reference = [{ $ampersand }]
214            tokens = [{ $($rest)* }]
215        }
216    };
217
218    // First token is `fn` keyword. Parse a function pointer type.
219    {
220        $caller:tt
221        tokens = [{ fn $($rest:tt)+ }]
222        _tokens = [{ $fn:tt $($dup:tt)* }]
223    } => {
224        $crate::private_parse_function! {
225            $caller
226            function = [{ $fn }]
227            tokens = [{ $($rest)* }]
228        }
229    };
230
231    // Unexpected: input ends with `fn` keyword.
232    {
233        $caller:tt
234        tokens = [{ fn }]
235        _tokens = [{ $unexpected:tt }]
236    } => {
237        $crate::error_unexpected! {
238            $unexpected
239        }
240    };
241
242    // The never type. Return.
243    {
244        $caller:tt
245        tokens = [{ ! $($rest:tt)* }]
246        _tokens = [{ $($dup:tt)* }]
247    } => {
248        $crate::tt_return! {
249            $caller
250            type = [{ ! }]
251            rest = [{ $($rest)* }]
252        }
253    };
254
255    // First token is `dyn` contextual keyword. Parse trait type with plus.
256    {
257        $caller:tt
258        tokens = [{ dyn $($rest:tt)+ }]
259        _tokens = [{ $dyn:tt $($dup:tt)* }]
260    } => {
261        $crate::tt_call! {
262            macro = [{ $crate::private_parse_type_with_plus }]
263            input = [{ $($rest)* }]
264            ~~> $crate::private_parse_type! {
265                $caller
266                object = [{ $dyn }]
267            }
268        }
269    };
270
271    // Unexpected: input ends with `dyn` contextual keyword.
272    {
273        $caller:tt
274        tokens = [{ dyn }]
275        _tokens = [{ $unexpected:tt }]
276    } => {
277        $crate::error_unexpected! {
278            $unexpected
279        }
280    };
281
282    // First token is `impl` keyword. Parse trait type with plus.
283    {
284        $caller:tt
285        tokens = [{ impl $($rest:tt)+ }]
286        _tokens = [{ $impl:tt $($dup:tt)* }]
287    } => {
288        $crate::tt_call! {
289            macro = [{ $crate::private_parse_type_with_plus }]
290            input = [{ $($rest)* }]
291            ~~> $crate::private_parse_type! {
292                $caller
293                object = [{ $impl }]
294            }
295        }
296    };
297
298    // Unexpected: input ends with `impl` keyword.
299    {
300        $caller:tt
301        tokens = [{ impl }]
302        _tokens = [{ $unexpected:tt }]
303    } => {
304        $crate::error_unexpected! {
305            $unexpected
306        }
307    };
308
309    // Return from parsing type after `dyn` or `impl`.
310    {
311        $caller:tt
312        object = [{ $kind:ident }]
313        type = [{ $($element:tt)* }]
314        rest = [{ $($rest:tt)* }]
315    } => {
316        $crate::tt_return! {
317            $caller
318            type = [{ $kind $($element)* }]
319            rest = [{ $($rest)* }]
320        }
321    };
322
323    // The underscore inferred type.
324    {
325        $caller:tt
326        tokens = [{ _ $($rest:tt)* }]
327        _tokens = [{ $underscore:tt $($dup:tt)* }]
328    } => {
329        $crate::tt_return! {
330            $caller
331            type = [{ $underscore }]
332            rest = [{ $($rest)* }]
333        }
334    };
335
336    // First token is `for` keyword. Parse poly trait.
337    {
338        $caller:tt
339        tokens = [{ for $($rest:tt)+ }]
340        _tokens = [{ $for:tt $($dup:tt)* }]
341    } => {
342        $crate::private_parse_poly_trait! {
343            $caller
344            poly_trait = [{ $for }]
345            tokens = [{ $($rest)* }]
346        }
347    };
348
349    // Unexpected: input ends with `for` keyword.
350    {
351        $caller:tt
352        tokens = [{ for }]
353        _tokens = [{ $unexpected:tt }]
354    } => {
355        $crate::error_unexpected! {
356            $unexpected
357        }
358    };
359
360    // Type macro invocation with relative path and parentheses.
361    //
362    // TODO: preserve the span of colons, bang, and parens.
363    {
364        $caller:tt
365        tokens = [{ $($path:ident)::+ ! ( $($args:tt)* ) $($rest:tt)* }]
366        _tokens = [{ $($dup:tt)* }]
367    } => {
368        $crate::tt_return! {
369            $caller
370            type = [{ $($path)::* ! ( $($args)* ) }]
371            rest = [{ $($rest)* }]
372        }
373    };
374
375    // Type macro invocation with absolute path and parentheses.
376    {
377        $caller:tt
378        tokens = [{ $(:: $path:ident)+ ! ( $($args:tt)* ) $($rest:tt)* }]
379        _tokens = [{ $($dup:tt)* }]
380    } => {
381        $crate::tt_return! {
382            $caller
383            type = [{ $(:: $path)* ! ( $($args)* ) }]
384            rest = [{ $($rest)* }]
385        }
386    };
387
388    // Type macro invocation with relative path and square brackets.
389    {
390        $caller:tt
391        tokens = [{ $($path:ident)::+ ! [ $($args:tt)* ] $($rest:tt)* }]
392        _tokens = [{ $($dup:tt)* }]
393    } => {
394        $crate::tt_return! {
395            $caller
396            type = [{ $($path)::* ! [ $($args)* ] }]
397            rest = [{ $($rest)* }]
398        }
399    };
400
401    // Type macro invocation with absolute path and square brackets.
402    {
403        $caller:tt
404        tokens = [{ $(:: $path:ident)+ ! [ $($args:tt)* ] $($rest:tt)* }]
405        _tokens = [{ $($dup:tt)* }]
406    } => {
407        $crate::tt_return! {
408            $caller
409            type = [{ $(:: $path)* ! [ $($args)* ] }]
410            rest = [{ $($rest)* }]
411        }
412    };
413
414    // Type macro invocation with relative path and curly braces.
415    {
416        $caller:tt
417        tokens = [{ $($path:ident)+ ! { $($args:tt)* } $($rest:tt)* }]
418        _tokens = [{ $($dup:tt)* }]
419    } => {
420        $crate::tt_return! {
421            $caller
422            type = [{ $($path)::* ! { $($args)* } }]
423            rest = [{ $($rest)* }]
424        }
425    };
426
427    // Type macro invocation with absolute path and curly braces.
428    {
429        $caller:tt
430        tokens = [{ $(:: $path:ident)+ ! { $($args:tt)* } $($rest:tt)* }]
431        _tokens = [{ $($dup:tt)* }]
432    } => {
433        $crate::tt_return! {
434            $caller
435            type = [{ $(:: $path)* ! { $($args)* } }]
436            rest = [{ $($rest)* }]
437        }
438    };
439
440    // First token is open angle bracket qualified path.
441    {
442        $caller:tt
443        tokens = [{ < $($rest:tt)+ }]
444        _tokens = [{ $lt:tt $($dup:tt)* }]
445    } => {
446        $crate::tt_call! {
447            macro = [{ $crate::parse_type }]
448            input = [{ $($rest)* }]
449            ~~> $crate::private_parse_type! {
450                $caller
451                type_prefix = [{ $lt }]
452            }
453        }
454    };
455
456    // Unexpected: input ends with open angle bracket.
457    {
458        $caller:tt
459        type_prefix = [{ < }]
460        type = [{ $($ty:tt)+ }]
461        rest = [{ }]
462    } => {
463        $crate::error_unexpected_last! {
464            $($ty)*
465        }
466    };
467
468    // Return from parsing angle bracketed path prefix element. Dup the rest
469    // tokens.
470    {
471        $caller:tt
472        type_prefix = [{ $($prefix:tt)* }]
473        type = [{ $($ty:tt)* }]
474        rest = [{ $($rest:tt)+ }]
475    } => {
476        $crate::private_parse_type! {
477            $caller
478            type_prefix = [{ $($prefix)* }]
479            type = [{ $($ty)* }]
480            rest = [{ $($rest)* }]
481            _rest = [{ $($rest)* }]
482        }
483    };
484
485    // Angle brackets are fully qualified trait syntax with absolute path.
486    {
487        $caller:tt
488        type_prefix = [{ $lt:tt }]
489        type = [{ $($qself:tt)* }]
490        rest = [{ as :: $_segment:ident $($rest:tt)* }]
491        _rest = [{ $as:tt $colons:tt $segment:tt $($dup:tt)* }]
492    } => {
493        $crate::tt_call! {
494            macro = [{ $crate::private_parse_possibly_empty_path_after_ident }]
495            input = [{ $($rest)* }]
496            ~~> $crate::private_parse_type! {
497                $caller
498                qpath = [{ $lt $($qself)* $as $colons $segment }]
499            }
500        }
501    };
502
503    // Unexpected: angle bracketed trait absolute path is invalid.
504    {
505        $caller:tt
506        type_prefix = [{ $lt:tt }]
507        type = [{ $($qself:tt)* }]
508        rest = [{ as :: $($unexpected:tt)+ }]
509        _rest = [{ $($dup:tt)* }]
510    } => {
511        $crate::error_unexpected! {
512            $($unexpected)*
513        }
514    };
515
516    // Angle brackets are fully qualified trait syntax with relative path.
517    {
518        $caller:tt
519        type_prefix = [{ $lt:tt }]
520        type = [{ $($qself:tt)* }]
521        rest = [{ as $_segment:ident $($rest:tt)* }]
522        _rest = [{ $as:tt $segment:tt $($dup:tt)* }]
523    } => {
524        $crate::tt_call! {
525            macro = [{ $crate::private_parse_possibly_empty_path_after_ident }]
526            input = [{ $($rest)* }]
527            ~~> $crate::private_parse_type! {
528                $caller
529                qpath = [{ $lt $($qself)* $as $segment }]
530            }
531        }
532    };
533
534    // Unexpected: angle bracketed trait relative path is invalid.
535    {
536        $caller:tt
537        type_prefix = [{ < }]
538        type = [{ $($qself:tt)* }]
539        rest = [{ as $($unexpected:tt)+ }]
540        _rest = [{ $($dup:tt)* }]
541    } => {
542        $crate::error_unexpected! {
543            $($unexpected)*
544        }
545    };
546
547    // Return from parsing fully qualified trait syntax. Dup the rest tokens.
548    {
549        $caller:tt
550        qpath = [{ $($qpath:tt)* }]
551        path = [{ $($path:tt)* }]
552        rest = [{ $($rest:tt)* }]
553    } => {
554        $crate::private_parse_type! {
555            $caller
556            qpath = [{ $($qpath)* }]
557            path = [{ $($path)* }]
558            rest = [{ $($rest)* }]
559            _rest = [{ $($rest)* }]
560        }
561    };
562
563    // Close angle bracket of fully qualified trait syntax. Parse rest of path.
564    {
565        $caller:tt
566        qpath = [{ $($qpath:tt)* }]
567        path = [{ $($path:tt)* }]
568        rest = [{ > :: $_segment:ident $($rest:tt)* }]
569        _rest = [{ $gt:tt $colons:tt $segment:tt $($dup:tt)* }]
570    } => {
571        $crate::tt_call! {
572            macro = [{ $crate::private_parse_possibly_empty_path_after_ident }]
573            input = [{ $($rest)* }]
574            ~~> $crate::private_parse_type! {
575                $caller
576                path_prefix = [{ $($qpath)* $($path)* $gt $colons $segment }]
577            }
578        }
579    };
580
581    // Unexpected: path after fully qualified trait syntax is invalid.
582    {
583        $caller:tt
584        qpath = [{ $($qpath:tt)* }]
585        path = [{ $($path:tt)* }]
586        rest = [{ > :: $($unexpected:tt)+ }]
587        _rest = [{ $($dup:tt)* }]
588    } => {
589        $crate::error_unexpected! {
590            $($unexpected)*
591        }
592    };
593
594    // Unexpected: fully qualified trait syntax is not followed by path.
595    {
596        $caller:tt
597        qpath = [{ $($qpath:tt)* }]
598        path = [{ $($path:tt)* }]
599        rest = [{ > $($unexpected:tt)+ }]
600        _rest = [{ $($dup:tt)* }]
601    } => {
602        $crate::error_unexpected! {
603            $($unexpected)*
604        }
605    };
606
607    // Unexpected: failed to find close angle bracket of fully qualified trait
608    // syntax.
609    {
610        $caller:tt
611        qpath = [{ $($qpath:tt)* }]
612        path = [{ $($path:tt)* }]
613        rest = [{ $($unexpected:tt)+ }]
614        _rest = [{ $($dup:tt)* }]
615    } => {
616        $crate::error_unexpected! {
617            $($unexpected)*
618        }
619    };
620
621    // Unexpected: input ends inside of angle bracketed trait path.
622    {
623        $caller:tt
624        qpath = [{ $($qpath:tt)* }]
625        path = [{ $($path:tt)* }]
626        rest = [{ }]
627        _rest = [{ }]
628    } => {
629        $crate::error_unexpected_last! {
630            $($qpath)* $($path)*
631        }
632    };
633
634    // Angle brackets are a type by itself, not trait path. Parse rest of path.
635    {
636        $caller:tt
637        type_prefix = [{ $lt:tt }]
638        type = [{ $($qself:tt)* }]
639        rest = [{ > :: $_segment:ident $($rest:tt)* }]
640        _rest = [{ $gt:tt $colons:tt $segment:tt $($dup:tt)* }]
641    } => {
642        $crate::tt_call! {
643            macro = [{ $crate::private_parse_possibly_empty_path_after_ident }]
644            input = [{ $($rest)* }]
645            ~~> $crate::private_parse_type! {
646                $caller
647                path_prefix = [{ $lt $($qself)* $gt $colons $segment }]
648            }
649        }
650    };
651
652    // Unexpected: failed to find close angle bracket after type.
653    {
654        $caller:tt
655        type_prefix = [{ < }]
656        type = [{ $($qself:tt)* }]
657        rest = [{ $($unexpected:tt)+ }]
658        _rest = [{ $($dup:tt)* }]
659    } => {
660        $crate::error_unexpected! {
661            $($unexpected)*
662        }
663    };
664
665    // Parse absolute path.
666    {
667        $caller:tt
668        tokens = [{ :: $_segment:ident $($rest:tt)* }]
669        _tokens = [{ $colons:tt $segment:tt $($dup:tt)* }]
670    } => {
671        $crate::tt_call! {
672            macro = [{ $crate::private_parse_path }]
673            input = [{ $colons $segment $($rest)* }]
674            ~~> $crate::private_parse_type! {
675                $caller
676                path_prefix = [{ }]
677            }
678        }
679    };
680
681    // Unexpected: invalid start of absolute path.
682    {
683        $caller:tt
684        tokens = [{ :: $($unexpected:tt)+ }]
685        _tokens = [{ $($dup:tt)* }]
686    } => {
687        $crate::error_unexpected! {
688            $($unexpected)*
689        }
690    };
691
692    // Parse relative path.
693    {
694        $caller:tt
695        tokens = [{ $_segment:ident $($rest:tt)* }]
696        _tokens = [{ $segment:tt $($dup:tt)* }]
697    } => {
698        $crate::tt_call! {
699            macro = [{ $crate::private_parse_path }]
700            input = [{ $segment $($rest)* }]
701            ~~> $crate::private_parse_type! {
702                $caller
703                path_prefix = [{ }]
704            }
705        }
706    };
707
708    // First token is `?` for a maybe-trait.
709    {
710        $caller:tt
711        tokens = [{ ? $($tokens:tt)* }]
712        _tokens = [{ $question:tt $($dup:tt)* }]
713    } => {
714        $crate::tt_call! {
715            macro = [{ $crate::private_parse_path }]
716            input = [{ $($tokens)* }]
717            ~~> $crate::private_parse_type! {
718                $caller
719                path_prefix = [{ $question }]
720            }
721        }
722    };
723
724    // Return from parsing a path.
725    {
726        $caller:tt
727        path_prefix = [{ $($prefix:tt)* }]
728        path = [{ $($path:tt)* }]
729        rest = [{ $($rest:tt)* }]
730    } => {
731        $crate::tt_return! {
732            $caller
733            type = [{ $($prefix)* $($path)* }]
734            rest = [{ $($rest)* }]
735        }
736    };
737
738    // Unexpected: unrecognized first token.
739    {
740        $caller:tt
741        tokens = [{ $($unexpected:tt)+ }]
742        _tokens = [{ $($dup:tt)* }]
743    } => {
744        $crate::error_unexpected! {
745            $($unexpected)*
746        }
747    };
748
749    // Unexpected: input is empty.
750    {
751        $caller:tt
752        tokens = [{ }]
753        _tokens = [{ }]
754    } => {
755        $crate::error_eof! {}
756    };
757}
758
759#[doc(hidden)]
760#[macro_export]
761macro_rules! private_parse_pointer {
762    // Entry point. Dup tokens.
763    {
764        $caller:tt
765        pointer = [{ $($pointer:tt)* }]
766        tokens = [{ $($tokens:tt)* }]
767    } => {
768        $crate::private_parse_pointer! {
769            $caller
770            pointer = [{ $($pointer)* }]
771            tokens = [{ $($tokens)* }]
772            _tokens = [{ $($tokens)* }]
773        }
774    };
775
776    // Pointer is a *const. Parse element type.
777    {
778        $caller:tt
779        pointer = [{ $asterisk:tt }]
780        tokens = [{ const $($rest:tt)+ }]
781        _tokens = [{ $const:tt $($dup:tt)* }]
782    } => {
783        $crate::tt_call! {
784            macro = [{ $crate::parse_type }]
785            input = [{ $($rest)* }]
786            ~~> $crate::private_parse_pointer! {
787                $caller
788                pointer = [{ $asterisk $const }]
789            }
790        }
791    };
792
793    // Pointer is a *mut. Parse element type.
794    {
795        $caller:tt
796        pointer = [{ $asterisk:tt }]
797        tokens = [{ mut $($rest:tt)+ }]
798        _tokens = [{ $mut:tt $($dup:tt)+ }]
799    } => {
800        $crate::tt_call! {
801            macro = [{ $crate::parse_type }]
802            input = [{ $($rest)* }]
803            ~~> $crate::private_parse_pointer! {
804                $caller
805                pointer = [{ $asterisk $mut }]
806            }
807        }
808    };
809
810    // Unexpected: unrecognized pointer type.
811    {
812        $caller:tt
813        pointer = [{ * }]
814        tokens = [{ $($unexpected:tt)+ }]
815        _tokens = [{ $($dup:tt)* }]
816    } => {
817        $crate::error_unexpected! {
818            $($unexpected)*
819        }
820    };
821
822    // Return from parsing element type.
823    {
824        $caller:tt
825        pointer = [{ $($pointer:tt)* }]
826        type = [{ $($element:tt)* }]
827        rest = [{ $($rest:tt)* }]
828    } => {
829        $crate::tt_return! {
830            $caller
831            type = [{ $($pointer)* $($element)* }]
832            rest = [{ $($rest)* }]
833        }
834    };
835}
836
837#[doc(hidden)]
838#[macro_export]
839macro_rules! private_parse_reference {
840    // Entry point. Dup tokens.
841    {
842        $caller:tt
843        reference = [{ $($reference:tt)* }]
844        tokens = [{ $($tokens:tt)* }]
845    } => {
846        $crate::private_parse_reference! {
847            $caller
848            reference = [{ $($reference)* }]
849            tokens = [{ $($tokens)* }]
850            _tokens = [{ $($tokens)* }]
851        }
852    };
853
854    // Reference has an explicit lifetime.
855    {
856        $caller:tt
857        reference = [{ $ampersand:tt }]
858        tokens = [{ $lifetime:lifetime $($rest:tt)+ }]
859        _tokens = [{ $($dup:tt)* }]
860    } => {
861        $crate::private_parse_reference! {
862            $caller
863            reference = [{ $ampersand $lifetime }]
864            tokens = [{ $($rest)* }]
865            _tokens = [{ $($rest)* }]
866        }
867    };
868
869    // Exclusive reference.
870    {
871        $caller:tt
872        reference = [{ $ampersand:tt $($lifetime:lifetime)* }]
873        tokens = [{ mut $($rest:tt)+ }]
874        _tokens = [{ $mut:tt $($dup:tt)* }]
875    } => {
876        $crate::private_parse_reference! {
877            $caller
878            reference = [{ $ampersand $($lifetime)* $mut }]
879            tokens = [{ $($rest)* }]
880            _tokens = [{ $($rest)* }]
881        }
882    };
883
884    // Unexpected: input ends with &mut.
885    {
886        $caller:tt
887        reference = [{ & $($lifetime:lifetime)* }]
888        tokens = [{ mut }]
889        _tokens = [{ $unexpected:tt }]
890    } => {
891        $crate::error_unexpected! {
892            $unexpected
893        }
894    };
895
896    // Parse element type.
897    {
898        $caller:tt
899        reference = [{ $ampersand:tt $($lifetime:lifetime)* $($mut:ident)* }]
900        tokens = [{ $($rest:tt)+ }]
901        _tokens = [{ $($dup:tt)* }]
902    } => {
903        $crate::tt_call! {
904            macro = [{ $crate::parse_type }]
905            input = [{ $($rest)* }]
906            ~~> $crate::private_parse_reference! {
907                $caller
908                reference = [{ $ampersand $($lifetime)* $($mut)* }]
909            }
910        }
911    };
912
913    // Return from parsing element type.
914    {
915        $caller:tt
916        reference = [{ $($reference:tt)* }]
917        type = [{ $($element:tt)* }]
918        rest = [{ $($rest:tt)* }]
919    } => {
920        $crate::tt_return! {
921            $caller
922            type = [{ $($reference)* $($element)* }]
923            rest = [{ $($rest)* }]
924        }
925    };
926}
927
928#[doc(hidden)]
929#[macro_export]
930macro_rules! private_parse_function {
931    // Entry point. Dup tokens.
932    {
933        $caller:tt
934        function = [{ $($function:tt)* }]
935        tokens = [{ $($tokens:tt)* }]
936    } => {
937        $crate::private_parse_function! {
938            $caller
939            function = [{ $($function)* }]
940            tokens = [{ $($tokens)* }]
941            _tokens = [{ $($tokens)* }]
942        }
943    };
944
945    // Validate parenthesized function arguments.
946    {
947        $caller:tt
948        function = [{ $fn:tt }]
949        tokens = [{ ($($args:tt)*) $($rest:tt)* }]
950        _tokens = [{ $paren:tt $($dup:tt)* }]
951    } => {
952        $crate::tt_call! {
953            macro = [{ $crate::private_validate_fn_args }]
954            input = [{ $($args)* }]
955            ~~> $crate::private_parse_function! {
956                $caller
957                function = [{ $fn $paren }]
958                rest = [{ $($rest)* }]
959                _rest = [{ $($rest)* }]
960            }
961        }
962    };
963
964    // Unexpected: failed to find parenthesized function arguments.
965    {
966        $caller:tt
967        function = [{ $fn:tt }]
968        tokens = [{ $($unexpected:tt)+ }]
969        _tokens = [{ $($dup:tt)* }]
970    } => {
971        $crate::error_unexpected! {
972            $($unexpected)*
973        }
974    };
975
976    // Unexpected: input ends with `fn(...) ->`.
977    {
978        $caller:tt
979        function = [{ $fn:tt $args:tt }]
980        rest = [{ -> }]
981        _rest = [{ $arrow:tt }]
982    } => {
983        $crate::error_unexpected! {
984            $arrow
985        }
986    };
987
988    // Parse function return type.
989    {
990        $caller:tt
991        function = [{ $fn:tt $args:tt }]
992        rest = [{ -> $($rest:tt)+ }]
993        _rest = [{ $arrow:tt $($dup:tt)* }]
994    } => {
995        $crate::tt_call! {
996            macro = [{ $crate::parse_type }]
997            input = [{ $($rest)* }]
998            ~~> $crate::private_parse_function! {
999                $caller
1000                function = [{ $fn $args $arrow }]
1001            }
1002        }
1003    };
1004
1005    // Function has implicit unit return type.
1006    {
1007        $caller:tt
1008        function = [{ $fn:tt $args:tt }]
1009        rest = [{ $($rest:tt)* }]
1010        _rest = [{ $($dup:tt)* }]
1011    } => {
1012        $crate::tt_return! {
1013            $caller
1014            type = [{ $fn $args }]
1015            rest = [{ $($rest)* }]
1016        }
1017    };
1018
1019    // Return from parsing function return type.
1020    {
1021        $caller:tt
1022        function = [{ $fn:tt $args:tt $arrow:tt }]
1023        type = [{ $($ret:tt)* }]
1024        rest = [{ $($rest:tt)* }]
1025    } => {
1026        $crate::tt_return! {
1027            $caller
1028            type = [{ $fn $args $arrow $($ret)* }]
1029            rest = [{ $($rest)* }]
1030        }
1031    };
1032}
1033
1034#[doc(hidden)]
1035#[macro_export]
1036macro_rules! private_parse_poly_trait {
1037    // Entry point. Dup tokens.
1038    {
1039        $caller:tt
1040        poly_trait = [{ $($poly_trait:tt)* }]
1041        tokens = [{ $($tokens:tt)+ }]
1042    } => {
1043        $crate::private_parse_poly_trait! {
1044            $caller
1045            poly_trait = [{ $($poly_trait)* }]
1046            tokens = [{ $($tokens)* }]
1047            _tokens = [{ $($tokens)* }]
1048        }
1049    };
1050
1051    // Parse angle bracketed lifetimes of poly trait.
1052    {
1053        $caller:tt
1054        poly_trait = [{ $for:tt }]
1055        tokens = [{ < $($rest:tt)+ }]
1056        _tokens = [{ $lt:tt $($dup:tt)* }]
1057    } => {
1058        $crate::tt_call! {
1059            macro = [{ $crate::private_parse_lifetime_params }]
1060            input = [{ $($rest)* }]
1061            ~~> $crate::private_parse_poly_trait! {
1062                $caller
1063                poly_trait = [{ $for $lt }]
1064            }
1065        }
1066    };
1067
1068    // Unexpected: failed to find angle bracketed lifetimes.
1069    {
1070        $caller:tt
1071        poly_trait = [{ $for:tt }]
1072        tokens = [{ $($unexpected:tt)+ }]
1073        _tokens = [{ $($dup:tt)* }]
1074    } => {
1075        $crate::error_unexpected! {
1076            $($unexpected)*
1077        }
1078    };
1079
1080    // Return from parsing angle bracketed lifetimes. Parse rest of type.
1081    {
1082        $caller:tt
1083        poly_trait = [{ $for:tt $lt:tt }]
1084        lifetime_params = [{ $($params:tt)* }]
1085        rest = [{ $gt:tt $($rest:tt)+ }]
1086    } => {
1087        $crate::tt_call! {
1088            macro = [{ $crate::parse_type }]
1089            input = [{ $($rest)* }]
1090            ~~> $crate::private_parse_poly_trait! {
1091                $caller
1092                poly_trait = [{ $for $lt $($params)* $gt }]
1093            }
1094        }
1095    };
1096
1097    // Unexpected: input ends with `for<...>`.
1098    {
1099        $caller:tt
1100        poly_trait = [{ $for:tt $lt:tt }]
1101        lifetime_params = [{ $($params:tt)* }]
1102        rest = [{ $gt:tt }]
1103    } => {
1104        $crate::error_unexpected! {
1105            $gt
1106        }
1107    };
1108
1109    // Return from parsing complete poly trait type.
1110    {
1111        $caller:tt
1112        poly_trait = [{ $($params:tt)* }]
1113        type = [{ $($ty:tt)* }]
1114        rest = [{ $($rest:tt)* }]
1115    } => {
1116        $crate::tt_return! {
1117            $caller
1118            type = [{ $($params)* $($ty)* }]
1119            rest = [{ $($rest)* }]
1120        }
1121    };
1122}
1123
1124#[doc(hidden)]
1125#[macro_export]
1126macro_rules! private_parse_lifetime_params {
1127    // Entry point after parsing `<`. Dup tokens.
1128    {
1129        $caller:tt
1130        input = [{ $($input:tt)* }]
1131    } => {
1132        $crate::private_parse_lifetime_params! {
1133            $caller
1134            lifetime_params = [{ }]
1135            mode = [{ < }]
1136            tokens = [{ $($input)* }]
1137            _tokens = [{ $($input)* }]
1138        }
1139    };
1140
1141    // Found `>`. Return lifetimes.
1142    {
1143        $caller:tt
1144        lifetime_params = [{ $($params:tt)* }]
1145        mode = [{ $any:tt }]
1146        tokens = [{ > $($rest:tt)* }]
1147        _tokens = [{ $gt:tt $($dup:tt)* }]
1148    } => {
1149        $crate::tt_return! {
1150            $caller
1151            lifetime_params = [{ $($params)* }]
1152            rest = [{ $gt $($rest)* }]
1153        }
1154    };
1155
1156    // Found lifetime.
1157    {
1158        $caller:tt
1159        lifetime_params = [{ $($params:tt)* }]
1160        mode = [{ < }]
1161        tokens = [{ $lifetime:lifetime $($rest:tt)+ }]
1162        _tokens = [{ $($dup:tt)* }]
1163    } => {
1164        $crate::private_parse_lifetime_params! {
1165            $caller
1166            lifetime_params = [{ $($params)* $lifetime }]
1167            mode = [{ 'a }]
1168            tokens = [{ $($rest)* }]
1169            _tokens = [{ $($rest)* }]
1170        }
1171    };
1172
1173    // Found colon after lifetime.
1174    {
1175        $caller:tt
1176        lifetime_params = [{ $($params:tt)* }]
1177        mode = [{ 'a }]
1178        tokens = [{ : $($rest:tt)+ }]
1179        _tokens = [{ $colon:tt $($dup:tt)* }]
1180    } => {
1181        $crate::private_parse_lifetime_params! {
1182            $caller
1183            lifetime_params = [{ $($params)* $colon }]
1184            mode = [{ : }]
1185            tokens = [{ $($rest)* }]
1186            _tokens = [{ $($rest)* }]
1187        }
1188    };
1189
1190    // Found comma after lifetime.
1191    {
1192        $caller:tt
1193        lifetime_params = [{ $($params:tt)* }]
1194        mode = [{ 'a }]
1195        tokens = [{ , $($rest:tt)+ }]
1196        _tokens = [{ $comma:tt $($dup:tt)* }]
1197    } => {
1198        $crate::private_parse_lifetime_params! {
1199            $caller
1200            lifetime_params = [{ $($params)* $comma }]
1201            mode = [{ < }]
1202            tokens = [{ $($rest)* }]
1203            _tokens = [{ $($rest)* }]
1204        }
1205    };
1206
1207    // Expect comma after colon, because lifetime bounds cannot be used in poly
1208    // trait.
1209    {
1210        $caller:tt
1211        lifetime_params = [{ $($params:tt)* }]
1212        mode = [{ : }]
1213        tokens = [{ , $($rest:tt)+ }]
1214        _tokens = [{ $comma:tt $($dup:tt)* }]
1215    } => {
1216        $crate::private_parse_lifetime_params! {
1217            $caller
1218            lifetime_params = [{ $($params)* $comma }]
1219            mode = [{ < }]
1220            tokens = [{ $($rest)* }]
1221            _tokens = [{ $($rest)* }]
1222        }
1223    };
1224
1225    // Unexpected: any other token.
1226    {
1227        $caller:tt
1228        lifetime_params = [{ $($params:tt)* }]
1229        mode = [{ $any:tt }]
1230        tokens = [{ $($unexpected:tt)+ }]
1231        _tokens = [{ $($dup:tt)* }]
1232    } => {
1233        $crate::error_unexpected! {
1234            $($unexpected)*
1235        }
1236    };
1237}
1238
1239#[doc(hidden)]
1240#[macro_export]
1241macro_rules! private_validate_inside_brackets {
1242    // Entry point. Parse content of brackets as type.
1243    {
1244        $caller:tt
1245        original = [{ $original:tt }]
1246        input = [{ $($input:tt)+ }]
1247    } => {
1248        $crate::tt_call! {
1249            macro = [{ $crate::parse_type }]
1250            input = [{ $($input)* }]
1251            ~~> $crate::private_validate_inside_brackets! {
1252                $caller
1253                original = [{ $original }]
1254            }
1255        }
1256    };
1257
1258    // Brackets contain only a type. Valid slice type.
1259    {
1260        $caller:tt
1261        original = [{ $original:tt }]
1262        type = [{ $($bracketed:tt)* }]
1263        rest = [{ }]
1264    } => {
1265        $crate::tt_return! {
1266            $caller
1267        }
1268    };
1269
1270    // Bracketed tokens are followed by semicolon. Parse expression.
1271    {
1272        $caller:tt
1273        original = [{ $original:tt }]
1274        type = [{ $($element:tt)* }]
1275        rest = [{ ; $($len:tt)+ }]
1276    } => {
1277        $crate::tt_call! {
1278            macro = [{ $crate::private_parse_expr }]
1279            input = [{ $($len)* }]
1280            ~~> $crate::private_validate_inside_brackets! {
1281                $caller
1282            }
1283        }
1284    };
1285
1286    // Unexpected: bracketed tokens end with semicolon: `[... ; ]`.
1287    {
1288        $caller:tt
1289        original = [{ $original:tt }]
1290        type = [{ $($element:tt)* }]
1291        rest = [{ ; }]
1292    } => {
1293        $crate::private_unexpected_close_square_bracket_after_ty_semicolon! {
1294            $original
1295        }
1296    };
1297
1298    // Unexpected: type is followed by something other than a semicolon.
1299    {
1300        $caller:tt
1301        original = [{ $original:tt }]
1302        type = [{ $($element:tt)* }]
1303        rest = [{ $($unexpected:tt)* }]
1304    } => {
1305        $crate::error_unexpected! {
1306            $($unexpected)*
1307        }
1308    };
1309
1310    // Brackets contain a type, semicolon, and expression. Valid array type.
1311    {
1312        $caller:tt
1313        expr = [{ $($len:tt)* }]
1314        rest = [{ }]
1315    } => {
1316        $crate::tt_return! {
1317            $caller
1318        }
1319    };
1320
1321    // Unexpected: remaining tokens after array length expression.
1322    {
1323        $caller:tt
1324        expr = [{ $($len:tt)* }]
1325        rest = [{ $($unexpected:tt)+ }]
1326    } => {
1327        $crate::error_unexpected! {
1328            $($unexpected)*
1329        }
1330    };
1331}
1332
1333#[doc(hidden)]
1334#[macro_export]
1335macro_rules! private_validate_inside_parens {
1336    // Entry point. Parentheses are empty.
1337    {
1338        $caller:tt
1339        input = [{ }]
1340    } => {
1341        $crate::tt_return! {
1342            $caller
1343        }
1344    };
1345
1346    // Entry point. Parse the first element as a type allowing plus.
1347    {
1348        $caller:tt
1349        input = [{ $($tokens:tt)+ }]
1350    } => {
1351        $crate::tt_call! {
1352            macro = [{ $crate::private_parse_type_with_plus }]
1353            input = [{ $($tokens)* }]
1354            ~~> $crate::private_validate_inside_parens! {
1355                $caller
1356            }
1357        }
1358    };
1359
1360    // Parentheses contain valid types.
1361    {
1362        $caller:tt
1363        type = [{ $($element:tt)* }]
1364        rest = [{ }]
1365    } => {
1366        $crate::tt_return! {
1367            $caller
1368        }
1369    };
1370
1371    // Parentheses contain valid types with trailing comma.
1372    {
1373        $caller:tt
1374        type = [{ $($element:tt)* }]
1375        rest = [{ , }]
1376    } => {
1377        $crate::tt_return! {
1378            $caller
1379        }
1380    };
1381
1382    // Parse the next type after comma.
1383    {
1384        $caller:tt
1385        type = [{ $($element:tt)* }]
1386        rest = [{ , $($rest:tt)+ }]
1387    } => {
1388        $crate::tt_call! {
1389            macro = [{ $crate::parse_type }]
1390            input = [{ $($rest)* }]
1391            ~~> $crate::private_validate_inside_parens! {
1392                $caller
1393            }
1394        }
1395    };
1396
1397    // Unexpected: parenthesized type is not followed by comma.
1398    {
1399        $caller:tt
1400        type = [{ $($element:tt)* }]
1401        rest = [{ $($unexpected:tt)* }]
1402    } => {
1403        $crate::error_unexpected! {
1404            $($unexpected)*
1405        }
1406    };
1407}
1408
1409#[doc(hidden)]
1410#[macro_export]
1411macro_rules! private_validate_fn_args {
1412    // Entry point. Dup tokens.
1413    {
1414        $caller:tt
1415        input = [{ $($input:tt)* }]
1416    } => {
1417        $crate::private_validate_fn_args! {
1418            $caller
1419            tokens = [{ $($input)* }]
1420            _tokens = [{ $($input)* }]
1421        }
1422    };
1423
1424    // Function arguments are valid.
1425    {
1426        $caller:tt
1427        tokens = [{ }]
1428        _tokens = [{ }]
1429    } => {
1430        $crate::tt_return! {
1431            $caller
1432        }
1433    };
1434
1435    // Parse type of an underscore named argument.
1436    {
1437        $caller:tt
1438        tokens = [{ _ : $($rest:tt)+ }]
1439        _tokens = [{ $($dup:tt)* }]
1440    } => {
1441        $crate::tt_call! {
1442            macro = [{ $crate::parse_type }]
1443            input = [{ $($rest)* }]
1444            ~~> $crate::private_validate_fn_args! {
1445                $caller
1446            }
1447        }
1448    };
1449
1450    // Unexpected: end of arguments after underscore colon.
1451    {
1452        $caller:tt
1453        tokens = [{ _ : }]
1454        _tokens = [{ $skip:tt $colon:tt }]
1455    } => {
1456        $crate::error_unexpected! {
1457            $colon
1458        }
1459    };
1460
1461    // Parse type of a named argument.
1462    {
1463        $caller:tt
1464        tokens = [{ $name:ident : $($rest:tt)+ }]
1465        _tokens = [{ $($dup:tt)* }]
1466    } => {
1467        $crate::tt_call! {
1468            macro = [{ $crate::parse_type }]
1469            input = [{ $($rest)* }]
1470            ~~> $crate::private_validate_fn_args! {
1471                $caller
1472            }
1473        }
1474    };
1475
1476    // Unexpected: end of arguments after ident colon.
1477    {
1478        $caller:tt
1479        tokens = [{ $name:ident : }]
1480        _tokens = [{ $skip:tt $colon:tt }]
1481    } => {
1482        $crate::error_unexpected! {
1483            $colon
1484        }
1485    };
1486
1487    // Parse type of an unnamed argument.
1488    {
1489        $caller:tt
1490        tokens = [{ $($rest:tt)+ }]
1491        _tokens = [{ $($dup:tt)* }]
1492    } => {
1493        $crate::tt_call! {
1494            macro = [{ $crate::parse_type }]
1495            input = [{ $($rest)* }]
1496            ~~> $crate::private_validate_fn_args! {
1497                $caller
1498            }
1499        }
1500    };
1501
1502    // Validated last function argument.
1503    {
1504        $caller:tt
1505        type = [{ $($ty:tt)* }]
1506        rest = [{ }]
1507    } => {
1508        $crate::tt_return! {
1509            $caller
1510        }
1511    };
1512
1513    // Validate next argument after comma.
1514    {
1515        $caller:tt
1516        type = [{ $($ty:tt)* }]
1517        rest = [{ , $($rest:tt)* }]
1518    } => {
1519        $crate::private_validate_fn_args! {
1520            $caller
1521            input = [{ $($rest)* }]
1522        }
1523    };
1524
1525    // Unexpected: function argument is followed by something other than comma.
1526    {
1527        $caller:tt
1528        type = [{ $($ty:tt)* }]
1529        rest = [{ $($unexpected:tt)+ }]
1530    } => {
1531        $crate::error_unexpected! {
1532            $($unexpected)*
1533        }
1534    };
1535}