syn/
ty.rs

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