1 // Copyright 2018 Syn Developers
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8 
9 use super::*;
10 use proc_macro2::TokenStream;
11 use punctuated::Punctuated;
12 #[cfg(feature = "extra-traits")]
13 use std::hash::{Hash, Hasher};
14 #[cfg(feature = "extra-traits")]
15 use tt::TokenStreamHelper;
16 
17 ast_enum_of_structs! {
18     /// The possible types that a Rust value could have.
19     ///
20     /// *This type is available if Syn is built with the `"derive"` or `"full"`
21     /// feature.*
22     ///
23     /// # Syntax tree enum
24     ///
25     /// This type is a [syntax tree enum].
26     ///
27     /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
28     pub enum Type {
29         /// A dynamically sized slice type: `[T]`.
30         ///
31         /// *This type is available if Syn is built with the `"derive"` or
32         /// `"full"` feature.*
33         pub Slice(TypeSlice {
34             pub bracket_token: token::Bracket,
35             pub elem: Box<Type>,
36         }),
37 
38         /// A fixed size array type: `[T; n]`.
39         ///
40         /// *This type is available if Syn is built with the `"derive"` or
41         /// `"full"` feature.*
42         pub Array(TypeArray {
43             pub bracket_token: token::Bracket,
44             pub elem: Box<Type>,
45             pub semi_token: Token![;],
46             pub len: Expr,
47         }),
48 
49         /// A raw pointer type: `*const T` or `*mut T`.
50         ///
51         /// *This type is available if Syn is built with the `"derive"` or
52         /// `"full"` feature.*
53         pub Ptr(TypePtr {
54             pub star_token: Token![*],
55             pub const_token: Option<Token![const]>,
56             pub mutability: Option<Token![mut]>,
57             pub elem: Box<Type>,
58         }),
59 
60         /// A reference type: `&'a T` or `&'a mut T`.
61         ///
62         /// *This type is available if Syn is built with the `"derive"` or
63         /// `"full"` feature.*
64         pub Reference(TypeReference {
65             pub and_token: Token![&],
66             pub lifetime: Option<Lifetime>,
67             pub mutability: Option<Token![mut]>,
68             pub elem: Box<Type>,
69         }),
70 
71         /// A bare function type: `fn(usize) -> bool`.
72         ///
73         /// *This type is available if Syn is built with the `"derive"` or
74         /// `"full"` feature.*
75         pub BareFn(TypeBareFn {
76             pub unsafety: Option<Token![unsafe]>,
77             pub abi: Option<Abi>,
78             pub fn_token: Token![fn],
79             pub lifetimes: Option<BoundLifetimes>,
80             pub paren_token: token::Paren,
81             pub inputs: Punctuated<BareFnArg, Token![,]>,
82             pub variadic: Option<Token![...]>,
83             pub output: ReturnType,
84         }),
85 
86         /// The never type: `!`.
87         ///
88         /// *This type is available if Syn is built with the `"derive"` or
89         /// `"full"` feature.*
90         pub Never(TypeNever {
91             pub bang_token: Token![!],
92         }),
93 
94         /// A tuple type: `(A, B, C, String)`.
95         ///
96         /// *This type is available if Syn is built with the `"derive"` or
97         /// `"full"` feature.*
98         pub Tuple(TypeTuple {
99             pub paren_token: token::Paren,
100             pub elems: Punctuated<Type, Token![,]>,
101         }),
102 
103         /// A path like `std::slice::Iter`, optionally qualified with a
104         /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
105         ///
106         /// Type arguments are stored in the Path itself.
107         ///
108         /// *This type is available if Syn is built with the `"derive"` or
109         /// `"full"` feature.*
110         pub Path(TypePath {
111             pub qself: Option<QSelf>,
112             pub path: Path,
113         }),
114 
115         /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
116         /// trait or a lifetime.
117         ///
118         /// *This type is available if Syn is built with the `"derive"` or
119         /// `"full"` feature.*
120         pub TraitObject(TypeTraitObject {
121             pub dyn_token: Option<Token![dyn]>,
122             pub bounds: Punctuated<TypeParamBound, Token![+]>,
123         }),
124 
125         /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
126         /// a lifetime.
127         ///
128         /// *This type is available if Syn is built with the `"derive"` or
129         /// `"full"` feature.*
130         pub ImplTrait(TypeImplTrait {
131             pub impl_token: Token![impl],
132             pub bounds: Punctuated<TypeParamBound, Token![+]>,
133         }),
134 
135         /// A parenthesized type equivalent to the inner type.
136         ///
137         /// *This type is available if Syn is built with the `"derive"` or
138         /// `"full"` feature.*
139         pub Paren(TypeParen {
140             pub paren_token: token::Paren,
141             pub elem: Box<Type>,
142         }),
143 
144         /// A type contained within invisible delimiters.
145         ///
146         /// *This type is available if Syn is built with the `"derive"` or
147         /// `"full"` feature.*
148         pub Group(TypeGroup {
149             pub group_token: token::Group,
150             pub elem: Box<Type>,
151         }),
152 
153         /// Indication that a type should be inferred by the compiler: `_`.
154         ///
155         /// *This type is available if Syn is built with the `"derive"` or
156         /// `"full"` feature.*
157         pub Infer(TypeInfer {
158             pub underscore_token: Token![_],
159         }),
160 
161         /// A macro in the type position.
162         ///
163         /// *This type is available if Syn is built with the `"derive"` or
164         /// `"full"` feature.*
165         pub Macro(TypeMacro {
166             pub mac: Macro,
167         }),
168 
169         /// Tokens in type position not interpreted by Syn.
170         ///
171         /// *This type is available if Syn is built with the `"derive"` or
172         /// `"full"` feature.*
173         pub Verbatim(TypeVerbatim #manual_extra_traits {
174             pub tts: TokenStream,
175         }),
176     }
177 }
178 
179 #[cfg(feature = "extra-traits")]
180 impl Eq for TypeVerbatim {}
181 
182 #[cfg(feature = "extra-traits")]
183 impl PartialEq for TypeVerbatim {
eq(&self, other: &Self) -> bool184     fn eq(&self, other: &Self) -> bool {
185         TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
186     }
187 }
188 
189 #[cfg(feature = "extra-traits")]
190 impl Hash for TypeVerbatim {
hash<H>(&self, state: &mut H) where H: Hasher,191     fn hash<H>(&self, state: &mut H)
192     where
193         H: Hasher,
194     {
195         TokenStreamHelper(&self.tts).hash(state);
196     }
197 }
198 
199 ast_struct! {
200     /// The binary interface of a function: `extern "C"`.
201     ///
202     /// *This type is available if Syn is built with the `"derive"` or `"full"`
203     /// feature.*
204     pub struct Abi {
205         pub extern_token: Token![extern],
206         pub name: Option<LitStr>,
207     }
208 }
209 
210 ast_struct! {
211     /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
212     ///
213     /// *This type is available if Syn is built with the `"derive"` or `"full"`
214     /// feature.*
215     pub struct BareFnArg {
216         pub name: Option<(BareFnArgName, Token![:])>,
217         pub ty: Type,
218     }
219 }
220 
221 ast_enum! {
222     /// Name of an argument in a function type: the `n` in `fn(n: usize)`.
223     ///
224     /// *This type is available if Syn is built with the `"derive"` or `"full"`
225     /// feature.*
226     pub enum BareFnArgName {
227         /// Argument given a name.
228         Named(Ident),
229         /// Argument not given a name, matched with `_`.
230         Wild(Token![_]),
231     }
232 }
233 
234 ast_enum! {
235     /// Return type of a function signature.
236     ///
237     /// *This type is available if Syn is built with the `"derive"` or `"full"`
238     /// feature.*
239     pub enum ReturnType {
240         /// Return type is not specified.
241         ///
242         /// Functions default to `()` and closures default to type inference.
243         Default,
244         /// A particular type is returned.
245         Type(Token![->], Box<Type>),
246     }
247 }
248 
249 #[cfg(feature = "parsing")]
250 pub mod parsing {
251     use super::*;
252     use path::parsing::qpath;
253     use synom::Synom;
254 
255     impl Synom for Type {
256         named!(parse -> Self, call!(ambig_ty, true));
257 
description() -> Option<&'static str>258         fn description() -> Option<&'static str> {
259             Some("type")
260         }
261     }
262 
263     impl Type {
264         /// In some positions, types may not contain the `+` character, to
265         /// disambiguate them. For example in the expression `1 as T`, T may not
266         /// contain a `+` character.
267         ///
268         /// This parser does not allow a `+`, while the default parser does.
269         named!(pub without_plus -> Self, call!(ambig_ty, false));
270     }
271 
272     named!(ambig_ty(allow_plus: bool) -> Type, alt!(
273         syn!(TypeGroup) => { Type::Group }
274         |
275         // must be before TypeTuple
276         call!(TypeParen::parse, allow_plus) => { Type::Paren }
277         |
278         // must be before TypePath
279         syn!(TypeMacro) => { Type::Macro }
280         |
281         // must be before TypeTraitObject
282         call!(TypePath::parse, allow_plus) => { Type::Path }
283         |
284         // Don't try parsing more than one trait bound if we aren't allowing it.
285         // must be before TypeTuple
286         call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject }
287         |
288         syn!(TypeSlice) => { Type::Slice }
289         |
290         syn!(TypeArray) => { Type::Array }
291         |
292         syn!(TypePtr) => { Type::Ptr }
293         |
294         syn!(TypeReference) => { Type::Reference }
295         |
296         syn!(TypeBareFn) => { Type::BareFn }
297         |
298         syn!(TypeNever) => { Type::Never }
299         |
300         syn!(TypeTuple) => { Type::Tuple }
301         |
302         syn!(TypeImplTrait) => { Type::ImplTrait }
303         |
304         syn!(TypeInfer) => { Type::Infer }
305     ));
306 
307     impl Synom for TypeSlice {
308         named!(parse -> Self, map!(
309             brackets!(syn!(Type)),
310             |(b, ty)| TypeSlice {
311                 elem: Box::new(ty),
312                 bracket_token: b,
313             }
314         ));
315 
description() -> Option<&'static str>316         fn description() -> Option<&'static str> {
317             Some("slice type")
318         }
319     }
320 
321     impl Synom for TypeArray {
322         named!(parse -> Self, map!(
323             brackets!(do_parse!(
324                 elem: syn!(Type) >>
325                     semi: punct!(;) >>
326                     len: syn!(Expr) >>
327                     (elem, semi, len)
328             )),
329             |(brackets, (elem, semi, len))| {
330                 TypeArray {
331                     elem: Box::new(elem),
332                     len: len,
333                     bracket_token: brackets,
334                     semi_token: semi,
335                 }
336             }
337         ));
338 
description() -> Option<&'static str>339         fn description() -> Option<&'static str> {
340             Some("array type")
341         }
342     }
343 
344     impl Synom for TypePtr {
345         named!(parse -> Self, do_parse!(
346             star: punct!(*) >>
347             mutability: alt!(
348                 keyword!(const) => { |c| (None, Some(c)) }
349                 |
350                 keyword!(mut) => { |m| (Some(m), None) }
351             ) >>
352             target: call!(Type::without_plus) >>
353             (TypePtr {
354                 const_token: mutability.1,
355                 star_token: star,
356                 mutability: mutability.0,
357                 elem: Box::new(target),
358             })
359         ));
360 
description() -> Option<&'static str>361         fn description() -> Option<&'static str> {
362             Some("raw pointer type")
363         }
364     }
365 
366     impl Synom for TypeReference {
367         named!(parse -> Self, do_parse!(
368             amp: punct!(&) >>
369             life: option!(syn!(Lifetime)) >>
370             mutability: option!(keyword!(mut)) >>
371             // & binds tighter than +, so we don't allow + here.
372             target: call!(Type::without_plus) >>
373             (TypeReference {
374                 lifetime: life,
375                 mutability: mutability,
376                 elem: Box::new(target),
377                 and_token: amp,
378             })
379         ));
380 
description() -> Option<&'static str>381         fn description() -> Option<&'static str> {
382             Some("reference type")
383         }
384     }
385 
386     impl Synom for TypeBareFn {
387         named!(parse -> Self, do_parse!(
388             lifetimes: option!(syn!(BoundLifetimes)) >>
389             unsafety: option!(keyword!(unsafe)) >>
390             abi: option!(syn!(Abi)) >>
391             fn_: keyword!(fn) >>
392             parens: parens!(do_parse!(
393                 inputs: call!(Punctuated::parse_terminated) >>
394                 variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >>
395                 (inputs, variadic)
396             )) >>
397             output: syn!(ReturnType) >>
398             (TypeBareFn {
399                 unsafety: unsafety,
400                 abi: abi,
401                 lifetimes: lifetimes,
402                 output: output,
403                 variadic: (parens.1).1,
404                 fn_token: fn_,
405                 paren_token: parens.0,
406                 inputs: (parens.1).0,
407             })
408         ));
409 
description() -> Option<&'static str>410         fn description() -> Option<&'static str> {
411             Some("`fn` type")
412         }
413     }
414 
415     impl Synom for TypeNever {
416         named!(parse -> Self, map!(
417             punct!(!),
418             |b| TypeNever { bang_token: b }
419         ));
420 
description() -> Option<&'static str>421         fn description() -> Option<&'static str> {
422             Some("never type: `!`")
423         }
424     }
425 
426     impl Synom for TypeInfer {
427         named!(parse -> Self, map!(
428             punct!(_),
429             |u| TypeInfer { underscore_token: u }
430         ));
431 
description() -> Option<&'static str>432         fn description() -> Option<&'static str> {
433             Some("inferred type: `_`")
434         }
435     }
436 
437     impl Synom for TypeTuple {
438         named!(parse -> Self, do_parse!(
439             data: parens!(Punctuated::parse_terminated) >>
440             (TypeTuple {
441                 paren_token: data.0,
442                 elems: data.1,
443             })
444         ));
445 
description() -> Option<&'static str>446         fn description() -> Option<&'static str> {
447             Some("tuple type")
448         }
449     }
450 
451     impl Synom for TypeMacro {
452         named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac }));
453 
description() -> Option<&'static str>454         fn description() -> Option<&'static str> {
455             Some("macro invocation")
456         }
457     }
458 
459     impl Synom for TypePath {
460         named!(parse -> Self, call!(Self::parse, false));
461 
description() -> Option<&'static str>462         fn description() -> Option<&'static str> {
463             Some("type path")
464         }
465     }
466 
467     impl TypePath {
468         named!(parse(allow_plus: bool) -> Self, do_parse!(
469             qpath: qpath >>
470             parenthesized: option!(cond_reduce!(
471                 qpath.1.segments.last().unwrap().value().arguments.is_empty(),
472                 syn!(ParenthesizedGenericArguments)
473             )) >>
474             cond!(allow_plus, not!(punct!(+))) >>
475             ({
476                 let (qself, mut path) = qpath;
477                 if let Some(parenthesized) = parenthesized {
478                     let parenthesized = PathArguments::Parenthesized(parenthesized);
479                     path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
480                 }
481                 TypePath { qself: qself, path: path }
482             })
483         ));
484     }
485 
486     impl Synom for ReturnType {
487         named!(parse -> Self, alt!(
488             do_parse!(
489                 arrow: punct!(->) >>
490                 ty: syn!(Type) >>
491                 (ReturnType::Type(arrow, Box::new(ty)))
492             )
493             |
494             epsilon!() => { |_| ReturnType::Default }
495         ));
496 
description() -> Option<&'static str>497         fn description() -> Option<&'static str> {
498             Some("return type")
499         }
500     }
501 
502     impl Synom for TypeTraitObject {
503         named!(parse -> Self, call!(Self::parse, true));
504 
description() -> Option<&'static str>505         fn description() -> Option<&'static str> {
506             Some("trait object type")
507         }
508     }
509 
at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool510     fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
511         for bound in bounds {
512             if let TypeParamBound::Trait(_) = *bound {
513                 return true;
514             }
515         }
516         false
517     }
518 
519     impl TypeTraitObject {
520         named!(pub without_plus -> Self, call!(Self::parse, false));
521 
522         // Only allow multiple trait references if allow_plus is true.
523         named!(parse(allow_plus: bool) -> Self, do_parse!(
524             dyn_token: option!(keyword!(dyn)) >>
525             bounds: alt!(
526                 cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty)
527                 |
528                 syn!(TypeParamBound) => {|x| {
529                     let mut bounds = Punctuated::new();
530                     bounds.push_value(x);
531                     bounds
532                 }}
533             ) >>
534             // Just lifetimes like `'a + 'b` is not a TraitObject.
535             cond_reduce!(at_least_one_type(&bounds)) >>
536             (TypeTraitObject {
537                 dyn_token: dyn_token,
538                 bounds: bounds,
539             })
540         ));
541     }
542 
543     impl Synom for TypeImplTrait {
544         named!(parse -> Self, do_parse!(
545             impl_: keyword!(impl) >>
546             // NOTE: rust-lang/rust#34511 includes discussion about whether or
547             // not + should be allowed in ImplTrait directly without ().
548             elem: call!(Punctuated::parse_terminated_nonempty) >>
549             (TypeImplTrait {
550                 impl_token: impl_,
551                 bounds: elem,
552             })
553         ));
554 
description() -> Option<&'static str>555         fn description() -> Option<&'static str> {
556             Some("`impl Trait` type")
557         }
558     }
559 
560     impl Synom for TypeGroup {
561         named!(parse -> Self, do_parse!(
562             data: grouped!(syn!(Type)) >>
563             (TypeGroup {
564                 group_token: data.0,
565                 elem: Box::new(data.1),
566             })
567         ));
568 
description() -> Option<&'static str>569         fn description() -> Option<&'static str> {
570             Some("type surrounded by invisible delimiters")
571         }
572     }
573 
574     impl Synom for TypeParen {
575         named!(parse -> Self, call!(Self::parse, false));
576 
description() -> Option<&'static str>577         fn description() -> Option<&'static str> {
578             Some("parenthesized type")
579         }
580     }
581 
582     impl TypeParen {
583         named!(parse(allow_plus: bool) -> Self, do_parse!(
584             data: parens!(syn!(Type)) >>
585             cond!(allow_plus, not!(punct!(+))) >>
586             (TypeParen {
587                 paren_token: data.0,
588                 elem: Box::new(data.1),
589             })
590         ));
591     }
592 
593     impl Synom for BareFnArg {
594         named!(parse -> Self, do_parse!(
595             name: option!(do_parse!(
596                 name: syn!(BareFnArgName) >>
597                 not!(punct!(::)) >>
598                 colon: punct!(:) >>
599                 (name, colon)
600             )) >>
601             ty: syn!(Type) >>
602             (BareFnArg {
603                 name: name,
604                 ty: ty,
605             })
606         ));
607 
description() -> Option<&'static str>608         fn description() -> Option<&'static str> {
609             Some("function type argument")
610         }
611     }
612 
613     impl Synom for BareFnArgName {
614         named!(parse -> Self, alt!(
615             map!(syn!(Ident), BareFnArgName::Named)
616             |
617             map!(punct!(_), BareFnArgName::Wild)
618         ));
619 
description() -> Option<&'static str>620         fn description() -> Option<&'static str> {
621             Some("function argument name")
622         }
623     }
624 
625     impl Synom for Abi {
626         named!(parse -> Self, do_parse!(
627             extern_: keyword!(extern) >>
628             name: option!(syn!(LitStr)) >>
629             (Abi {
630                 extern_token: extern_,
631                 name: name,
632             })
633         ));
634 
description() -> Option<&'static str>635         fn description() -> Option<&'static str> {
636             Some("`extern` ABI qualifier")
637         }
638     }
639 }
640 
641 #[cfg(feature = "printing")]
642 mod printing {
643     use super::*;
644     use quote::{ToTokens, Tokens};
645 
646     impl ToTokens for TypeSlice {
to_tokens(&self, tokens: &mut Tokens)647         fn to_tokens(&self, tokens: &mut Tokens) {
648             self.bracket_token.surround(tokens, |tokens| {
649                 self.elem.to_tokens(tokens);
650             });
651         }
652     }
653 
654     impl ToTokens for TypeArray {
to_tokens(&self, tokens: &mut Tokens)655         fn to_tokens(&self, tokens: &mut Tokens) {
656             self.bracket_token.surround(tokens, |tokens| {
657                 self.elem.to_tokens(tokens);
658                 self.semi_token.to_tokens(tokens);
659                 self.len.to_tokens(tokens);
660             });
661         }
662     }
663 
664     impl ToTokens for TypePtr {
to_tokens(&self, tokens: &mut Tokens)665         fn to_tokens(&self, tokens: &mut Tokens) {
666             self.star_token.to_tokens(tokens);
667             match self.mutability {
668                 Some(ref tok) => tok.to_tokens(tokens),
669                 None => {
670                     TokensOrDefault(&self.const_token).to_tokens(tokens);
671                 }
672             }
673             self.elem.to_tokens(tokens);
674         }
675     }
676 
677     impl ToTokens for TypeReference {
to_tokens(&self, tokens: &mut Tokens)678         fn to_tokens(&self, tokens: &mut Tokens) {
679             self.and_token.to_tokens(tokens);
680             self.lifetime.to_tokens(tokens);
681             self.mutability.to_tokens(tokens);
682             self.elem.to_tokens(tokens);
683         }
684     }
685 
686     impl ToTokens for TypeBareFn {
to_tokens(&self, tokens: &mut Tokens)687         fn to_tokens(&self, tokens: &mut Tokens) {
688             self.lifetimes.to_tokens(tokens);
689             self.unsafety.to_tokens(tokens);
690             self.abi.to_tokens(tokens);
691             self.fn_token.to_tokens(tokens);
692             self.paren_token.surround(tokens, |tokens| {
693                 self.inputs.to_tokens(tokens);
694                 if let Some(ref variadic) = self.variadic {
695                     if !self.inputs.empty_or_trailing() {
696                         let span = variadic.0[0];
697                         <Token![,]>::new(span).to_tokens(tokens);
698                     }
699                     variadic.to_tokens(tokens);
700                 }
701             });
702             self.output.to_tokens(tokens);
703         }
704     }
705 
706     impl ToTokens for TypeNever {
to_tokens(&self, tokens: &mut Tokens)707         fn to_tokens(&self, tokens: &mut Tokens) {
708             self.bang_token.to_tokens(tokens);
709         }
710     }
711 
712     impl ToTokens for TypeTuple {
to_tokens(&self, tokens: &mut Tokens)713         fn to_tokens(&self, tokens: &mut Tokens) {
714             self.paren_token.surround(tokens, |tokens| {
715                 self.elems.to_tokens(tokens);
716             });
717         }
718     }
719 
720     impl ToTokens for TypePath {
to_tokens(&self, tokens: &mut Tokens)721         fn to_tokens(&self, tokens: &mut Tokens) {
722             PathTokens(&self.qself, &self.path).to_tokens(tokens);
723         }
724     }
725 
726     impl ToTokens for TypeTraitObject {
to_tokens(&self, tokens: &mut Tokens)727         fn to_tokens(&self, tokens: &mut Tokens) {
728             self.dyn_token.to_tokens(tokens);
729             self.bounds.to_tokens(tokens);
730         }
731     }
732 
733     impl ToTokens for TypeImplTrait {
to_tokens(&self, tokens: &mut Tokens)734         fn to_tokens(&self, tokens: &mut Tokens) {
735             self.impl_token.to_tokens(tokens);
736             self.bounds.to_tokens(tokens);
737         }
738     }
739 
740     impl ToTokens for TypeGroup {
to_tokens(&self, tokens: &mut Tokens)741         fn to_tokens(&self, tokens: &mut Tokens) {
742             self.group_token.surround(tokens, |tokens| {
743                 self.elem.to_tokens(tokens);
744             });
745         }
746     }
747 
748     impl ToTokens for TypeParen {
to_tokens(&self, tokens: &mut Tokens)749         fn to_tokens(&self, tokens: &mut Tokens) {
750             self.paren_token.surround(tokens, |tokens| {
751                 self.elem.to_tokens(tokens);
752             });
753         }
754     }
755 
756     impl ToTokens for TypeInfer {
to_tokens(&self, tokens: &mut Tokens)757         fn to_tokens(&self, tokens: &mut Tokens) {
758             self.underscore_token.to_tokens(tokens);
759         }
760     }
761 
762     impl ToTokens for TypeMacro {
to_tokens(&self, tokens: &mut Tokens)763         fn to_tokens(&self, tokens: &mut Tokens) {
764             self.mac.to_tokens(tokens);
765         }
766     }
767 
768     impl ToTokens for TypeVerbatim {
to_tokens(&self, tokens: &mut Tokens)769         fn to_tokens(&self, tokens: &mut Tokens) {
770             self.tts.to_tokens(tokens);
771         }
772     }
773 
774     impl ToTokens for ReturnType {
to_tokens(&self, tokens: &mut Tokens)775         fn to_tokens(&self, tokens: &mut Tokens) {
776             match *self {
777                 ReturnType::Default => {}
778                 ReturnType::Type(ref arrow, ref ty) => {
779                     arrow.to_tokens(tokens);
780                     ty.to_tokens(tokens);
781                 }
782             }
783         }
784     }
785 
786     impl ToTokens for BareFnArg {
to_tokens(&self, tokens: &mut Tokens)787         fn to_tokens(&self, tokens: &mut Tokens) {
788             if let Some((ref name, ref colon)) = self.name {
789                 name.to_tokens(tokens);
790                 colon.to_tokens(tokens);
791             }
792             self.ty.to_tokens(tokens);
793         }
794     }
795 
796     impl ToTokens for BareFnArgName {
to_tokens(&self, tokens: &mut Tokens)797         fn to_tokens(&self, tokens: &mut Tokens) {
798             match *self {
799                 BareFnArgName::Named(ref t) => t.to_tokens(tokens),
800                 BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
801             }
802         }
803     }
804 
805     impl ToTokens for Abi {
to_tokens(&self, tokens: &mut Tokens)806         fn to_tokens(&self, tokens: &mut Tokens) {
807             self.extern_token.to_tokens(tokens);
808             self.name.to_tokens(tokens);
809         }
810     }
811 }
812