syn/
ty.rs

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