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"]
#[doc(cfg(any(feature = "full", feature = "derive")))]
#[non_exhaustive]
pub enum Type {

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

    #[doc = r" A bare function type: `fn(usize) -> bool`."]
    BareFn(TypeBareFn),

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