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, 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            ambig_ty(input, allow_plus)
347        }
348    }
349
350    impl Type {
351        /// In some positions, types may not contain the `+` character, to
352        /// disambiguate them. For example in the expression `1 as T`, T may not
353        /// contain a `+` character.
354        ///
355        /// This parser does not allow a `+`, while the default parser does.
356        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
357        pub fn without_plus(input: ParseStream) -> Result<Self> {
358            let allow_plus = false;
359            ambig_ty(input, allow_plus)
360        }
361    }
362
363    fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> {
364        let begin = input.fork();
365
366        if input.peek(token::Group) {
367            let mut group: TypeGroup = input.parse()?;
368            if input.peek(Token![::]) && input.peek3(Ident::peek_any) {
369                if let Type::Path(mut ty) = *group.elem {
370                    Path::parse_rest(input, &mut ty.path, false)?;
371                    return Ok(Type::Path(ty));
372                } else {
373                    return Ok(Type::Path(TypePath {
374                        qself: Some(QSelf {
375                            lt_token: Token![<](group.group_token.span),
376                            position: 0,
377                            as_token: None,
378                            gt_token: Token![>](group.group_token.span),
379                            ty: group.elem,
380                        }),
381                        path: Path::parse_helper(input, false)?,
382                    }));
383                }
384            } else if input.peek(Token![<]) || input.peek(Token![::]) && input.peek3(Token![<]) {
385                if let Type::Path(mut ty) = *group.elem {
386                    let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
387                    if let PathArguments::None = arguments {
388                        *arguments = PathArguments::AngleBracketed(input.parse()?);
389                        Path::parse_rest(input, &mut ty.path, false)?;
390                        return Ok(Type::Path(ty));
391                    } else {
392                        group.elem = Box::new(Type::Path(ty));
393                    }
394                }
395            }
396            return Ok(Type::Group(group));
397        }
398
399        let mut lifetimes = None::<BoundLifetimes>;
400        let mut lookahead = input.lookahead1();
401        if lookahead.peek(Token![for]) {
402            lifetimes = input.parse()?;
403            lookahead = input.lookahead1();
404            if !lookahead.peek(Ident)
405                && !lookahead.peek(Token![fn])
406                && !lookahead.peek(Token![unsafe])
407                && !lookahead.peek(Token![extern])
408                && !lookahead.peek(Token![super])
409                && !lookahead.peek(Token![self])
410                && !lookahead.peek(Token![Self])
411                && !lookahead.peek(Token![crate])
412                || input.peek(Token![dyn])
413            {
414                return Err(lookahead.error());
415            }
416        }
417
418        if lookahead.peek(token::Paren) {
419            let content;
420            let paren_token = parenthesized!(content in input);
421            if content.is_empty() {
422                return Ok(Type::Tuple(TypeTuple {
423                    paren_token,
424                    elems: Punctuated::new(),
425                }));
426            }
427            if content.peek(Lifetime) {
428                return Ok(Type::Paren(TypeParen {
429                    paren_token,
430                    elem: Box::new(Type::TraitObject(content.parse()?)),
431                }));
432            }
433            if content.peek(Token![?]) {
434                return Ok(Type::TraitObject(TypeTraitObject {
435                    dyn_token: None,
436                    bounds: {
437                        let mut bounds = Punctuated::new();
438                        bounds.push_value(TypeParamBound::Trait(TraitBound {
439                            paren_token: Some(paren_token),
440                            ..content.parse()?
441                        }));
442                        while let Some(plus) = input.parse()? {
443                            bounds.push_punct(plus);
444                            bounds.push_value(input.parse()?);
445                        }
446                        bounds
447                    },
448                }));
449            }
450            let mut first: Type = content.parse()?;
451            if content.peek(Token![,]) {
452                return Ok(Type::Tuple(TypeTuple {
453                    paren_token,
454                    elems: {
455                        let mut elems = Punctuated::new();
456                        elems.push_value(first);
457                        elems.push_punct(content.parse()?);
458                        while !content.is_empty() {
459                            elems.push_value(content.parse()?);
460                            if content.is_empty() {
461                                break;
462                            }
463                            elems.push_punct(content.parse()?);
464                        }
465                        elems
466                    },
467                }));
468            }
469            if allow_plus && input.peek(Token![+]) {
470                loop {
471                    let first = match first {
472                        Type::Path(TypePath { qself: None, path }) => {
473                            TypeParamBound::Trait(TraitBound {
474                                paren_token: Some(paren_token),
475                                modifier: TraitBoundModifier::None,
476                                lifetimes: None,
477                                path,
478                            })
479                        }
480                        Type::TraitObject(TypeTraitObject {
481                            dyn_token: None,
482                            bounds,
483                        }) => {
484                            if bounds.len() > 1 || bounds.trailing_punct() {
485                                first = Type::TraitObject(TypeTraitObject {
486                                    dyn_token: None,
487                                    bounds,
488                                });
489                                break;
490                            }
491                            match bounds.into_iter().next().unwrap() {
492                                TypeParamBound::Trait(trait_bound) => {
493                                    TypeParamBound::Trait(TraitBound {
494                                        paren_token: Some(paren_token),
495                                        ..trait_bound
496                                    })
497                                }
498                                other @ TypeParamBound::Lifetime(_) => other,
499                            }
500                        }
501                        _ => break,
502                    };
503                    return Ok(Type::TraitObject(TypeTraitObject {
504                        dyn_token: None,
505                        bounds: {
506                            let mut bounds = Punctuated::new();
507                            bounds.push_value(first);
508                            while let Some(plus) = input.parse()? {
509                                bounds.push_punct(plus);
510                                bounds.push_value(input.parse()?);
511                            }
512                            bounds
513                        },
514                    }));
515                }
516            }
517            Ok(Type::Paren(TypeParen {
518                paren_token,
519                elem: Box::new(first),
520            }))
521        } else if lookahead.peek(Token![fn])
522            || lookahead.peek(Token![unsafe])
523            || lookahead.peek(Token![extern])
524        {
525            let allow_mut_self = true;
526            if let Some(mut bare_fn) = parse_bare_fn(input, allow_mut_self)? {
527                bare_fn.lifetimes = lifetimes;
528                Ok(Type::BareFn(bare_fn))
529            } else {
530                Ok(Type::Verbatim(verbatim::between(begin, input)))
531            }
532        } else if lookahead.peek(Ident)
533            || input.peek(Token![super])
534            || input.peek(Token![self])
535            || input.peek(Token![Self])
536            || input.peek(Token![crate])
537            || lookahead.peek(Token![::])
538            || lookahead.peek(Token![<])
539        {
540            let dyn_token: Option<Token![dyn]> = input.parse()?;
541            if dyn_token.is_some() {
542                let star_token: Option<Token![*]> = input.parse()?;
543                let bounds = TypeTraitObject::parse_bounds(input, allow_plus)?;
544                return Ok(if star_token.is_some() {
545                    Type::Verbatim(verbatim::between(begin, input))
546                } else {
547                    Type::TraitObject(TypeTraitObject { dyn_token, bounds })
548                });
549            }
550
551            let ty: TypePath = input.parse()?;
552            if ty.qself.is_some() {
553                return Ok(Type::Path(ty));
554            }
555
556            if input.peek(Token![!]) && !input.peek(Token![!=]) {
557                let mut contains_arguments = false;
558                for segment in &ty.path.segments {
559                    match segment.arguments {
560                        PathArguments::None => {}
561                        PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
562                            contains_arguments = true;
563                        }
564                    }
565                }
566
567                if !contains_arguments {
568                    let bang_token: Token![!] = input.parse()?;
569                    let (delimiter, tokens) = mac::parse_delimiter(input)?;
570                    return Ok(Type::Macro(TypeMacro {
571                        mac: Macro {
572                            path: ty.path,
573                            bang_token,
574                            delimiter,
575                            tokens,
576                        },
577                    }));
578                }
579            }
580
581            if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
582                let mut bounds = Punctuated::new();
583                bounds.push_value(TypeParamBound::Trait(TraitBound {
584                    paren_token: None,
585                    modifier: TraitBoundModifier::None,
586                    lifetimes,
587                    path: ty.path,
588                }));
589                if allow_plus {
590                    while input.peek(Token![+]) {
591                        bounds.push_punct(input.parse()?);
592                        if !(input.peek(Ident::peek_any)
593                            || input.peek(Token![::])
594                            || input.peek(Token![?])
595                            || input.peek(Lifetime)
596                            || input.peek(token::Paren))
597                        {
598                            break;
599                        }
600                        bounds.push_value(input.parse()?);
601                    }
602                }
603                return Ok(Type::TraitObject(TypeTraitObject {
604                    dyn_token: None,
605                    bounds,
606                }));
607            }
608
609            Ok(Type::Path(ty))
610        } else if lookahead.peek(token::Bracket) {
611            let content;
612            let bracket_token = bracketed!(content in input);
613            let elem: Type = content.parse()?;
614            if content.peek(Token![;]) {
615                Ok(Type::Array(TypeArray {
616                    bracket_token,
617                    elem: Box::new(elem),
618                    semi_token: content.parse()?,
619                    len: content.parse()?,
620                }))
621            } else {
622                Ok(Type::Slice(TypeSlice {
623                    bracket_token,
624                    elem: Box::new(elem),
625                }))
626            }
627        } else if lookahead.peek(Token![*]) {
628            input.parse().map(Type::Ptr)
629        } else if lookahead.peek(Token![&]) {
630            input.parse().map(Type::Reference)
631        } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
632            input.parse().map(Type::Never)
633        } else if lookahead.peek(Token![impl]) {
634            TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
635        } else if lookahead.peek(Token![_]) {
636            input.parse().map(Type::Infer)
637        } else if lookahead.peek(Lifetime) {
638            input.parse().map(Type::TraitObject)
639        } else {
640            Err(lookahead.error())
641        }
642    }
643
644    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
645    impl Parse for TypeSlice {
646        fn parse(input: ParseStream) -> Result<Self> {
647            let content;
648            Ok(TypeSlice {
649                bracket_token: bracketed!(content in input),
650                elem: content.parse()?,
651            })
652        }
653    }
654
655    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
656    impl Parse for TypeArray {
657        fn parse(input: ParseStream) -> Result<Self> {
658            let content;
659            Ok(TypeArray {
660                bracket_token: bracketed!(content in input),
661                elem: content.parse()?,
662                semi_token: content.parse()?,
663                len: content.parse()?,
664            })
665        }
666    }
667
668    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
669    impl Parse for TypePtr {
670        fn parse(input: ParseStream) -> Result<Self> {
671            let star_token: Token![*] = input.parse()?;
672
673            let lookahead = input.lookahead1();
674            let (const_token, mutability) = if lookahead.peek(Token![const]) {
675                (Some(input.parse()?), None)
676            } else if lookahead.peek(Token![mut]) {
677                (None, Some(input.parse()?))
678            } else {
679                return Err(lookahead.error());
680            };
681
682            Ok(TypePtr {
683                star_token,
684                const_token,
685                mutability,
686                elem: Box::new(input.call(Type::without_plus)?),
687            })
688        }
689    }
690
691    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
692    impl Parse for TypeReference {
693        fn parse(input: ParseStream) -> Result<Self> {
694            Ok(TypeReference {
695                and_token: input.parse()?,
696                lifetime: input.parse()?,
697                mutability: input.parse()?,
698                // & binds tighter than +, so we don't allow + here.
699                elem: Box::new(input.call(Type::without_plus)?),
700            })
701        }
702    }
703
704    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
705    impl Parse for TypeBareFn {
706        fn parse(input: ParseStream) -> Result<Self> {
707            let allow_mut_self = false;
708            parse_bare_fn(input, allow_mut_self).map(Option::unwrap)
709        }
710    }
711
712    fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> {
713        let args;
714        let mut variadic = None;
715        let mut has_mut_self = false;
716
717        let bare_fn = TypeBareFn {
718            lifetimes: input.parse()?,
719            unsafety: input.parse()?,
720            abi: input.parse()?,
721            fn_token: input.parse()?,
722            paren_token: parenthesized!(args in input),
723            inputs: {
724                let mut inputs = Punctuated::new();
725
726                while !args.is_empty() {
727                    let attrs = args.call(Attribute::parse_outer)?;
728
729                    if inputs.empty_or_trailing() && args.peek(Token![...]) {
730                        variadic = Some(Variadic {
731                            attrs,
732                            dots: args.parse()?,
733                        });
734                        break;
735                    }
736
737                    if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? {
738                        inputs.push_value(BareFnArg { attrs, ..arg });
739                    } else {
740                        has_mut_self = true;
741                    }
742                    if args.is_empty() {
743                        break;
744                    }
745
746                    let comma = args.parse()?;
747                    if !has_mut_self {
748                        inputs.push_punct(comma);
749                    }
750                }
751
752                inputs
753            },
754            variadic,
755            output: input.call(ReturnType::without_plus)?,
756        };
757
758        if has_mut_self {
759            Ok(None)
760        } else {
761            Ok(Some(bare_fn))
762        }
763    }
764
765    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
766    impl Parse for TypeNever {
767        fn parse(input: ParseStream) -> Result<Self> {
768            Ok(TypeNever {
769                bang_token: input.parse()?,
770            })
771        }
772    }
773
774    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
775    impl Parse for TypeInfer {
776        fn parse(input: ParseStream) -> Result<Self> {
777            Ok(TypeInfer {
778                underscore_token: input.parse()?,
779            })
780        }
781    }
782
783    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
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                    while !content.is_empty() {
804                        elems.push_value(content.parse()?);
805                        if content.is_empty() {
806                            break;
807                        }
808                        elems.push_punct(content.parse()?);
809                    }
810                    elems
811                },
812            })
813        }
814    }
815
816    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
817    impl Parse for TypeMacro {
818        fn parse(input: ParseStream) -> Result<Self> {
819            Ok(TypeMacro {
820                mac: input.parse()?,
821            })
822        }
823    }
824
825    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
826    impl Parse for TypePath {
827        fn parse(input: ParseStream) -> Result<Self> {
828            let expr_style = false;
829            let (qself, mut path) = path::parsing::qpath(input, expr_style)?;
830
831            while path.segments.last().unwrap().arguments.is_empty()
832                && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
833            {
834                input.parse::<Option<Token![::]>>()?;
835                let args: ParenthesizedGenericArguments = input.parse()?;
836                let allow_associated_type = cfg!(feature = "full")
837                    && match &args.output {
838                        ReturnType::Default => true,
839                        ReturnType::Type(_, ty) => match **ty {
840                            // TODO: probably some of the other kinds allow this too.
841                            Type::Paren(_) => true,
842                            _ => false,
843                        },
844                    };
845                let parenthesized = PathArguments::Parenthesized(args);
846                path.segments.last_mut().unwrap().arguments = parenthesized;
847                if allow_associated_type {
848                    Path::parse_rest(input, &mut path, expr_style)?;
849                }
850            }
851
852            Ok(TypePath { qself, path })
853        }
854    }
855
856    impl ReturnType {
857        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
858        pub fn without_plus(input: ParseStream) -> Result<Self> {
859            let allow_plus = false;
860            Self::parse(input, allow_plus)
861        }
862
863        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
864            if input.peek(Token![->]) {
865                let arrow = input.parse()?;
866                let ty = ambig_ty(input, allow_plus)?;
867                Ok(ReturnType::Type(arrow, Box::new(ty)))
868            } else {
869                Ok(ReturnType::Default)
870            }
871        }
872    }
873
874    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
875    impl Parse for ReturnType {
876        fn parse(input: ParseStream) -> Result<Self> {
877            let allow_plus = true;
878            Self::parse(input, allow_plus)
879        }
880    }
881
882    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
883    impl Parse for TypeTraitObject {
884        fn parse(input: ParseStream) -> Result<Self> {
885            let allow_plus = true;
886            Self::parse(input, allow_plus)
887        }
888    }
889
890    fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
891        for bound in bounds {
892            if let TypeParamBound::Trait(_) = *bound {
893                return true;
894            }
895        }
896        false
897    }
898
899    impl TypeTraitObject {
900        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
901        pub fn without_plus(input: ParseStream) -> Result<Self> {
902            let allow_plus = false;
903            Self::parse(input, allow_plus)
904        }
905
906        // Only allow multiple trait references if allow_plus is true.
907        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
908            Ok(TypeTraitObject {
909                dyn_token: input.parse()?,
910                bounds: Self::parse_bounds(input, allow_plus)?,
911            })
912        }
913
914        fn parse_bounds(
915            input: ParseStream,
916            allow_plus: bool,
917        ) -> Result<Punctuated<TypeParamBound, Token![+]>> {
918            let mut bounds = Punctuated::new();
919            loop {
920                bounds.push_value(input.parse()?);
921                if !(allow_plus && input.peek(Token![+])) {
922                    break;
923                }
924                bounds.push_punct(input.parse()?);
925                if !(input.peek(Ident::peek_any)
926                    || input.peek(Token![::])
927                    || input.peek(Token![?])
928                    || input.peek(Lifetime)
929                    || input.peek(token::Paren))
930                {
931                    break;
932                }
933            }
934            // Just lifetimes like `'a + 'b` is not a TraitObject.
935            if !at_least_one_type(&bounds) {
936                return Err(input.error("expected at least one type"));
937            }
938            Ok(bounds)
939        }
940    }
941
942    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
943    impl Parse for TypeImplTrait {
944        fn parse(input: ParseStream) -> Result<Self> {
945            let allow_plus = true;
946            Self::parse(input, allow_plus)
947        }
948    }
949
950    impl TypeImplTrait {
951        #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
952        pub fn without_plus(input: ParseStream) -> Result<Self> {
953            let allow_plus = false;
954            Self::parse(input, allow_plus)
955        }
956
957        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
958            Ok(TypeImplTrait {
959                impl_token: input.parse()?,
960                bounds: TypeTraitObject::parse_bounds(input, allow_plus)?,
961            })
962        }
963    }
964
965    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
966    impl Parse for TypeGroup {
967        fn parse(input: ParseStream) -> Result<Self> {
968            let group = crate::group::parse_group(input)?;
969            Ok(TypeGroup {
970                group_token: group.token,
971                elem: group.content.parse()?,
972            })
973        }
974    }
975
976    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
977    impl Parse for TypeParen {
978        fn parse(input: ParseStream) -> Result<Self> {
979            let allow_plus = false;
980            Self::parse(input, allow_plus)
981        }
982    }
983
984    impl TypeParen {
985        fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
986            let content;
987            Ok(TypeParen {
988                paren_token: parenthesized!(content in input),
989                elem: Box::new(ambig_ty(&content, allow_plus)?),
990            })
991        }
992    }
993
994    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
995    impl Parse for BareFnArg {
996        fn parse(input: ParseStream) -> Result<Self> {
997            let allow_mut_self = false;
998            parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap)
999        }
1000    }
1001
1002    fn parse_bare_fn_arg(
1003        input: ParseStream,
1004        mut allow_mut_self: bool,
1005    ) -> Result<Option<BareFnArg>> {
1006        let mut has_mut_self = false;
1007        let arg = BareFnArg {
1008            attrs: input.call(Attribute::parse_outer)?,
1009            name: {
1010                if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self]))
1011                    && input.peek2(Token![:])
1012                    && !input.peek2(Token![::])
1013                {
1014                    let name = input.call(Ident::parse_any)?;
1015                    let colon: Token![:] = input.parse()?;
1016                    Some((name, colon))
1017                } else if allow_mut_self
1018                    && input.peek(Token![mut])
1019                    && input.peek2(Token![self])
1020                    && input.peek3(Token![:])
1021                    && !input.peek3(Token![::])
1022                {
1023                    has_mut_self = true;
1024                    allow_mut_self = false;
1025                    input.parse::<Token![mut]>()?;
1026                    input.parse::<Token![self]>()?;
1027                    input.parse::<Token![:]>()?;
1028                    None
1029                } else {
1030                    None
1031                }
1032            },
1033            ty: if !has_mut_self && input.peek(Token![...]) {
1034                let dot3 = input.parse::<Token![...]>()?;
1035                let args = vec![
1036                    TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1037                    TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1038                    TokenTree::Punct(Punct::new('.', Spacing::Alone)),
1039                ];
1040                let tokens: TokenStream = args
1041                    .into_iter()
1042                    .zip(&dot3.spans)
1043                    .map(|(mut arg, span)| {
1044                        arg.set_span(*span);
1045                        arg
1046                    })
1047                    .collect();
1048                Type::Verbatim(tokens)
1049            } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) {
1050                has_mut_self = true;
1051                input.parse::<Token![mut]>()?;
1052                Type::Path(TypePath {
1053                    qself: None,
1054                    path: input.parse::<Token![self]>()?.into(),
1055                })
1056            } else {
1057                input.parse()?
1058            },
1059        };
1060
1061        if has_mut_self {
1062            Ok(None)
1063        } else {
1064            Ok(Some(arg))
1065        }
1066    }
1067
1068    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1069    impl Parse for Abi {
1070        fn parse(input: ParseStream) -> Result<Self> {
1071            Ok(Abi {
1072                extern_token: input.parse()?,
1073                name: input.parse()?,
1074            })
1075        }
1076    }
1077
1078    #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1079    impl Parse for Option<Abi> {
1080        fn parse(input: ParseStream) -> Result<Self> {
1081            if input.peek(Token![extern]) {
1082                input.parse().map(Some)
1083            } else {
1084                Ok(None)
1085            }
1086        }
1087    }
1088}
1089
1090#[cfg(feature = "printing")]
1091mod printing {
1092    use super::*;
1093    use crate::attr::FilterAttrs;
1094    use crate::print::TokensOrDefault;
1095    use proc_macro2::TokenStream;
1096    use quote::{ToTokens, TokenStreamExt};
1097
1098    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1099    impl ToTokens for TypeSlice {
1100        fn to_tokens(&self, tokens: &mut TokenStream) {
1101            self.bracket_token.surround(tokens, |tokens| {
1102                self.elem.to_tokens(tokens);
1103            });
1104        }
1105    }
1106
1107    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1108    impl ToTokens for TypeArray {
1109        fn to_tokens(&self, tokens: &mut TokenStream) {
1110            self.bracket_token.surround(tokens, |tokens| {
1111                self.elem.to_tokens(tokens);
1112                self.semi_token.to_tokens(tokens);
1113                self.len.to_tokens(tokens);
1114            });
1115        }
1116    }
1117
1118    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1119    impl ToTokens for TypePtr {
1120        fn to_tokens(&self, tokens: &mut TokenStream) {
1121            self.star_token.to_tokens(tokens);
1122            match &self.mutability {
1123                Some(tok) => tok.to_tokens(tokens),
1124                None => {
1125                    TokensOrDefault(&self.const_token).to_tokens(tokens);
1126                }
1127            }
1128            self.elem.to_tokens(tokens);
1129        }
1130    }
1131
1132    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1133    impl ToTokens for TypeReference {
1134        fn to_tokens(&self, tokens: &mut TokenStream) {
1135            self.and_token.to_tokens(tokens);
1136            self.lifetime.to_tokens(tokens);
1137            self.mutability.to_tokens(tokens);
1138            self.elem.to_tokens(tokens);
1139        }
1140    }
1141
1142    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1143    impl ToTokens for TypeBareFn {
1144        fn to_tokens(&self, tokens: &mut TokenStream) {
1145            self.lifetimes.to_tokens(tokens);
1146            self.unsafety.to_tokens(tokens);
1147            self.abi.to_tokens(tokens);
1148            self.fn_token.to_tokens(tokens);
1149            self.paren_token.surround(tokens, |tokens| {
1150                self.inputs.to_tokens(tokens);
1151                if let Some(variadic) = &self.variadic {
1152                    if !self.inputs.empty_or_trailing() {
1153                        let span = variadic.dots.spans[0];
1154                        Token![,](span).to_tokens(tokens);
1155                    }
1156                    variadic.to_tokens(tokens);
1157                }
1158            });
1159            self.output.to_tokens(tokens);
1160        }
1161    }
1162
1163    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1164    impl ToTokens for TypeNever {
1165        fn to_tokens(&self, tokens: &mut TokenStream) {
1166            self.bang_token.to_tokens(tokens);
1167        }
1168    }
1169
1170    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1171    impl ToTokens for TypeTuple {
1172        fn to_tokens(&self, tokens: &mut TokenStream) {
1173            self.paren_token.surround(tokens, |tokens| {
1174                self.elems.to_tokens(tokens);
1175            });
1176        }
1177    }
1178
1179    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1180    impl ToTokens for TypePath {
1181        fn to_tokens(&self, tokens: &mut TokenStream) {
1182            path::printing::print_path(tokens, &self.qself, &self.path);
1183        }
1184    }
1185
1186    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1187    impl ToTokens for TypeTraitObject {
1188        fn to_tokens(&self, tokens: &mut TokenStream) {
1189            self.dyn_token.to_tokens(tokens);
1190            self.bounds.to_tokens(tokens);
1191        }
1192    }
1193
1194    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1195    impl ToTokens for TypeImplTrait {
1196        fn to_tokens(&self, tokens: &mut TokenStream) {
1197            self.impl_token.to_tokens(tokens);
1198            self.bounds.to_tokens(tokens);
1199        }
1200    }
1201
1202    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1203    impl ToTokens for TypeGroup {
1204        fn to_tokens(&self, tokens: &mut TokenStream) {
1205            self.group_token.surround(tokens, |tokens| {
1206                self.elem.to_tokens(tokens);
1207            });
1208        }
1209    }
1210
1211    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1212    impl ToTokens for TypeParen {
1213        fn to_tokens(&self, tokens: &mut TokenStream) {
1214            self.paren_token.surround(tokens, |tokens| {
1215                self.elem.to_tokens(tokens);
1216            });
1217        }
1218    }
1219
1220    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1221    impl ToTokens for TypeInfer {
1222        fn to_tokens(&self, tokens: &mut TokenStream) {
1223            self.underscore_token.to_tokens(tokens);
1224        }
1225    }
1226
1227    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1228    impl ToTokens for TypeMacro {
1229        fn to_tokens(&self, tokens: &mut TokenStream) {
1230            self.mac.to_tokens(tokens);
1231        }
1232    }
1233
1234    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1235    impl ToTokens for ReturnType {
1236        fn to_tokens(&self, tokens: &mut TokenStream) {
1237            match self {
1238                ReturnType::Default => {}
1239                ReturnType::Type(arrow, ty) => {
1240                    arrow.to_tokens(tokens);
1241                    ty.to_tokens(tokens);
1242                }
1243            }
1244        }
1245    }
1246
1247    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1248    impl ToTokens for BareFnArg {
1249        fn to_tokens(&self, tokens: &mut TokenStream) {
1250            tokens.append_all(self.attrs.outer());
1251            if let Some((name, colon)) = &self.name {
1252                name.to_tokens(tokens);
1253                colon.to_tokens(tokens);
1254            }
1255            self.ty.to_tokens(tokens);
1256        }
1257    }
1258
1259    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1260    impl ToTokens for Variadic {
1261        fn to_tokens(&self, tokens: &mut TokenStream) {
1262            tokens.append_all(self.attrs.outer());
1263            self.dots.to_tokens(tokens);
1264        }
1265    }
1266
1267    #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1268    impl ToTokens for Abi {
1269        fn to_tokens(&self, tokens: &mut TokenStream) {
1270            self.extern_token.to_tokens(tokens);
1271            self.name.to_tokens(tokens);
1272        }
1273    }
1274}