Skip to main content

syn/
ty.rs

1use crate::attr::Attribute;
2use crate::expr::Expr;
3use crate::generics::{BoundLifetimes, TypeParamBound};
4use crate::ident::Ident;
5use crate::lifetime::Lifetime;
6use crate::lit::LitStr;
7use crate::mac::Macro;
8use crate::path::{Path, QSelf};
9use crate::punctuated::Punctuated;
10use crate::token;
11use alloc::boxed::Box;
12use alloc::vec::Vec;
13use proc_macro2::TokenStream;
14
15#[doc = r" The possible types that a Rust value could have."]
#[doc = r""]
#[doc = r" # Syntax tree enum"]
#[doc = r""]
#[doc = r" This type is a [syntax tree enum]."]
#[doc = r""]
#[doc = r" [syntax tree enum]: crate::expr::Expr#syntax-tree-enums"]
#[non_exhaustive]
pub enum Type {

    #[doc = r" A fixed size array type: `[T; n]`."]
    Array(TypeArray),

    #[doc = r" A function pointer type: `fn(usize) -> bool`."]
    FnPtr(TypeFnPtr),

    #[doc = r" A type contained within invisible delimiters."]
    Group(TypeGroup),

    #[doc =
    r" An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or"]
    #[doc = r" a lifetime."]
    ImplTrait(TypeImplTrait),

    #[doc =
    r" Indication that a type should be inferred by the compiler: `_`."]
    Infer(TypeInfer),

    #[doc = r" A macro in the type position."]
    Macro(TypeMacro),

    #[doc = r" The never type: `!`."]
    Never(TypeNever),

    #[doc = r" A parenthesized type equivalent to the inner type."]
    Paren(TypeParen),

    #[doc = r" A path like `core::slice::Iter`, optionally qualified with a"]
    #[doc = r" self-type as in `<Vec<T> as SomeTrait>::Associated`."]
    Path(TypePath),

    #[doc = r" A raw pointer type: `*const T` or `*mut T`."]
    Ptr(TypePtr),

    #[doc = r" A reference type: `&'a T` or `&'a mut T`."]
    Reference(TypeReference),

    #[doc = r" A dynamically sized slice type: `[T]`."]
    Slice(TypeSlice),

    #[doc =
    r" A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a"]
    #[doc = r" trait or a lifetime."]
    TraitObject(TypeTraitObject),

    #[doc = r" A tuple type: `(A, B, C, String)`."]
    Tuple(TypeTuple),

    #[doc = r" Tokens in type position not interpreted by Syn."]
    #[doc = r""]
    #[doc = r#" <div class="warning">"#]
    #[doc = r""]
    #[doc =
    r" Important: see [Compatibility notes][crate#verbatim-variants]."]
    #[doc = r""]
    #[doc = r" </div>"]
    Verbatim(TokenStream),
}
impl ::quote::ToTokens for Type {
    fn to_tokens(&self, tokens: &mut ::proc_macro2::TokenStream) {
        match self {
            Type::Array(_e) => _e.to_tokens(tokens),
            Type::FnPtr(_e) => _e.to_tokens(tokens),
            Type::Group(_e) => _e.to_tokens(tokens),
            Type::ImplTrait(_e) => _e.to_tokens(tokens),
            Type::Infer(_e) => _e.to_tokens(tokens),
            Type::Macro(_e) => _e.to_tokens(tokens),
            Type::Never(_e) => _e.to_tokens(tokens),
            Type::Paren(_e) => _e.to_tokens(tokens),
            Type::Path(_e) => _e.to_tokens(tokens),
            Type::Ptr(_e) => _e.to_tokens(tokens),
            Type::Reference(_e) => _e.to_tokens(tokens),
            Type::Slice(_e) => _e.to_tokens(tokens),
            Type::TraitObject(_e) => _e.to_tokens(tokens),
            Type::Tuple(_e) => _e.to_tokens(tokens),
            Type::Verbatim(_e) => _e.to_tokens(tokens),
        }
    }
}ast_enum_of_structs! {
16    /// The possible types that a Rust value could have.
17    ///
18    /// # Syntax tree enum
19    ///
20    /// This type is a [syntax tree enum].
21    ///
22    /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
23    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
24    #[non_exhaustive]
25    pub enum Type {
26        /// A fixed size array type: `[T; n]`.
27        Array(TypeArray),
28
29        /// A function pointer type: `fn(usize) -> bool`.
30        FnPtr(TypeFnPtr),
31
32        /// A type contained within invisible delimiters.
33        Group(TypeGroup),
34
35        /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
36        /// a lifetime.
37        ImplTrait(TypeImplTrait),
38
39        /// Indication that a type should be inferred by the compiler: `_`.
40        Infer(TypeInfer),
41
42        /// A macro in the type position.
43        Macro(TypeMacro),
44
45        /// The never type: `!`.
46        Never(TypeNever),
47
48        /// A parenthesized type equivalent to the inner type.
49        Paren(TypeParen),
50
51        /// A path like `core::slice::Iter`, optionally qualified with a
52        /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
53        Path(TypePath),
54
55        /// A raw pointer type: `*const T` or `*mut T`.
56        Ptr(TypePtr),
57
58        /// A reference type: `&'a T` or `&'a mut T`.
59        Reference(TypeReference),
60
61        /// A dynamically sized slice type: `[T]`.
62        Slice(TypeSlice),
63
64        /// A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a
65        /// trait or a lifetime.
66        TraitObject(TypeTraitObject),
67
68        /// A tuple type: `(A, B, C, String)`.
69        Tuple(TypeTuple),
70
71        /// Tokens in type position not interpreted by Syn.
72        ///
73        /// <div class="warning">
74        ///
75        /// Important: see [Compatibility notes][crate#verbatim-variants].
76        ///
77        /// </div>
78        Verbatim(TokenStream),
79    }
80}
81
82#[doc = r" A fixed size array type: `[T; n]`."]
pub struct TypeArray {
    pub attrs: Vec<Attribute>,
    pub bracket_token: token::Bracket,
    pub elem: Box<Type>,
    pub semi_token: crate::token::Semi,
    pub len: Expr,
}ast_struct! {
83    /// A fixed size array type: `[T; n]`.
84    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
85    pub struct TypeArray {
86        pub attrs: Vec<Attribute>,
87        pub bracket_token: token::Bracket,
88        pub elem: Box<Type>,
89        pub semi_token: Token![;],
90        pub len: Expr,
91    }
92}
93
94#[doc = r" A function pointer type: `fn(usize) -> bool`."]
pub struct TypeFnPtr {
    pub attrs: Vec<Attribute>,
    pub lifetimes: Option<BoundLifetimes>,
    pub unsafety: Option<crate::token::Unsafe>,
    pub abi: Option<Abi>,
    pub fn_token: crate::token::Fn,
    pub paren_token: token::Paren,
    pub inputs: Punctuated<NamedArg, crate::token::Comma>,
    pub variadic: Option<FnPtrVariadic>,
    pub output: ReturnType,
}ast_struct! {
95    /// A function pointer type: `fn(usize) -> bool`.
96    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
97    pub struct TypeFnPtr {
98        pub attrs: Vec<Attribute>,
99        pub lifetimes: Option<BoundLifetimes>,
100        pub unsafety: Option<Token![unsafe]>,
101        pub abi: Option<Abi>,
102        pub fn_token: Token![fn],
103        pub paren_token: token::Paren,
104        pub inputs: Punctuated<NamedArg, Token![,]>,
105        pub variadic: Option<FnPtrVariadic>,
106        pub output: ReturnType,
107    }
108}
109
110#[doc = r" A type contained within invisible delimiters."]
pub struct TypeGroup {
    pub attrs: Vec<Attribute>,
    pub group_token: token::Group,
    pub elem: Box<Type>,
}ast_struct! {
111    /// A type contained within invisible delimiters.
112    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
113    pub struct TypeGroup {
114        pub attrs: Vec<Attribute>,
115        pub group_token: token::Group,
116        pub elem: Box<Type>,
117    }
118}
119
120#[doc =
r" An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or"]
#[doc = r" a lifetime."]
pub struct TypeImplTrait {
    pub attrs: Vec<Attribute>,
    pub impl_token: crate::token::Impl,
    pub bounds: Punctuated<TypeParamBound, crate::token::Plus>,
}ast_struct! {
121    /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or
122    /// a lifetime.
123    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
124    pub struct TypeImplTrait {
125        pub attrs: Vec<Attribute>,
126        pub impl_token: Token![impl],
127        pub bounds: Punctuated<TypeParamBound, Token![+]>,
128    }
129}
130
131#[doc = r" Indication that a type should be inferred by the compiler: `_`."]
pub struct TypeInfer {
    pub attrs: Vec<Attribute>,
    pub underscore_token: crate::token::Underscore,
}ast_struct! {
132    /// Indication that a type should be inferred by the compiler: `_`.
133    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
134    pub struct TypeInfer {
135        pub attrs: Vec<Attribute>,
136        pub underscore_token: Token![_],
137    }
138}
139
140#[doc = r" A macro in the type position."]
pub struct TypeMacro {
    pub attrs: Vec<Attribute>,
    pub mac: Macro,
}ast_struct! {
141    /// A macro in the type position.
142    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
143    pub struct TypeMacro {
144        pub attrs: Vec<Attribute>,
145        pub mac: Macro,
146    }
147}
148
149#[doc = r" The never type: `!`."]
pub struct TypeNever {
    pub attrs: Vec<Attribute>,
    pub bang_token: crate::token::Not,
}ast_struct! {
150    /// The never type: `!`.
151    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
152    pub struct TypeNever {
153        pub attrs: Vec<Attribute>,
154        pub bang_token: Token![!],
155    }
156}
157
158#[doc = r" A parenthesized type equivalent to the inner type."]
pub struct TypeParen {
    pub attrs: Vec<Attribute>,
    pub paren_token: token::Paren,
    pub elem: Box<Type>,
}ast_struct! {
159    /// A parenthesized type equivalent to the inner type.
160    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
161    pub struct TypeParen {
162        pub attrs: Vec<Attribute>,
163        pub paren_token: token::Paren,
164        pub elem: Box<Type>,
165    }
166}
167
168#[doc = r" A path like `core::slice::Iter`, optionally qualified with a"]
#[doc = r" self-type as in `<Vec<T> as SomeTrait>::Associated`."]
pub struct TypePath {
    pub attrs: Vec<Attribute>,
    pub qself: Option<QSelf>,
    pub path: Path,
}ast_struct! {
169    /// A path like `core::slice::Iter`, optionally qualified with a
170    /// self-type as in `<Vec<T> as SomeTrait>::Associated`.
171    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
172    pub struct TypePath {
173        pub attrs: Vec<Attribute>,
174        pub qself: Option<QSelf>,
175        pub path: Path,
176    }
177}
178
179#[doc = r" A raw pointer type: `*const T` or `*mut T`."]
pub struct TypePtr {
    pub attrs: Vec<Attribute>,
    pub star_token: crate::token::Star,
    pub mutability: PointerMutability,
    pub elem: Box<Type>,
}ast_struct! {
180    /// A raw pointer type: `*const T` or `*mut T`.
181    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
182    pub struct TypePtr {
183        pub attrs: Vec<Attribute>,
184        pub star_token: Token![*],
185        pub mutability: PointerMutability,
186        pub elem: Box<Type>,
187    }
188}
189
190#[doc = r" A reference type: `&'a T` or `&'a mut T`."]
pub struct TypeReference {
    pub attrs: Vec<Attribute>,
    pub and_token: crate::token::And,
    pub lifetime: Option<Lifetime>,
    pub mutability: Option<crate::token::Mut>,
    pub elem: Box<Type>,
}ast_struct! {
191    /// A reference type: `&'a T` or `&'a mut T`.
192    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
193    pub struct TypeReference {
194        pub attrs: Vec<Attribute>,
195        pub and_token: Token![&],
196        pub lifetime: Option<Lifetime>,
197        pub mutability: Option<Token![mut]>,
198        pub elem: Box<Type>,
199    }
200}
201
202#[doc = r" A dynamically sized slice type: `[T]`."]
pub struct TypeSlice {
    pub attrs: Vec<Attribute>,
    pub bracket_token: token::Bracket,
    pub elem: Box<Type>,
}ast_struct! {
203    /// A dynamically sized slice type: `[T]`.
204    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
205    pub struct TypeSlice {
206        pub attrs: Vec<Attribute>,
207        pub bracket_token: token::Bracket,
208        pub elem: Box<Type>,
209    }
210}
211
212#[doc =
r" A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a"]
#[doc = r" trait or a lifetime."]
pub struct TypeTraitObject {
    pub attrs: Vec<Attribute>,
    #[doc =
    r" The `dyn` keyword is required since Rust 2021 edition. In editions"]
    #[doc =
    r" 2015&ndash;2018, trait objects without a `dyn` keyword are allowed"]
    #[doc = r" but deprecated."]
    pub dyn_token: Option<crate::token::Dyn>,
    pub bounds: Punctuated<TypeParamBound, crate::token::Plus>,
}ast_struct! {
213    /// A trait object type `dyn Bound1 + Bound2 + Bound3` where `Bound` is a
214    /// trait or a lifetime.
215    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
216    pub struct TypeTraitObject {
217        pub attrs: Vec<Attribute>,
218        /// The `dyn` keyword is required since Rust 2021 edition. In editions
219        /// 2015&ndash;2018, trait objects without a `dyn` keyword are allowed
220        /// but deprecated.
221        pub dyn_token: Option<Token![dyn]>,
222        pub bounds: Punctuated<TypeParamBound, Token![+]>,
223    }
224}
225
226#[doc = r" A tuple type: `(A, B, C, String)`."]
pub struct TypeTuple {
    pub attrs: Vec<Attribute>,
    pub paren_token: token::Paren,
    pub elems: Punctuated<Type, crate::token::Comma>,
}ast_struct! {
227    /// A tuple type: `(A, B, C, String)`.
228    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
229    pub struct TypeTuple {
230        pub attrs: Vec<Attribute>,
231        pub paren_token: token::Paren,
232        pub elems: Punctuated<Type, Token![,]>,
233    }
234}
235
236#[doc = r#" The binary interface of a function: `extern "C"`."#]
pub struct Abi {
    pub extern_token: crate::token::Extern,
    #[doc =
    r" ABI name is optional, but note that extern blocks and functions with"]
    #[doc =
    r" an omitted ABI name are [deprecated since Rust 1.86.0][deprecated]."]
    #[doc =
    r" Omitting the ABI after the extern keyword has always implicitly"]
    #[doc =
    r#" resulted in the "C" ABI. It is now recommended to explicitly specify"#]
    #[doc = r#" the "C" ABI (`extern "C" {}` and `extern "C" fn`)."#]
    #[doc = r""]
    #[doc =
    r" [deprecated]: https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/#make-missing-abi-lint-warn-by-default"]
    pub name: Option<LitStr>,
}ast_struct! {
237    /// The binary interface of a function: `extern "C"`.
238    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
239    pub struct Abi {
240        pub extern_token: Token![extern],
241
242        /// ABI name is optional, but note that extern blocks and functions with
243        /// an omitted ABI name are [deprecated since Rust 1.86.0][deprecated].
244        /// Omitting the ABI after the extern keyword has always implicitly
245        /// resulted in the "C" ABI. It is now recommended to explicitly specify
246        /// the "C" ABI (`extern "C" {}` and `extern "C" fn`).
247        ///
248        /// [deprecated]: https://blog.rust-lang.org/2025/04/03/Rust-1.86.0/#make-missing-abi-lint-warn-by-default
249        pub name: Option<LitStr>,
250    }
251}
252
253#[doc =
r" Mutability of a raw pointer (`*const T`, `*mut T`), in which non-mutable"]
#[doc = r" isn't the implicit default."]
pub enum PointerMutability {
    Const(crate::token::Const),
    Mut(crate::token::Mut),
}ast_enum! {
254    /// Mutability of a raw pointer (`*const T`, `*mut T`), in which non-mutable
255    /// isn't the implicit default.
256    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
257    pub enum PointerMutability {
258        Const(Token![const]),
259        Mut(Token![mut]),
260    }
261}
262
263#[doc =
r" An argument in a function type: the `usize` in `fn(usize) -> bool`."]
pub struct NamedArg {
    pub attrs: Vec<Attribute>,
    pub name: Option<(Ident, crate::token::Colon)>,
    pub ty: Type,
}ast_struct! {
264    /// An argument in a function type: the `usize` in `fn(usize) -> bool`.
265    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
266    pub struct NamedArg {
267        pub attrs: Vec<Attribute>,
268        pub name: Option<(Ident, Token![:])>,
269        pub ty: Type,
270    }
271}
272
273#[doc =
r" The variadic argument of a function pointer like `fn(usize, ...)`."]
pub struct FnPtrVariadic {
    pub attrs: Vec<Attribute>,
    pub name: Option<(Ident, crate::token::Colon)>,
    pub dots: crate::token::DotDotDot,
    pub comma: Option<crate::token::Comma>,
}ast_struct! {
274    /// The variadic argument of a function pointer like `fn(usize, ...)`.
275    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
276    pub struct FnPtrVariadic {
277        pub attrs: Vec<Attribute>,
278        pub name: Option<(Ident, Token![:])>,
279        pub dots: Token![...],
280        pub comma: Option<Token![,]>,
281    }
282}
283
284#[doc = r" Return type of a function signature."]
pub enum ReturnType {

