syn_pub_items/
ty.rs

1use super::*;
2use proc_macro2::TokenStream;
3use punctuated::Punctuated;
4#[cfg(feature = "extra-traits")]
5use std::hash::{Hash, Hasher};
6#[cfg(feature = "extra-traits")]
7use tt::TokenStreamHelper;
8
9ast_enum_of_structs! {
10    /// The possible types that a Rust value could have.
11    ///
12    /// *This type is available if Syn is built with the `"derive"` or `"full"`
13    /// feature.*
14    ///
15    /// # Syntax tree enum
16    ///
17    /// This type is a [syntax tree enum].
18    ///
19    /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
20    pub enum Type {
21        /// A dynamically sized slice type: `[T]`.
22        ///
23        /// *This type is available if Syn is built with the `"derive"` or
24        /// `"full"` feature.*
25        pub Slice(TypeSlice {
26            pub bracket_token: token::Bracket,
27            pub elem: Box<Type>,
28        }),
29
30        /// A fixed size array type: `[T; n]`.
31        ///
32        /// *This type is available if Syn is built with the `"derive"` or
33        /// `"full"` feature.*
34        pub Array(TypeArray {
35            pub bracket_token: token::Bracket,
36            pub elem: Box<Type>,
37            pub semi_token: Token![;],
38            pub len: Expr,
39        }),
40
41        /// A raw pointer type: `*const T` or `*mut T`.
42        ///
43        /// *This type is available if Syn is built with the `"derive"` or
44        /// `"full"` feature.*
45        pub Ptr(TypePtr {
46            pub star_token: Token![*],
47            pub const_token: Option<Token![const]>,
48            pub mutability: Option<Token![mut]>,
49            pub elem: Box<Type>,
50        }),
51
52        /// A reference type: `&'a T` or `&'a mut T`.
53        ///
54        /// *This type is available if Syn is built with the `"derive"` or
55        /// `"full"` feature.*
56        pub Reference(TypeReference {
57            pub and_token: Token![&],
58            pub lifetime: Option<Lifetime>,
59            pub mutability: Option<Token![mut]>,
60            pub elem: Box<Type>,
61        }),
62
63        /// A bare function type: `fn(usize) -> bool`.
64        ///
65        /// *This type is available if Syn is built with the `"derive"` or
66        /// `"full"` feature.*
67        pub BareFn(TypeBareFn {
68            pub lifetimes: Option<BoundLifetimes>,
69            pub unsafety: Option<Token![unsafe]>,
70            pub abi: Option<Abi>,
71            pub fn_token: Token![fn],
72            pub paren_token: token::Paren,
73            pub inputs: Punctuated<BareFnArg, Token![,]>,
74            pub variadic: Option<Token![...]>,
75            pub output: ReturnType,
76        }),
77
78        /// The never type: `!`.
79        ///
80        /// *This type is available if Syn is built with the `"derive"` or
81        /// `"full"` feature.*
82        pub Never(TypeNever {
83            pub bang_token: Token![!],
84        }),
85
86        /// A tuple type: `(A, B, C, String)`.
87        ///
88        /// *This type is available if Syn is built with the `"derive"` or
89        /// `"full"` feature.*
90        pub Tuple(TypeTuple {
91            pub paren_token: token::Paren,
92            pub elems: Punctuated<Type, Token![,]>,
93        }),
94
95        /// A path like `std::slice::Iter`, optionally qualified with a
96        /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
97        ///
98        /// Type arguments are stored in the Path itself.
99        ///
100        /// *This type is available if Syn is built with the `"derive"` or
101        /// `"full"` feature.*
102        pub Path(TypePath {
103            pub qself: Option<QSelf>,
104            pub path: Path,
105        }),
106
107        /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a
108        /// trait or a lifetime.
109        ///
110        /// *This type is available if Syn is built with the `"derive"` or
111        /// `"full"` feature.*
112        pub TraitObject(TypeTraitObject {
113            pub dyn_token: Option<Token![dyn]>,
114            pub bounds: Punctuated<TypeParamBound, Token![+]>,
115        }),
116
117        /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
118        /// a lifetime.
119        ///
120        /// *This type is available if Syn is built with the `"derive"` or
121        /// `"full"` feature.*
122        pub ImplTrait(TypeImplTrait {
123            pub impl_token: Token![impl],
124            pub bounds: Punctuated<TypeParamBound, Token![+]>,
125        }),
126
127        /// A parenthesized type equivalent to the inner type.
128        ///
129        /// *This type is available if Syn is built with the `"derive"` or
130        /// `"full"` feature.*
131        pub Paren(TypeParen {
132            pub paren_token: token::Paren,
133            pub elem: Box<Type>,
134        }),
135
136        /// A type contained within invisible delimiters.
137        ///
138        /// *This type is available if Syn is built with the `"derive"` or
139        /// `"full"` feature.*
140        pub Group(TypeGroup {
141            pub group_token: token::Group,
142            pub elem: Box<Type>,
143        }),
144
145        /// Indication that a type should be inferred by the compiler: `_`.
146        ///
147        /// *This type is available if Syn is built with the `"derive"` or
148        /// `"full"` feature.*
149        pub Infer(TypeInfer {
150            pub underscore_token: Token![_],
151        }),
152
153        /// A macro in the type position.
154        ///
155        /// *This type is available if Syn is built with the `"derive"` or
156        /// `"full"` feature.*
157        pub Macro(TypeMacro {
158            pub mac: Macro,
159        }),
160
161        /// Tokens in type position not interpreted by Syn.
162        ///
163        /// *This type is available if Syn is built with the `"derive"` or
164        /// `"full"` feature.*
165        pub Verbatim(TypeVerbatim #manual_extra_traits {
166            pub tts: TokenStream,
167        }),
168    }
169}
170
171#[cfg(feature = "extra-traits")]
172impl Eq for TypeVerbatim {}
173
174#[cfg(feature = "extra-traits")]
175impl PartialEq for TypeVerbatim {
176    fn eq(&self, other: &Self) -> bool {
177        TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
178    }
179}
180
181#[cfg(feature = "extra-traits")]
182impl Hash for TypeVerbatim {
183    fn hash<H>(&self, state: &mut H)
184    where
185        H: Hasher,
186    {
187        TokenStreamHelper(&self.tts).hash(state);
188    }
189}
190
191ast_struct! {
192    /// The binary interface of a function: `extern "C"`.
193    ///
194    /// *This type is available if Syn is built with the `"derive"` or `"full"`
195    /// feature.*
196    pub struct Abi {
197        pub extern_token: Token![extern],
198        pub name: Option<LitStr>,
199    }
200}
201
202ast_struct! {
203    /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
204    ///
205    /// *This type is available if Syn is built with the `"derive"` or `"full"`
206    /// feature.*
207    pub struct BareFnArg {
208        pub name: Option<(BareFnArgName, Token![:])>,
209        pub ty: Type,
210    }
211}
212
213ast_enum! {
214    /// Name of an argument in a function type: the `n` in `fn(n: usize)`.
215    ///
216    /// *This type is available if Syn is built with the `"derive"` or `"full"`
217    /// feature.*
218    pub enum BareFnArgName {
219        /// Argument given a name.
220        Named(Ident),
221        /// Argument not given a name, matched with `_`.
222        Wild(Token![_]),
223    }
224}
225
226ast_enum! {
227    /// Return type of a function signature.
228    ///
229    /// *This type is available if Syn is built with the `"derive"` or `"full"`
230    /// feature.*
231    pub enum ReturnType {
232        /// Return type is not specified.
233        ///
234        /// Functions default to `()` and closures default to type inference.
235        Default,
236        /// A particular type is returned.
237        Type(Token![->], Box<Type>),
238    }
239}
240
241#[cfg(feature = "parsing")]
242pub mod parsing {
243    use super::*;
244
245    use parse::{Parse, ParseStream, Result};
246    use path;
247
248    impl Parse for Type {
249        fn parse(input: ParseStream) -> Result<Self> {
250            ambig_ty(input, true)
251        }
252    }
253
254    impl Type {
255        /// In some positions, types may not contain the `+` character, to
256        /// disambiguate them. For example in the expression `1 as T`, T may not
257        /// contain a `+` character.
258        ///
259        /// This parser does not allow a `+`, while the default parser does.
260        pub fn without_plus(input: ParseStream) -> Result<Self> {
261            ambig_ty(input, false)
262        }
263    }
264
265    fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
266        if input.peek(token::Group) {
267            return input.parse().map(Type::Group);
268        }
269
270        let mut lifetimes = None::<BoundLifetimes>;
271        let mut lookahead = input.lookahead1();
272        if lookahead.peek(Token![for]) {
273            lifetimes = input.parse()?;
274            lookahead = input.lookahead1();
275            if !lookahead.peek(Ident)
276                && !lookahead.peek(Token![fn])
277                && !lookahead.peek(Token![unsafe])
278                && !lookahead.peek(Token![extern])
279                && !lookahead.peek(Token![super])
280                && !lookahead.peek(Token![self])
281                && !lookahead.peek(Token![Self])
282                && !lookahead.peek(Token![crate])
283            {
284                return Err(lookahead.error());
285            }
286        }
287
288        if lookahead.peek(token::Paren) {
289            let content;
290            let paren_token = parenthesized!(content in input);
291            if content.is_empty() {
292                return Ok(Type::Tuple(TypeTuple {
293                    paren_token: paren_token,
294                    elems: Punctuated::new(),
295                }));
296            }
297            if content.peek(Lifetime) {
298                return Ok(Type::Paren(TypeParen {
299                    paren_token: paren_token,
300                    elem: Box::new(Type::TraitObject(content.parse()?)),
301                }));
302            }
303            if content.peek(Token![?]) {
304                return Ok(Type::TraitObject(TypeTraitObject {
305                    dyn_token: None,
306                    bounds: {
307                        let mut bounds = Punctuated::new();
308                        bounds.push_value(TypeParamBound::Trait(TraitBound {
309                            paren_token: Some(paren_token),
310                            ..content.parse()?
311                        }));
312                        while let Some(plus) = input.parse()? {
313                            bounds.push_punct(plus);
314                            bounds.push_value(input.parse()?);
315                        }
316                        bounds
317                    },
318                }));
319            }
320            let first: Type = content.parse()?;
321            if content.peek(Token![,]) {
322                return Ok(Type::Tuple(TypeTuple {
323                    paren_token: paren_token,
324                    elems: {
325                        let mut elems = Punctuated::new();
326                        elems.push_value(first);
327                        elems.push_punct(content.parse()?);
328                        let rest: Punctuated<Type, Token![,]> =
329                            content.parse_terminated(Parse::parse)?;
330                        elems.extend(rest);
331                        elems
332                    },
333                }));
334            }
335            if allow_plus && input.peek(Token![+]) {
336                loop {
337                    let first = match first {
338                        Type::Path(TypePath { qself: None, path }) => {
339                            TypeParamBound::Trait(TraitBound {
340                                paren_token: Some(paren_token),
341                                modifier: TraitBoundModifier::None,
342                                lifetimes: None,
343                                path: path,
344                            })
345                        }
346                        Type::TraitObject(TypeTraitObject {
347                            dyn_token: None,
348                            ref bounds,
349                        }) => {
350                            if bounds.len() > 1 || bounds.trailing_punct() {
351                                break;
352                            }
353                            match first {
354                                Type::TraitObject(TypeTraitObject { bounds, .. }) => {
355                                    match bounds.into_iter().next().unwrap() {
356                                        TypeParamBound::Trait(trait_bound) => {
357                                            TypeParamBound::Trait(TraitBound {
358                                                paren_token: Some(paren_token),
359                                                ..trait_bound
360                                            })
361                                        }
362                                        other => other,
363                                    }
364                                }
365                                _ => unreachable!(),
366                            }
367                        }
368                        _ => break,
369                    };
370                    return Ok(Type::TraitObject(TypeTraitObject {
371                        dyn_token: None,
372                        bounds: {
373                            let mut bounds = Punctuated::new();
374                            bounds.push_value(first);
375                            while let Some(plus) = input.parse()? {
376                                bounds.push_punct(plus);
377                                bounds.push_value(input.parse()?);
378                            }
379                            bounds
380                        },
381                    }));
382                }
383            }
384            Ok(Type::Paren(TypeParen {
385                paren_token: paren_token,
386                elem: Box::new(first),
387            }))
388        } else if lookahead.peek(Token![fn])
389            || lookahead.peek(Token![unsafe])
390            || lookahead.peek(Token![extern]) && !input.peek2(Token![::])
391        {
392            let mut bare_fn: TypeBareFn = input.parse()?;
393            bare_fn.lifetimes = lifetimes;
394            Ok(Type::BareFn(bare_fn))
395        } else if lookahead.peek(Ident)
396            || input.peek(Token![super])
397            || input.peek(Token![self])
398            || input.peek(Token![Self])
399            || input.peek(Token![crate])
400            || input.peek(Token![extern])
401            || lookahead.peek(Token![::])
402            || lookahead.peek(Token![<])
403        {
404            if input.peek(Token![dyn]) {
405                let mut trait_object: TypeTraitObject = input.parse()?;
406                if lifetimes.is_some() {
407                    match *trait_object.bounds.iter_mut().next().unwrap() {
408                        TypeParamBound::Trait(ref mut trait_bound) => {
409                            trait_bound.lifetimes = lifetimes;
410                        }
411                        TypeParamBound::Lifetime(_) => unreachable!(),
412                    }
413                }
414                return Ok(Type::TraitObject(trait_object));
415            }
416
417            let ty: TypePath = input.parse()?;
418            if ty.qself.is_some() {
419                return Ok(Type::Path(ty));
420            }
421
422            if input.peek(Token![!]) && !input.peek(Token![!=]) {
423                let mut contains_arguments = false;
424                for segment in &ty.path.segments {
425                    match segment.arguments {
426                        PathArguments::None => {}
427                        PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
428                            contains_arguments = true;
429                        }
430                    }
431                }
432
433                if !contains_arguments {
434                    let bang_token: Token![!] = input.parse()?;
435                    let (delimiter, tts) = mac::parse_delimiter(input)?;
436                    return Ok(Type::Macro(TypeMacro {
437                        mac: Macro {
438                            path: ty.path,
439                            bang_token: bang_token,
440                            delimiter: delimiter,
441                            tts: tts,
442                        },
443                    }));
444                }
445            }
446
447            if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
448                let mut bounds = Punctuated::new();
449                bounds.push_value(TypeParamBound::Trait(TraitBound {
450                    paren_token: None,
451                    modifier: TraitBoundModifier::None,
452                    lifetimes: lifetimes,
453                    path: ty.path,
454                }));
455                if allow_plus {
456                    while input.peek(Token![+]) {
457                        bounds.push_punct(input.parse()?);
458                        if input.peek(Token![>]) {
459                            break;
460                        }
461                        bounds.push_value(input.parse()?);
462                    }
463                }
464                return Ok(Type::TraitObject(TypeTraitObject {
465                    dyn_token: None,
466                    bounds: bounds,
467                }));
468            }
469
470            Ok(Type::Path(ty))
471        } else if lookahead.peek(token::Bracket) {
472            let content;
473            let bracket_token = bracketed!(content in input);
474            let elem: Type = content.parse()?;
475            if content.peek(Token![;]) {
476                Ok(Type::Array(TypeArray {
477                    bracket_token: bracket_token,
478                    elem: Box::new(elem),
479                    semi_token: content.parse()?,
480                    len: content.parse()?,
481                }))
482            } else {
483                Ok(Type::Slice(TypeSlice {
484                    bracket_token: bracket_token,
485                    elem: Box::new(elem),
486                }))
487            }
488        } else if lookahead.peek(Token![*]) {
489            input.parse().map(Type::Ptr)
490        } else if lookahead.peek(Token![&]) {
491            input.parse().map(Type::Reference)
492        } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
493            input.parse().map(Type::Never)
494        } else if lookahead.peek(Token![impl]) {
495            input.parse().map(Type::ImplTrait)
496        } else if lookahead.peek(Token![_]) {
497            input.parse().map(Type::Infer)
498        } else if lookahead.peek(Lifetime) {
499            input.parse().map(Type::TraitObject)
500        } else {
501            Err(lookahead.error())
502        }
503    }
504
505    impl Parse for TypeSlice {
506        fn parse(input: ParseStream) -> Result<Self> {
507            let content;
508            Ok(TypeSlice {
509                bracket_token: bracketed!(content in input),
510                elem: content.parse()?,
511            })
512        }
513    }
514
515    impl Parse for TypeArray {
516        fn parse(input: ParseStream) -> Result<Self> {
517            let content;
518            Ok(TypeArray {
519                bracket_token: bracketed!(content in input),
520                elem: content.parse()?,
521                semi_token: content.parse()?,
522                len: content.parse()?,
523            })
524        }
525    }
526
527    impl Parse for TypePtr {
528        fn parse(input: ParseStream) -> Result<Self> {
529            let star_token: Token![*] = input.parse()?;
530
531            let lookahead = input.lookahead1();
532            let (const_token, mutability) = if lookahead.peek(Token![const]) {
533                (Some(input.parse()?), None)
534            } else if lookahead.peek(Token![mut]) {
535                (None, Some(input.parse()?))
536            } else {
537                return Err(lookahead.error());
538            };
539
540            Ok(TypePtr {
541                star_token: star_token,
542                const_token: const_token,
543                mutability: mutability,
544                elem: Box::new(input.call(Type::without_plus)?),
545            })
546        }
547    }
548
549    impl Parse for TypeReference {
550        fn parse(input: ParseStream) -> Result<Self> {
551            Ok(TypeReference {
552                and_token: input.parse()?,
553                lifetime: input.parse()?,
554                mutability: input.parse()?,
555                // & binds tighter than +, so we don't allow + here.
556                elem: Box::new(input.call(Type::without_plus)?),
557            })
558        }
559    }
560
561    impl Parse for TypeBareFn {
562        fn parse(input: ParseStream) -> Result<Self> {
563            let args;
564            let allow_variadic;
565            Ok(TypeBareFn {
566                lifetimes: input.parse()?,
567                unsafety: input.parse()?,
568                abi: input.parse()?,
569                fn_token: input.parse()?,
570                paren_token: parenthesized!(args in input),
571                inputs: {
572                    let mut inputs = Punctuated::new();
573                    while !args.is_empty() && !args.peek(Token![...]) {
574                        inputs.push_value(args.parse()?);
575                        if args.is_empty() {
576                            break;
577                        }
578                        inputs.push_punct(args.parse()?);
579                    }
580                    allow_variadic = inputs.empty_or_trailing();
581                    inputs
582                },
583                variadic: {
584                    if allow_variadic && args.peek(Token![...]) {
585                        Some(args.parse()?)
586                    } else {
587                        None
588                    }
589                },
590                output: input.call(ReturnType::without_plus)?,
591            })
592        }
593    }
594
595    impl Parse for TypeNever {
596        fn parse(input: ParseStream) -> Result<Self> {
597            Ok(TypeNever {
598                bang_token: input.parse()?,
599            })
600        }
601    }
602
603    impl Parse for TypeInfer {
604        fn parse(input: ParseStream) -> Result<Self> {
605            Ok(TypeInfer {
606                underscore_token: input.parse()?,
607            })
608        }
609    }
610
611    impl Parse for TypeTuple {
612        fn parse(input: ParseStream) -> Result<Self> {
613            let content;
614            Ok(TypeTuple {
615                paren_token: parenthesized!(content in input),
616                elems: content.parse_terminated(Type::parse)?,
617            })
618        }
619    }
620
621    impl Parse for TypeMacro {
622        fn parse(input: ParseStream) -> Result<Self> {
623            Ok(TypeMacro {
624                mac: input.parse()?,
625            })
626        }
627    }
628
629    impl Parse for TypePath {
630        fn parse(input: ParseStream) -> Result<Self> {
631            let (qself, mut path) = path::parsing::qpath(input, false)?;
632
633            if path.segments.last().unwrap().value().arguments.is_empty()
634                && input.peek(token::Paren)
635            {
636                let args: ParenthesizedGenericArguments = input.parse()?;
637                let parenthesized = PathArguments::Parenthesized(args);
638                path.segments.last_mut().unwrap().value_mut().arguments = parenthesized;
639            }
640
641            Ok(TypePath {
642                qself: qself,
643                path: path,
644            })
645        }
646    }
647
648    impl ReturnType {
649        pub fn without_plus(input: ParseStream) -> Result<Self> {
650            Self::parse(input, false)
651        }
652
653        pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
654            if input.peek(Token![->]) {
655                let arrow = input.parse()?;
656                let ty = ambig_ty(input, allow_plus)?;
657                Ok(ReturnType::Type(arrow, Box::new(ty)))
658            } else {
659                Ok(ReturnType::Default)
660            }
661        }
662    }
663
664    impl Parse for ReturnType {
665        fn parse(input: ParseStream) -> Result<Self> {
666            Self::parse(input, true)
667        }
668    }
669
670    impl Parse for TypeTraitObject {
671        fn parse(input: ParseStream) -> Result<Self> {
672            Self::parse(input, true)
673        }
674    }
675
676    fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
677        for bound in bounds {
678            if let TypeParamBound::Trait(_) = *bound {
679                return true;
680            }
681        }
682        false
683    }
684
685    impl TypeTraitObject {
686        pub fn without_plus(input: ParseStream) -> Result<Self> {
687            Self::parse(input, false)
688        }
689
690        // Only allow multiple trait references if allow_plus is true.
691        pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
692            Ok(TypeTraitObject {
693                dyn_token: input.parse()?,
694                bounds: {
695                    let mut bounds = Punctuated::new();
696                    if allow_plus {
697                        loop {
698                            bounds.push_value(input.parse()?);
699                            if !input.peek(Token![+]) {
700                                break;
701                            }
702                            bounds.push_punct(input.parse()?);
703                            if input.peek(Token![>]) {
704                                break;
705                            }
706                        }
707                    } else {
708                        bounds.push_value(input.parse()?);
709                    }
710                    // Just lifetimes like `'a + 'b` is not a TraitObject.
711                    if !at_least_one_type(&bounds) {
712                        return Err(input.error("expected at least one type"));
713                    }
714                    bounds
715                },
716            })
717        }
718    }
719
720    impl Parse for TypeImplTrait {
721        fn parse(input: ParseStream) -> Result<Self> {
722            Ok(TypeImplTrait {
723                impl_token: input.parse()?,
724                // NOTE: rust-lang/rust#34511 includes discussion about whether
725                // or not + should be allowed in ImplTrait directly without ().
726                bounds: {
727                    let mut bounds = Punctuated::new();
728                    loop {
729                        bounds.push_value(input.parse()?);
730                        if !input.peek(Token![+]) {
731                            break;
732                        }
733                        bounds.push_punct(input.parse()?);
734                    }
735                    bounds
736                },
737            })
738        }
739    }
740
741    impl Parse for TypeGroup {
742        fn parse(input: ParseStream) -> Result<Self> {
743            let group = private::parse_group(input)?;
744            Ok(TypeGroup {
745                group_token: group.token,
746                elem: group.content.parse()?,
747            })
748        }
749    }
750
751    impl Parse for TypeParen {
752        fn parse(input: ParseStream) -> Result<Self> {
753            Self::parse(input, false)
754        }
755    }
756
757    impl TypeParen {
758        fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
759            let content;
760            Ok(TypeParen {
761                paren_token: parenthesized!(content in input),
762                elem: Box::new(ambig_ty(&content, allow_plus)?),
763            })
764        }
765    }
766
767    impl Parse for BareFnArg {
768        fn parse(input: ParseStream) -> Result<Self> {
769            Ok(BareFnArg {
770                name: {
771                    if (input.peek(Ident) || input.peek(Token![_]))
772                        && !input.peek2(Token![::])
773                        && input.peek2(Token![:])
774                    {
775                        let name: BareFnArgName = input.parse()?;
776                        let colon: Token![:] = input.parse()?;
777                        Some((name, colon))
778                    } else {
779                        None
780                    }
781                },
782                ty: input.parse()?,
783            })
784        }
785    }
786
787    impl Parse for BareFnArgName {
788        fn parse(input: ParseStream) -> Result<Self> {
789            let lookahead = input.lookahead1();
790            if lookahead.peek(Ident) {
791                input.parse().map(BareFnArgName::Named)
792            } else if lookahead.peek(Token![_]) {
793                input.parse().map(BareFnArgName::Wild)
794            } else {
795                Err(lookahead.error())
796            }
797        }
798    }
799
800    impl Parse for Abi {
801        fn parse(input: ParseStream) -> Result<Self> {
802            Ok(Abi {
803                extern_token: input.parse()?,
804                name: input.parse()?,
805            })
806        }
807    }
808
809    impl Parse for Option<Abi> {
810        fn parse(input: ParseStream) -> Result<Self> {
811            if input.peek(Token![extern]) {
812                input.parse().map(Some)
813            } else {
814                Ok(None)
815            }
816        }
817    }
818}
819
820#[cfg(feature = "printing")]
821mod printing {
822    use super::*;
823
824    use proc_macro2::TokenStream;
825    use quote::ToTokens;
826
827    use print::TokensOrDefault;
828
829    impl ToTokens for TypeSlice {
830        fn to_tokens(&self, tokens: &mut TokenStream) {
831            self.bracket_token.surround(tokens, |tokens| {
832                self.elem.to_tokens(tokens);
833            });
834        }
835    }
836
837    impl ToTokens for TypeArray {
838        fn to_tokens(&self, tokens: &mut TokenStream) {
839            self.bracket_token.surround(tokens, |tokens| {
840                self.elem.to_tokens(tokens);
841                self.semi_token.to_tokens(tokens);
842                self.len.to_tokens(tokens);
843            });
844        }
845    }
846
847    impl ToTokens for TypePtr {
848        fn to_tokens(&self, tokens: &mut TokenStream) {
849            self.star_token.to_tokens(tokens);
850            match self.mutability {
851                Some(ref tok) => tok.to_tokens(tokens),
852                None => {
853                    TokensOrDefault(&self.const_token).to_tokens(tokens);
854                }
855            }
856            self.elem.to_tokens(tokens);
857        }
858    }
859
860    impl ToTokens for TypeReference {
861        fn to_tokens(&self, tokens: &mut TokenStream) {
862            self.and_token.to_tokens(tokens);
863            self.lifetime.to_tokens(tokens);
864            self.mutability.to_tokens(tokens);
865            self.elem.to_tokens(tokens);
866        }
867    }
868
869    impl ToTokens for TypeBareFn {
870        fn to_tokens(&self, tokens: &mut TokenStream) {
871            self.lifetimes.to_tokens(tokens);
872            self.unsafety.to_tokens(tokens);
873            self.abi.to_tokens(tokens);
874            self.fn_token.to_tokens(tokens);
875            self.paren_token.surround(tokens, |tokens| {
876                self.inputs.to_tokens(tokens);
877                if let Some(ref variadic) = self.variadic {
878                    if !self.inputs.empty_or_trailing() {
879                        let span = variadic.spans[0];
880                        Token![,](span).to_tokens(tokens);
881                    }
882                    variadic.to_tokens(tokens);
883                }
884            });
885            self.output.to_tokens(tokens);
886        }
887    }
888
889    impl ToTokens for TypeNever {
890        fn to_tokens(&self, tokens: &mut TokenStream) {
891            self.bang_token.to_tokens(tokens);
892        }
893    }
894
895    impl ToTokens for TypeTuple {
896        fn to_tokens(&self, tokens: &mut TokenStream) {
897            self.paren_token.surround(tokens, |tokens| {
898                self.elems.to_tokens(tokens);
899            });
900        }
901    }
902
903    impl ToTokens for TypePath {
904        fn to_tokens(&self, tokens: &mut TokenStream) {
905            private::print_path(tokens, &self.qself, &self.path);
906        }
907    }
908
909    impl ToTokens for TypeTraitObject {
910        fn to_tokens(&self, tokens: &mut TokenStream) {
911            self.dyn_token.to_tokens(tokens);
912            self.bounds.to_tokens(tokens);
913        }
914    }
915
916    impl ToTokens for TypeImplTrait {
917        fn to_tokens(&self, tokens: &mut TokenStream) {
918            self.impl_token.to_tokens(tokens);
919            self.bounds.to_tokens(tokens);
920        }
921    }
922
923    impl ToTokens for TypeGroup {
924        fn to_tokens(&self, tokens: &mut TokenStream) {
925            self.group_token.surround(tokens, |tokens| {
926                self.elem.to_tokens(tokens);
927            });
928        }
929    }
930
931    impl ToTokens for TypeParen {
932        fn to_tokens(&self, tokens: &mut TokenStream) {
933            self.paren_token.surround(tokens, |tokens| {
934                self.elem.to_tokens(tokens);
935            });
936        }
937    }
938
939    impl ToTokens for TypeInfer {
940        fn to_tokens(&self, tokens: &mut TokenStream) {
941            self.underscore_token.to_tokens(tokens);
942        }
943    }
944
945    impl ToTokens for TypeMacro {
946        fn to_tokens(&self, tokens: &mut TokenStream) {
947            self.mac.to_tokens(tokens);
948        }
949    }
950
951    impl ToTokens for TypeVerbatim {
952        fn to_tokens(&self, tokens: &mut TokenStream) {
953            self.tts.to_tokens(tokens);
954        }
955    }
956
957    impl ToTokens for ReturnType {
958        fn to_tokens(&self, tokens: &mut TokenStream) {
959            match *self {
960                ReturnType::Default => {}
961                ReturnType::Type(ref arrow, ref ty) => {
962                    arrow.to_tokens(tokens);
963                    ty.to_tokens(tokens);
964                }
965            }
966        }
967    }
968
969    impl ToTokens for BareFnArg {
970        fn to_tokens(&self, tokens: &mut TokenStream) {
971            if let Some((ref name, ref colon)) = self.name {
972                name.to_tokens(tokens);
973                colon.to_tokens(tokens);
974            }
975            self.ty.to_tokens(tokens);
976        }
977    }
978
979    impl ToTokens for BareFnArgName {
980        fn to_tokens(&self, tokens: &mut TokenStream) {
981            match *self {
982                BareFnArgName::Named(ref t) => t.to_tokens(tokens),
983                BareFnArgName::Wild(ref t) => t.to_tokens(tokens),
984            }
985        }
986    }
987
988    impl ToTokens for Abi {
989        fn to_tokens(&self, tokens: &mut TokenStream) {
990            self.extern_token.to_tokens(tokens);
991            self.name.to_tokens(tokens);
992        }
993    }
994}