    #[doc = r" Return type is not specified."]
    #[doc = r""]
    #[doc =
    r" Functions default to `()` and closures default to type inference."]
    Default,

    #[doc = r" A particular type is returned."]
    Type(crate::token::RArrow, Box<Type>),
}ast_enum! {
285    /// Return type of a function signature.
286    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
287    pub enum ReturnType {
288        /// Return type is not specified.
289        ///
290        /// Functions default to `()` and closures default to type inference.
291        Default,
292        /// A particular type is returned.
293        Type(Token![->], Box<Type>),
294    }
295}
296
297#[cfg(feature = "parsing")]
298pub(crate) mod parsing {
299    use crate::attr::Attribute;
300    use crate::buffer::Cursor;
301    use crate::error::{Error, Result};
302    use crate::ext::IdentExt as _;
303    use crate::generics::{BoundLifetimes, TraitBound, TraitBoundModifiers, TypeParamBound};
304    use crate::ident::Ident;
305    use crate::lifetime::Lifetime;
306    use crate::mac::{self, Macro};
307    use crate::parse::{Parse, ParseStream};
308    use crate::path;
309    use crate::path::{Path, PathArguments, QSelf};
310    use crate::punctuated::Punctuated;
311    use crate::token;
312    use crate::ty::{
313        Abi, FnPtrVariadic, NamedArg, PointerMutability, ReturnType, Type, TypeArray, TypeFnPtr,
314        TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr,
315        TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
316    };
317    use crate::verbatim;
318    use alloc::boxed::Box;
319    use alloc::vec::Vec;
320    use proc_macro2::TokenStream;
321
322    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
323    impl Parse for Type {
324        fn parse(input: ParseStream) -> Result<Self> {
325            let allow_plus = true;
326            let allow_group_generic = true;
327            ambig_ty(input, allow_plus, allow_group_generic)
328        }
329    }
330
331    impl Type {
332        /// In some positions, types may not contain the `+` character, to
333        /// disambiguate them. For example in the expression `1 as T`, T may not
334        /// contain a `+` character.
335        ///
336        /// This parser does not allow a `+`, while the default parser does.
337        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
338        pub fn without_plus(input: ParseStream) -> Result<Self> {
339            let allow_plus = false;
340            let allow_group_generic = true;
341            ambig_ty(input, allow_plus, allow_group_generic)
342        }
343    }
344
345    pub(crate) fn ambig_ty(
346        input: ParseStream,
347        allow_plus: bool,
348        allow_group_generic: bool,
349    ) -> Result<Type> {
350        let begin = input.cursor();
351
352        if input.peek(token::Group) {
353            let mut group: TypeGroup = input.parse()?;
354            if input.peek(crate::token::PathSepToken![::]) && input.peek3(Ident::peek_any) {
355                if let Type::Path(mut ty) = *group.elem {
356                    Path::parse_rest(input, &mut ty.path, false)?;
357                    return Ok(Type::Path(ty));
358                } else {
359                    return Ok(Type::Path(TypePath {
360                        attrs: Vec::new(),
361                        qself: Some(QSelf {
362                            lt_token: crate::token::LtToken![<](group.group_token.span),
363                            position: 0,
364                            as_token: None,
365                            gt_token: crate::token::GtToken![>](group.group_token.span),
366                            ty: group.elem,
367                        }),
368                        path: Path::parse_helper(input, false)?,
369                    }));
370                }
371            } else if input.peek(crate::token::LtToken![<]) && allow_group_generic
372                || input.peek(crate::token::PathSepToken![::]) && input.peek3(crate::token::LtToken![<])
373            {
374                if let Type::Path(mut ty) = *group.elem {
375                    let arguments = &mut ty.path.segments.last_mut().unwrap().arguments;
376                    if arguments.is_none() {
377                        *arguments = PathArguments::AngleBracketed(input.parse()?);
378                        Path::parse_rest(input, &mut ty.path, false)?;
379                        return Ok(Type::Path(ty));
380                    } else {
381                        *group.elem = Type::Path(ty);
382                    }
383                }
384            }
385            return Ok(Type::Group(group));
386        }
387
388        let mut lifetimes = None::<BoundLifetimes>;
389        let mut lookahead = input.lookahead1();
390        if lookahead.peek(crate::token::ForToken![for]) {
391            lifetimes = input.parse()?;
392            lookahead = input.lookahead1();
393            if !lookahead.peek(Ident)
394                && !lookahead.peek(crate::token::FnToken![fn])
395                && !lookahead.peek(crate::token::UnsafeToken![unsafe])
396                && !lookahead.peek(crate::token::ExternToken![extern])
397                && !lookahead.peek(crate::token::SuperToken![super])
398                && !lookahead.peek(crate::token::SelfValueToken![self])
399                && !lookahead.peek(crate::token::SelfTypeToken![Self])
400                && !lookahead.peek(crate::token::CrateToken![crate])
401                || input.peek(crate::token::DynToken![dyn])
402            {
403                return Err(lookahead.error());
404            }
405        }
406
407        if lookahead.peek(token::Paren) {
408            let content;
409            let paren_token = match crate::__private::parse_parens(&input) {
    crate::__private::Ok(parens) => {
        content = parens.content;
        _ = content;
        parens.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input);
410            if content.is_empty() {
411                return Ok(Type::Tuple(TypeTuple {
412                    attrs: Vec::new(),
413                    paren_token,
414                    elems: Punctuated::new(),
415                }));
416            }
417            if content.peek(Lifetime) {
418                return Ok(Type::Paren(TypeParen {
419                    attrs: Vec::new(),
420                    paren_token,
421                    elem: Box::new(Type::TraitObject(content.parse()?)),
422                }));
423            }
424            if content.peek(crate::token::QuestionToken![?]) {
425                return Ok(Type::TraitObject(TypeTraitObject {
426                    attrs: Vec::new(),
427                    dyn_token: None,
428                    bounds: {
429                        let mut bounds = Punctuated::new();
430                        bounds.push_value(TypeParamBound::Trait(TraitBound {
431                            paren_token: Some(paren_token),
432                            ..content.parse()?
433                        }));
434                        while let Some(plus) = input.parse()? {
435                            bounds.push_punct(plus);
436                            bounds.push_value({
437                                let allow_precise_capture = false;
438                                let allow_const = false;
439                                TypeParamBound::parse_single(
440                                    input,
441                                    allow_precise_capture,
442                                    allow_const,
443                                )?
444                            });
445                        }
446                        bounds
447                    },
448                }));
449            }
450            let mut first: Type = content.parse()?;
451            if content.peek(crate::token::CommaToken![,]) {
452                return Ok(Type::Tuple(TypeTuple {
453                    attrs: Vec::new(),
454                    paren_token,
455                    elems: {
456                        let mut elems = Punctuated::new();
457                        elems.push_value(first);
458                        elems.push_punct(content.parse()?);
459                        while !content.is_empty() {
460                            elems.push_value(content.parse()?);
461                            if content.is_empty() {
462                                break;
463                            }
464                            elems.push_punct(content.parse()?);
465                        }
466                        elems
467                    },
468                }));
469            }
470            if allow_plus && input.peek(crate::token::PlusToken![+]) {
471                loop {
472                    let first = match first {
473                        Type::Path(TypePath {
474                            attrs: _,
475                            qself: None,
476                            path,
477                        }) => TypeParamBound::Trait(TraitBound {
478                            paren_token: Some(paren_token),
479                            lifetimes: None,
480                            modifiers: TraitBoundModifiers {},
481                            maybe: None,
482                            path,
483                        }),
484                        Type::TraitObject(TypeTraitObject {
485                            attrs: _,
486                            dyn_token: None,
487                            bounds,
488                        }) => {
489                            if bounds.len() > 1 || bounds.trailing_punct() {
490                                first = Type::TraitObject(TypeTraitObject {
491                                    attrs: Vec::new(),
492                                    dyn_token: None,
493                                    bounds,
494                                });
495                                break;
496                            }
497                            match bounds.into_iter().next().unwrap() {
498                                TypeParamBound::Trait(trait_bound) => {
499                                    TypeParamBound::Trait(TraitBound {
500                                        paren_token: Some(paren_token),
501                                        ..trait_bound
502                                    })
503                                }
504                                other @ (TypeParamBound::Lifetime(_)
505                                | TypeParamBound::PreciseCapture(_)
506                                | TypeParamBound::Verbatim(_)) => other,
507                            }
508                        }
509                        _ => break,
510                    };
511                    return Ok(Type::TraitObject(TypeTraitObject {
512                        attrs: Vec::new(),
513                        dyn_token: None,
514                        bounds: {
515                            let mut bounds = Punctuated::new();
516                            bounds.push_value(first);
517                            while let Some(plus) = input.parse()? {
518                                bounds.push_punct(plus);
519                                bounds.push_value({
520                                    let allow_precise_capture = false;
521                                    let allow_const = false;
522                                    TypeParamBound::parse_single(
523                                        input,
524                                        allow_precise_capture,
525                                        allow_const,
526                                    )?
527                                });
528                            }
529                            bounds
530                        },
531                    }));
532                }
533            }
534            Ok(Type::Paren(TypeParen {
535                attrs: Vec::new(),
536                paren_token,
537                elem: Box::new(first),
538            }))
539        } else if lookahead.peek(crate::token::UnsafeToken![unsafe]) && input.peek2(crate::token::LtToken![<]) {
540            input.parse::<crate::token::UnsafeToken![unsafe]>()?;
541            input.parse::<crate::token::LtToken![<]>()?;
542            while !input.peek(crate::token::GtToken![>]) {
543                Lifetime::parse_any(input)?;
544                if input.peek(crate::token::GtToken![>]) {
545                    break;
546                }
547                input.parse::<crate::token::CommaToken![,]>()?;
548            }
549            input.parse::<crate::token::GtToken![>]>()?;
550            ambig_ty(input, allow_plus, allow_group_generic)?;
551            Ok(Type::Verbatim(verbatim::between(begin, input.cursor())))
552        } else if lookahead.peek(crate::token::FnToken![fn])
553            || input.peek(crate::token::UnsafeToken![unsafe])
554            || lookahead.peek(crate::token::ExternToken![extern])
555        {
556            let mut fn_ptr: TypeFnPtr = input.parse()?;
557            fn_ptr.lifetimes = lifetimes;
558            Ok(Type::FnPtr(fn_ptr))
559        } else if truecfg!(feature = "full")
560            && input.cursor().peek_keyword("builtin")
561            && input.peek2(crate::token::PoundToken![#])
562        {
563            token::parsing::keyword(input, "builtin")?;
564            input.parse::<crate::token::PoundToken![#]>()?;
565            input.parse::<Ident>()?;
566            let args;
567            match crate::__private::parse_parens(&input) {
    crate::__private::Ok(parens) => {
        args = parens.content;
        _ = args;
        parens.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
};parenthesized!(args in input);
568            args.parse::<TokenStream>()?;
569            Ok(Type::Verbatim(verbatim::between(begin, input.cursor())))
570        } else if lookahead.peek(Ident)
571            || input.peek(crate::token::SuperToken![super])
572            || input.peek(crate::token::SelfValueToken![self])
573            || input.peek(crate::token::SelfTypeToken![Self])
574            || input.peek(crate::token::CrateToken![crate])
575            || lookahead.peek(crate::token::PathSepToken![::])
576            || lookahead.peek(crate::token::LtToken![<])
577        {
578            let ty: TypePath = input.parse()?;
579            if ty.qself.is_some() {
580                return Ok(Type::Path(ty));
581            }
582
583            if input.peek(crate::token::NotToken![!]) && !input.peek(crate::token::NeToken![!=]) && ty.path.is_mod_style() {
584                let bang_token: crate::token::NotToken![!] = input.parse()?;
585                let (delimiter, tokens) = mac::parse_delimiter(input)?;
586                return Ok(Type::Macro(TypeMacro {
587                    attrs: Vec::new(),
588                    mac: Macro {
589                        path: ty.path,
590                        bang_token,
591                        delimiter,
592                        tokens,
593                    },
594                }));
595            }
596
597            if lifetimes.is_some() || allow_plus && input.peek(crate::token::PlusToken![+]) {
598                let mut bounds = Punctuated::new();
599                bounds.push_value(TypeParamBound::Trait(TraitBound {
600                    paren_token: None,
601                    lifetimes,
602                    modifiers: TraitBoundModifiers {},
603                    maybe: None,
604                    path: ty.path,
605                }));
606                if allow_plus {
607                    while input.peek(crate::token::PlusToken![+]) {
608                        bounds.push_punct(input.parse()?);
609                        if !(input.peek(Ident::peek_any)
610                            || input.peek(crate::token::PathSepToken![::])
611                            || input.peek(crate::token::QuestionToken![?])
612                            || input.peek(Lifetime)
613                            || input.peek(token::Paren))
614                        {
615                            break;
616                        }
617                        bounds.push_value({
618                            let allow_precise_capture = false;
619                            let allow_const = false;
620                            TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
621                        });
622                    }
623                }
624                return Ok(Type::TraitObject(TypeTraitObject {
625                    attrs: Vec::new(),
626                    dyn_token: None,
627                    bounds,
628                }));
629            }
630
631            Ok(Type::Path(ty))
632        } else if lookahead.peek(crate::token::DynToken![dyn]) {
633            let dyn_begin = input.cursor();
634            let dyn_token: crate::token::DynToken![dyn] = input.parse()?;
635            let star_token: Option<crate::token::StarToken![*]> = input.parse()?;
636            let bounds = TypeTraitObject::parse_bounds(dyn_begin, input, allow_plus)?;
637            Ok(if star_token.is_some() {
638                Type::Verbatim(verbatim::between(begin, input.cursor()))
639            } else {
640                Type::TraitObject(TypeTraitObject {
641                    attrs: Vec::new(),
642                    dyn_token: Some(dyn_token),
643                    bounds,
644                })
645            })
646        } else if lookahead.peek(token::Bracket) {
647            let content;
648            let bracket_token = match crate::__private::parse_brackets(&input) {
    crate::__private::Ok(brackets) => {
        content = brackets.content;
        _ = content;
        brackets.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input);
649            let elem: Type = content.parse()?;
650            if content.peek(crate::token::SemiToken![;]) {
651                Ok(Type::Array(TypeArray {
652                    attrs: Vec::new(),
653                    bracket_token,
654                    elem: Box::new(elem),
655                    semi_token: content.parse()?,
656                    len: content.parse()?,
657                }))
658            } else {
659                Ok(Type::Slice(TypeSlice {
660                    attrs: Vec::new(),
661                    bracket_token,
662                    elem: Box::new(elem),
663                }))
664            }
665        } else if lookahead.peek(crate::token::StarToken![*]) {
666            input.parse().map(Type::Ptr)
667        } else if lookahead.peek(crate::token::AndToken![&]) {
668            input.parse().map(Type::Reference)
669        } else if lookahead.peek(crate::token::NotToken![!]) && !input.peek(crate::token::EqToken![=]) {
670            input.parse().map(Type::Never)
671        } else if lookahead.peek(crate::token::ImplToken![impl]) {
672            TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
673        } else if lookahead.peek(crate::token::UnderscoreToken![_]) {
674            input.parse().map(Type::Infer)
675        } else if lookahead.peek(Lifetime) {
676            input.parse().map(Type::TraitObject)
677        } else {
678            Err(lookahead.error())
679        }
680    }
681
682    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
683    impl Parse for TypeSlice {
684        fn parse(input: ParseStream) -> Result<Self> {
685            let content;
686            Ok(TypeSlice {
687                attrs: Vec::new(),
688                bracket_token: match crate::__private::parse_brackets(&input) {
    crate::__private::Ok(brackets) => {
        content = brackets.content;
        _ = content;
        brackets.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input),
689                elem: content.parse()?,
690            })
691        }
692    }
693
694    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
695    impl Parse for TypeArray {
696        fn parse(input: ParseStream) -> Result<Self> {
697            let content;
698            Ok(TypeArray {
699                attrs: Vec::new(),
700                bracket_token: match crate::__private::parse_brackets(&input) {
    crate::__private::Ok(brackets) => {
        content = brackets.content;
        _ = content;
        brackets.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}bracketed!(content in input),
701                elem: content.parse()?,
702                semi_token: content.parse()?,
703                len: content.parse()?,
704            })
705        }
706    }
707
708    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
709    impl Parse for TypePtr {
710        fn parse(input: ParseStream) -> Result<Self> {
711            Ok(TypePtr {
712                attrs: Vec::new(),
713                star_token: input.parse()?,
714                mutability: input.parse()?,
715                elem: Box::new(input.call(Type::without_plus)?),
716            })
717        }
718    }
719
720    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
721    impl Parse for TypeReference {
722        fn parse(input: ParseStream) -> Result<Self> {
723            Ok(TypeReference {
724                attrs: Vec::new(),
725                and_token: input.parse()?,
726                lifetime: Lifetime::parse_optional_any(input),
727                mutability: input.parse()?,
728                // & binds tighter than +, so we don't allow + here.
729                elem: Box::new(input.call(Type::without_plus)?),
730            })
731        }
732    }
733
734    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
735    impl Parse for TypeFnPtr {
736        fn parse(input: ParseStream) -> Result<Self> {
737            let args;
738            let mut variadic = None;
739
740            Ok(TypeFnPtr {
741                attrs: Vec::new(),
742                lifetimes: input.parse()?,
743                unsafety: input.parse()?,
744                abi: input.parse()?,
745                fn_token: input.parse()?,
746                paren_token: match crate::__private::parse_parens(&input) {
    crate::__private::Ok(parens) => {
        args = parens.content;
        _ = args;
        parens.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(args in input),
747                inputs: {
748                    let mut inputs = Punctuated::new();
749
750                    while !args.is_empty() {
751                        let attrs = args.call(Attribute::parse_outer)?;
752
753                        if inputs.empty_or_trailing()
754                            && (args.peek(crate::token::DotDotDotToken![...])
755                                || (args.peek(Ident) || args.peek(crate::token::UnderscoreToken![_]))
756                                    && args.peek2(crate::token::ColonToken![:])
757                                    && args.peek3(crate::token::DotDotDotToken![...]))
758                        {
759                            variadic = Some(parse_fn_ptr_variadic(&args, attrs)?);
760                            break;
761                        }
762
763                        let allow_self = inputs.is_empty();
764                        let arg = parse_fn_ptr_arg(&args, allow_self)?;
765                        inputs.push_value(NamedArg { attrs, ..arg });
766                        if args.is_empty() {
767                            break;
768                        }
769
770                        let comma = args.parse()?;
771                        inputs.push_punct(comma);
772                    }
773
774                    inputs
775                },
776                variadic,
777                output: input.call(ReturnType::without_plus)?,
778            })
779        }
780    }
781
782    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
783    impl Parse for TypeNever {
784        fn parse(input: ParseStream) -> Result<Self> {
785            Ok(TypeNever {
786                attrs: Vec::new(),
787                bang_token: input.parse()?,
788            })
789        }
790    }
791
792    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
793    impl Parse for TypeInfer {
794        fn parse(input: ParseStream) -> Result<Self> {
795            Ok(TypeInfer {
796                attrs: Vec::new(),
797                underscore_token: input.parse()?,
798            })
799        }
800    }
801
802    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
803    impl Parse for TypeTuple {
804        fn parse(input: ParseStream) -> Result<Self> {
805            let content;
806            let paren_token = match crate::__private::parse_parens(&input) {
    crate::__private::Ok(parens) => {
        content = parens.content;
        _ = content;
        parens.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input);
807
808            if content.is_empty() {
809                return Ok(TypeTuple {
810                    attrs: Vec::new(),
811                    paren_token,
812                    elems: Punctuated::new(),
813                });
814            }
815
816            let first: Type = content.parse()?;
817            Ok(TypeTuple {
818                attrs: Vec::new(),
819                paren_token,
820                elems: {
821                    let mut elems = Punctuated::new();
822                    elems.push_value(first);
823                    elems.push_punct(content.parse()?);
824                    while !content.is_empty() {
825                        elems.push_value(content.parse()?);
826                        if content.is_empty() {
827                            break;
828                        }
829                        elems.push_punct(content.parse()?);
830                    }
831                    elems
832                },
833            })
834        }
835    }
836
837    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
838    impl Parse for TypeMacro {
839        fn parse(input: ParseStream) -> Result<Self> {
840            Ok(TypeMacro {
841                attrs: Vec::new(),
842                mac: input.parse()?,
843            })
844        }
845    }
846
847    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
848    impl Parse for TypePath {
849        fn parse(input: ParseStream) -> Result<Self> {
850            let expr_style = false;
851            let (qself, path) = path::parsing::qpath(input, expr_style)?;
852            Ok(TypePath {
853                attrs: Vec::new(),
854                qself,
855                path,
856            })
857        }
858    }
859
860    impl ReturnType {
861        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
862        pub fn without_plus(input: ParseStream) -> Result<Self> {
863            let allow_plus = false;
864            Self::parse(input, allow_plus)
865        }
866
867        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
868            if input.peek(crate::token::RArrowToken![->]) {
869                let arrow = input.parse()?;
870                let allow_group_generic = true;
871                let ty = ambig_ty(input, allow_plus, allow_group_generic)?;
872                Ok(ReturnType::Type(arrow, Box::new(ty)))
873            } else {
874                Ok(ReturnType::Default)
875            }
876        }
877    }
878
879    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
880    impl Parse for ReturnType {
881        fn parse(input: ParseStream) -> Result<Self> {
882            let allow_plus = true;
883            Self::parse(input, allow_plus)
884        }
885    }
886
887    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
888    impl Parse for TypeTraitObject {
889        fn parse(input: ParseStream) -> Result<Self> {
890            let allow_plus = true;
891            Self::parse(input, allow_plus)
892        }
893    }
894
895    impl TypeTraitObject {
896        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
897        pub fn without_plus(input: ParseStream) -> Result<Self> {
898            let allow_plus = false;
899            Self::parse(input, allow_plus)
900        }
901
902        // Only allow multiple trait references if allow_plus is true.
903        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
904            let dyn_begin = input.cursor();
905            let dyn_token: Option<crate::token::DynToken![dyn]> = input.parse()?;
906            let bounds = Self::parse_bounds(dyn_begin, input, allow_plus)?;
907            Ok(TypeTraitObject {
908                attrs: Vec::new(),
909                dyn_token,
910                bounds,
911            })
912        }
913
914        fn parse_bounds(
915            dyn_begin: Cursor,
916            input: ParseStream,
917            allow_plus: bool,
918        ) -> Result<Punctuated<TypeParamBound, crate::token::PlusToken![+]>> {
919            let allow_precise_capture = false;
920            let allow_const = false;
921            let bounds = TypeParamBound::parse_multiple(
922                input,
923                allow_plus,
924                allow_precise_capture,
925                allow_const,
926            )?;
927            let mut at_least_one_trait = false;
928            for bound in &bounds {
929                match bound {
930                    TypeParamBound::Trait(_) => {
931                        at_least_one_trait = true;
932                        break;
933                    }
934                    TypeParamBound::Lifetime(_) => {}
935                    TypeParamBound::PreciseCapture(_) | TypeParamBound::Verbatim(_) => {
936                        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
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::new_range(dyn_begin..input.cursor(), msg));
944            }
945            Ok(bounds)
946        }
947    }
948
949    #[cfg_attr(docsrs, 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(docsrs, 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_begin = input.cursor();
966            let impl_token: crate::token::ImplToken![impl] = input.parse()?;
967            let allow_precise_capture = true;
968            let allow_const = true;
969            let bounds = TypeParamBound::parse_multiple(
970                input,
971                allow_plus,
972                allow_precise_capture,
973                allow_const,
974            )?;
975            let mut at_least_one_trait = false;
976            for bound in &bounds {
977                match bound {
978                    TypeParamBound::Trait(_) => {
979                        at_least_one_trait = true;
980                        break;
981                    }
982                    TypeParamBound::Lifetime(_) | TypeParamBound::PreciseCapture(_) => {}
983                    TypeParamBound::Verbatim(_) => {
984                        // `[const] Trait`
985                        at_least_one_trait = true;
986                        break;
987                    }
988                }
989            }
990            if !at_least_one_trait {
991                let msg = "at least one trait must be specified";
992                return Err(Error::new_range(impl_begin..input.cursor(), msg));
993            }
994            Ok(TypeImplTrait {
995                attrs: Vec::new(),
996                impl_token,
997                bounds,
998            })
999        }
1000    }
1001
1002    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1003    impl Parse for TypeGroup {
1004        fn parse(input: ParseStream) -> Result<Self> {
1005            let group = crate::group::parse_group(input)?;
1006            Ok(TypeGroup {
1007                attrs: Vec::new(),
1008                group_token: group.token,
1009                elem: group.content.parse()?,
1010            })
1011        }
1012    }
1013
1014    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1015    impl Parse for TypeParen {
1016        fn parse(input: ParseStream) -> Result<Self> {
1017            let allow_plus = false;
1018            Self::parse(input, allow_plus)
1019        }
1020    }
1021
1022    impl TypeParen {
1023        fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
1024            let content;
1025            Ok(TypeParen {
1026                attrs: Vec::new(),
1027                paren_token: match crate::__private::parse_parens(&input) {
    crate::__private::Ok(parens) => {
        content = parens.content;
        _ = content;
        parens.token
    }
    crate::__private::Err(error) => { return crate::__private::Err(error); }
}parenthesized!(content in input),
1028                elem: Box::new({
1029                    let allow_group_generic = true;
1030                    ambig_ty(&content, allow_plus, allow_group_generic)?
1031                }),
1032            })
1033        }
1034    }
1035
1036    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1037    impl Parse for NamedArg {
1038        fn parse(input: ParseStream) -> Result<Self> {
1039            let allow_self = false;
1040            parse_fn_ptr_arg(input, allow_self)
1041        }
1042    }
1043
1044    fn parse_fn_ptr_arg(input: ParseStream, allow_self: bool) -> Result<NamedArg> {
1045        let attrs = input.call(Attribute::parse_outer)?;
1046
1047        let begin = input.cursor();
1048
1049        let has_mut_self = allow_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self]);
1050        if has_mut_self {
1051            input.parse::<crate::token::MutToken![mut]>()?;
1052        }
1053
1054        let mut has_self = false;
1055        let mut name = if (input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) || {
1056            has_self = allow_self && input.peek(crate::token::SelfValueToken![self]);
1057            has_self
1058        }) && input.peek2(crate::token::ColonToken![:])
1059            && !input.peek2(crate::token::PathSepToken![::])
1060        {
1061            let name = input.call(Ident::parse_any)?;
1062            let colon: crate::token::ColonToken![:] = input.parse()?;
1063            Some((name, colon))
1064        } else {
1065            has_self = false;
1066            None
1067        };
1068
1069        let ty = if allow_self && !has_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self])
1070        {
1071            input.parse::<crate::token::MutToken![mut]>()?;
1072            input.parse::<crate::token::SelfValueToken![self]>()?;
1073            None
1074        } else if has_mut_self && name.is_none() {
1075            input.parse::<crate::token::SelfValueToken![self]>()?;
1076            None
1077        } else {
1078            Some(input.parse()?)
1079        };
1080
1081        let ty = match ty {
1082            Some(ty) if !has_mut_self => ty,
1083            _ => {
1084                name = None;
1085                Type::Verbatim(verbatim::between(begin, input.cursor()))
1086            }
1087        };
1088
1089        Ok(NamedArg { attrs, name, ty })
1090    }
1091
1092    fn parse_fn_ptr_variadic(input: ParseStream, attrs: Vec<Attribute>) -> Result<FnPtrVariadic> {
1093        Ok(FnPtrVariadic {
1094            attrs,
1095            name: if input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) {
1096                let name = input.call(Ident::parse_any)?;
1097                let colon: crate::token::ColonToken![:] = input.parse()?;
1098                Some((name, colon))
1099            } else {
1100                None
1101            },
1102            dots: input.parse()?,
1103            comma: input.parse()?,
1104        })
1105    }
1106
1107    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1108    impl Parse for Abi {
1109        fn parse(input: ParseStream) -> Result<Self> {
1110            Ok(Abi {
1111                extern_token: input.parse()?,
1112                name: input.parse()?,
1113            })
1114        }
1115    }
1116
1117    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1118    impl Parse for Option<Abi> {
1119        fn parse(input: ParseStream) -> Result<Self> {
1120            if input.peek(crate::token::ExternToken![extern]) {
1121                input.parse().map(Some)
1122            } else {
1123                Ok(None)
1124            }
1125        }
1126    }
1127
1128    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1129    impl Parse for PointerMutability {
1130        fn parse(input: ParseStream) -> Result<Self> {
1131            let lookahead = input.lookahead1();
1132            if lookahead.peek(crate::token::ConstToken![const]) {
1133                Ok(PointerMutability::Const(input.parse()?))
1134            } else if lookahead.peek(crate::token::MutToken![mut]) {
1135                Ok(PointerMutability::Mut(input.parse()?))
1136            } else {
1137                Err(lookahead.error())
1138            }
1139        }
1140    }
1141}
1142
1143#[cfg(feature = "printing")]
1144mod printing {
1145    use crate::attr::FilterAttrs;
1146    use crate::path;
1147    use crate::path::printing::PathStyle;
1148    use crate::ty::{
1149        Abi, FnPtrVariadic, NamedArg, PointerMutability, ReturnType, TypeArray, TypeFnPtr,
1150        TypeGroup, TypeImplTrait, TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr,
1151        TypeReference, TypeSlice, TypeTraitObject, TypeTuple,
1152    };
1153    use proc_macro2::TokenStream;
1154    use quote::{ToTokens, TokenStreamExt as _};
1155
1156    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1157    impl ToTokens for TypeSlice {
1158        fn to_tokens(&self, tokens: &mut TokenStream) {
1159            self.bracket_token.surround(tokens, |tokens| {
1160                self.elem.to_tokens(tokens);
1161            });
1162        }
1163    }
1164
1165    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1166    impl ToTokens for TypeArray {
1167        fn to_tokens(&self, tokens: &mut TokenStream) {
1168            self.bracket_token.surround(tokens, |tokens| {
1169                self.elem.to_tokens(tokens);
1170                self.semi_token.to_tokens(tokens);
1171                self.len.to_tokens(tokens);
1172            });
1173        }
1174    }
1175
1176    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1177    impl ToTokens for TypePtr {
1178        fn to_tokens(&self, tokens: &mut TokenStream) {
1179            self.star_token.to_tokens(tokens);
1180            self.mutability.to_tokens(tokens);
1181            self.elem.to_tokens(tokens);
1182        }
1183    }
1184
1185    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1186    impl ToTokens for TypeReference {
1187        fn to_tokens(&self, tokens: &mut TokenStream) {
1188            self.and_token.to_tokens(tokens);
1189            self.lifetime.to_tokens(tokens);
1190            self.mutability.to_tokens(tokens);
1191            self.elem.to_tokens(tokens);
1192        }
1193    }
1194
1195    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1196    impl ToTokens for TypeFnPtr {
1197        fn to_tokens(&self, tokens: &mut TokenStream) {
1198            self.lifetimes.to_tokens(tokens);
1199            self.unsafety.to_tokens(tokens);
1200            self.abi.to_tokens(tokens);
1201            self.fn_token.to_tokens(tokens);
1202            self.paren_token.surround(tokens, |tokens| {
1203                self.inputs.to_tokens(tokens);
1204                if let Some(variadic) = &self.variadic {
1205                    if !self.inputs.empty_or_trailing() {
1206                        let span = variadic.dots.spans[0];
1207                        crate::token::CommaToken![,](span).to_tokens(tokens);
1208                    }
1209                    variadic.to_tokens(tokens);
1210                }
1211            });
1212            self.output.to_tokens(tokens);
1213        }
1214    }
1215
1216    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1217    impl ToTokens for TypeNever {
1218        fn to_tokens(&self, tokens: &mut TokenStream) {
1219            self.bang_token.to_tokens(tokens);
1220        }
1221    }
1222
1223    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1224    impl ToTokens for TypeTuple {
1225        fn to_tokens(&self, tokens: &mut TokenStream) {
1226            self.paren_token.surround(tokens, |tokens| {
1227                self.elems.to_tokens(tokens);
1228                // If we only have one argument, we need a trailing comma to
1229                // distinguish TypeTuple from TypeParen.
1230                if self.elems.len() == 1 && !self.elems.trailing_punct() {
1231                    <crate::token::CommaToken![,]>::default().to_tokens(tokens);
1232                }
1233            });
1234        }
1235    }
1236
1237    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1238    impl ToTokens for TypePath {
1239        fn to_tokens(&self, tokens: &mut TokenStream) {
1240            path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::AsWritten);
1241        }
1242    }
1243
1244    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1245    impl ToTokens for TypeTraitObject {
1246        fn to_tokens(&self, tokens: &mut TokenStream) {
1247            self.dyn_token.to_tokens(tokens);
1248            self.bounds.to_tokens(tokens);
1249        }
1250    }
1251
1252    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1253    impl ToTokens for TypeImplTrait {
1254        fn to_tokens(&self, tokens: &mut TokenStream) {
1255            self.impl_token.to_tokens(tokens);
1256            self.bounds.to_tokens(tokens);
1257        }
1258    }
1259
1260    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1261    impl ToTokens for TypeGroup {
1262        fn to_tokens(&self, tokens: &mut TokenStream) {
1263            self.group_token.surround(tokens, |tokens| {
1264                self.elem.to_tokens(tokens);
1265            });
1266        }
1267    }
1268
1269    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1270    impl ToTokens for TypeParen {
1271        fn to_tokens(&self, tokens: &mut TokenStream) {
1272            self.paren_token.surround(tokens, |tokens| {
1273                self.elem.to_tokens(tokens);
1274            });
1275        }
1276    }
1277
1278    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1279    impl ToTokens for TypeInfer {
1280        fn to_tokens(&self, tokens: &mut TokenStream) {
1281            self.underscore_token.to_tokens(tokens);
1282        }
1283    }
1284
1285    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1286    impl ToTokens for TypeMacro {
1287        fn to_tokens(&self, tokens: &mut TokenStream) {
1288            self.mac.to_tokens(tokens);
1289        }
1290    }
1291
1292    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1293    impl ToTokens for ReturnType {
1294        fn to_tokens(&self, tokens: &mut TokenStream) {
1295            match self {
1296                ReturnType::Default => {}
1297                ReturnType::Type(arrow, ty) => {
1298                    arrow.to_tokens(tokens);
1299                    ty.to_tokens(tokens);
1300                }
1301            }
1302        }
1303    }
1304
1305    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1306    impl ToTokens for NamedArg {
1307        fn to_tokens(&self, tokens: &mut TokenStream) {
1308            tokens.append_all(self.attrs.outer());
1309            if let Some((name, colon)) = &self.name {
1310                name.to_tokens(tokens);
1311                colon.to_tokens(tokens);
1312            }
1313            self.ty.to_tokens(tokens);
1314        }
1315    }
1316
1317    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1318    impl ToTokens for FnPtrVariadic {
1319        fn to_tokens(&self, tokens: &mut TokenStream) {
1320            tokens.append_all(self.attrs.outer());
1321            if let Some((name, colon)) = &self.name {
1322                name.to_tokens(tokens);
1323                colon.to_tokens(tokens);
1324            }
1325            self.dots.to_tokens(tokens);
1326            self.comma.to_tokens(tokens);
1327        }
1328    }
1329
1330    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1331    impl ToTokens for Abi {
1332        fn to_tokens(&self, tokens: &mut TokenStream) {
1333            self.extern_token.to_tokens(tokens);
1334            self.name.to_tokens(tokens);
1335        }
1336    }
1337
1338    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1339    impl ToTokens for PointerMutability {
1340        fn to_tokens(&self, tokens: &mut TokenStream) {
1341            match self {
1342                PointerMutability::Const(const_token) => const_token.to_tokens(tokens),
1343                PointerMutability::Mut(mut_token) => mut_token.to_tokens(tokens),
1344            }
1345        }
1346    }
1347}