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 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) }
}
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]`."]
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`."]
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."]
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."]
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: `_`."]
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."]
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: `!`."]
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."]
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`."]
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`."]
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`."]
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]`."]
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."]
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)`."]
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"`."#]
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`."]
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, ...)`."]
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."]
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;
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.fork();
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 lookahead.peek(Ident)
512            || input.peek(crate::token::SuperToken![super])
513            || input.peek(crate::token::SelfValueToken![self])
514            || input.peek(crate::token::SelfTypeToken![Self])
515            || input.peek(crate::token::CrateToken![crate])
516            || lookahead.peek(crate::token::PathSepToken![::])
517            || lookahead.peek(crate::token::LtToken![<])
518        {
519            let ty: TypePath = input.parse()?;
520            if ty.qself.is_some() {
521                return Ok(Type::Path(ty));
522            }
523
524            if input.peek(crate::token::NotToken![!]) && !input.peek(crate::token::NeToken![!=]) && ty.path.is_mod_style() {
525                let bang_token: crate::token::NotToken![!] = input.parse()?;
526                let (delimiter, tokens) = mac::parse_delimiter(input)?;
527                return Ok(Type::Macro(TypeMacro {
528                    mac: Macro {
529                        path: ty.path,
530                        bang_token,
531                        delimiter,
532                        tokens,
533                    },
534                }));
535            }
536
537            if lifetimes.is_some() || allow_plus && input.peek(crate::token::PlusToken![+]) {
538                let mut bounds = Punctuated::new();
539                bounds.push_value(TypeParamBound::Trait(TraitBound {
540                    paren_token: None,
541                    modifier: TraitBoundModifier::None,
542                    lifetimes,
543                    path: ty.path,
544                }));
545                if allow_plus {
546                    while input.peek(crate::token::PlusToken![+]) {
547                        bounds.push_punct(input.parse()?);
548                        if !(input.peek(Ident::peek_any)
549                            || input.peek(crate::token::PathSepToken![::])
550                            || input.peek(crate::token::QuestionToken![?])
551                            || input.peek(Lifetime)
552                            || input.peek(token::Paren))
553                        {
554                            break;
555                        }
556                        bounds.push_value({
557                            let allow_precise_capture = false;
558                            let allow_const = false;
559                            TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
560                        });
561                    }
562                }
563                return Ok(Type::TraitObject(TypeTraitObject {
564                    dyn_token: None,
565                    bounds,
566                }));
567            }
568
569            Ok(Type::Path(ty))
570        } else if lookahead.peek(crate::token::DynToken![dyn]) {
571            let dyn_token: crate::token::DynToken![dyn] = input.parse()?;
572            let dyn_span = dyn_token.span;
573            let star_token: Option<crate::token::StarToken![*]> = input.parse()?;
574            let bounds = TypeTraitObject::parse_bounds(dyn_span, input, allow_plus)?;
575            Ok(if star_token.is_some() {
576                Type::Verbatim(verbatim::between(&begin, input))
577            } else {
578                Type::TraitObject(TypeTraitObject {
579                    dyn_token: Some(dyn_token),
580                    bounds,
581                })
582            })
583        } else if lookahead.peek(token::Bracket) {
584            let content;
585            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);
586            let elem: Type = content.parse()?;
587            if content.peek(crate::token::SemiToken![;]) {
588                Ok(Type::Array(TypeArray {
589                    bracket_token,
590                    elem: Box::new(elem),
591                    semi_token: content.parse()?,
592                    len: content.parse()?,
593                }))
594            } else {
595                Ok(Type::Slice(TypeSlice {
596                    bracket_token,
597                    elem: Box::new(elem),
598                }))
599            }
600        } else if lookahead.peek(crate::token::StarToken![*]) {
601            input.parse().map(Type::Ptr)
602        } else if lookahead.peek(crate::token::AndToken![&]) {
603            input.parse().map(Type::Reference)
604        } else if lookahead.peek(crate::token::NotToken![!]) && !input.peek(crate::token::EqToken![=]) {
605            input.parse().map(Type::Never)
606        } else if lookahead.peek(crate::token::ImplToken![impl]) {
607            TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
608        } else if lookahead.peek(crate::token::UnderscoreToken![_]) {
609            input.parse().map(Type::Infer)
610        } else if lookahead.peek(Lifetime) {
611            input.parse().map(Type::TraitObject)
612        } else {
613            Err(lookahead.error())
614        }
615    }
616
617    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
618    impl Parse for TypeSlice {
619        fn parse(input: ParseStream) -> Result<Self> {
620            let content;
621            Ok(TypeSlice {
622                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),
623                elem: content.parse()?,
624            })
625        }
626    }
627
628    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
629    impl Parse for TypeArray {
630        fn parse(input: ParseStream) -> Result<Self> {
631            let content;
632            Ok(TypeArray {
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                semi_token: content.parse()?,
636                len: content.parse()?,
637            })
638        }
639    }
640
641    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
642    impl Parse for TypePtr {
643        fn parse(input: ParseStream) -> Result<Self> {
644            let star_token: crate::token::StarToken![*] = input.parse()?;
645
646            let lookahead = input.lookahead1();
647            let (const_token, mutability) = if lookahead.peek(crate::token::ConstToken![const]) {
648                (Some(input.parse()?), None)
649            } else if lookahead.peek(crate::token::MutToken![mut]) {
650                (None, Some(input.parse()?))
651            } else {
652                return Err(lookahead.error());
653            };
654
655            Ok(TypePtr {
656                star_token,
657                const_token,
658                mutability,
659                elem: Box::new(input.call(Type::without_plus)?),
660            })
661        }
662    }
663
664    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
665    impl Parse for TypeReference {
666        fn parse(input: ParseStream) -> Result<Self> {
667            Ok(TypeReference {
668                and_token: input.parse()?,
669                lifetime: input.parse()?,
670                mutability: input.parse()?,
671                // & binds tighter than +, so we don't allow + here.
672                elem: Box::new(input.call(Type::without_plus)?),
673            })
674        }
675    }
676
677    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
678    impl Parse for TypeBareFn {
679        fn parse(input: ParseStream) -> Result<Self> {
680            let args;
681            let mut variadic = None;
682
683            Ok(TypeBareFn {
684                lifetimes: input.parse()?,
685                unsafety: input.parse()?,
686                abi: input.parse()?,
687                fn_token: input.parse()?,
688                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),
689                inputs: {
690                    let mut inputs = Punctuated::new();
691
692                    while !args.is_empty() {
693                        let attrs = args.call(Attribute::parse_outer)?;
694
695                        if inputs.empty_or_trailing()
696                            && (args.peek(crate::token::DotDotDotToken![...])
697                                || (args.peek(Ident) || args.peek(crate::token::UnderscoreToken![_]))
698                                    && args.peek2(crate::token::ColonToken![:])
699                                    && args.peek3(crate::token::DotDotDotToken![...]))
700                        {
701                            variadic = Some(parse_bare_variadic(&args, attrs)?);
702                            break;
703                        }
704
705                        let allow_self = inputs.is_empty();
706                        let arg = parse_bare_fn_arg(&args, allow_self)?;
707                        inputs.push_value(BareFnArg { attrs, ..arg });
708                        if args.is_empty() {
709                            break;
710                        }
711
712                        let comma = args.parse()?;
713                        inputs.push_punct(comma);
714                    }
715
716                    inputs
717                },
718                variadic,
719                output: input.call(ReturnType::without_plus)?,
720            })
721        }
722    }
723
724    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
725    impl Parse for TypeNever {
726        fn parse(input: ParseStream) -> Result<Self> {
727            Ok(TypeNever {
728                bang_token: input.parse()?,
729            })
730        }
731    }
732
733    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
734    impl Parse for TypeInfer {
735        fn parse(input: ParseStream) -> Result<Self> {
736            Ok(TypeInfer {
737                underscore_token: input.parse()?,
738            })
739        }
740    }
741
742    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
743    impl Parse for TypeTuple {
744        fn parse(input: ParseStream) -> Result<Self> {
745            let content;
746            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);
747
748            if content.is_empty() {
749                return Ok(TypeTuple {
750                    paren_token,
751                    elems: Punctuated::new(),
752                });
753            }
754
755            let first: Type = content.parse()?;
756            Ok(TypeTuple {
757                paren_token,
758                elems: {
759                    let mut elems = Punctuated::new();
760                    elems.push_value(first);
761                    elems.push_punct(content.parse()?);
762                    while !content.is_empty() {
763                        elems.push_value(content.parse()?);
764                        if content.is_empty() {
765                            break;
766                        }
767                        elems.push_punct(content.parse()?);
768                    }
769                    elems
770                },
771            })
772        }
773    }
774
775    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
776    impl Parse for TypeMacro {
777        fn parse(input: ParseStream) -> Result<Self> {
778            Ok(TypeMacro {
779                mac: input.parse()?,
780            })
781        }
782    }
783
784    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
785    impl Parse for TypePath {
786        fn parse(input: ParseStream) -> Result<Self> {
787            let expr_style = false;
788            let (qself, path) = path::parsing::qpath(input, expr_style)?;
789            Ok(TypePath { qself, path })
790        }
791    }
792
793    impl ReturnType {
794        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
795        pub fn without_plus(input: ParseStream) -> Result<Self> {
796            let allow_plus = false;
797            Self::parse(input, allow_plus)
798        }
799
800        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
801            if input.peek(crate::token::RArrowToken![->]) {
802                let arrow = input.parse()?;
803                let allow_group_generic = true;
804                let ty = ambig_ty(input, allow_plus, allow_group_generic)?;
805                Ok(ReturnType::Type(arrow, Box::new(ty)))
806            } else {
807                Ok(ReturnType::Default)
808            }
809        }
810    }
811
812    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
813    impl Parse for ReturnType {
814        fn parse(input: ParseStream) -> Result<Self> {
815            let allow_plus = true;
816            Self::parse(input, allow_plus)
817        }
818    }
819
820    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
821    impl Parse for TypeTraitObject {
822        fn parse(input: ParseStream) -> Result<Self> {
823            let allow_plus = true;
824            Self::parse(input, allow_plus)
825        }
826    }
827
828    impl TypeTraitObject {
829        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
830        pub fn without_plus(input: ParseStream) -> Result<Self> {
831            let allow_plus = false;
832            Self::parse(input, allow_plus)
833        }
834
835        // Only allow multiple trait references if allow_plus is true.
836        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
837            let dyn_token: Option<crate::token::DynToken![dyn]> = input.parse()?;
838            let dyn_span = match &dyn_token {
839                Some(token) => token.span,
840                None => input.span(),
841            };
842            let bounds = Self::parse_bounds(dyn_span, input, allow_plus)?;
843            Ok(TypeTraitObject { dyn_token, bounds })
844        }
845
846        fn parse_bounds(
847            dyn_span: Span,
848            input: ParseStream,
849            allow_plus: bool,
850        ) -> Result<Punctuated<TypeParamBound, crate::token::PlusToken![+]>> {
851            let allow_precise_capture = false;
852            let allow_const = false;
853            let bounds = TypeParamBound::parse_multiple(
854                input,
855                allow_plus,
856                allow_precise_capture,
857                allow_const,
858            )?;
859            let mut last_lifetime_span = None;
860            let mut at_least_one_trait = false;
861            for bound in &bounds {
862                match bound {
863                    TypeParamBound::Trait(_) => {
864                        at_least_one_trait = true;
865                        break;
866                    }
867                    TypeParamBound::Lifetime(lifetime) => {
868                        last_lifetime_span = Some(lifetime.ident.span());
869                    }
870                    TypeParamBound::PreciseCapture(_) | TypeParamBound::Verbatim(_) => {
871                        ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
872                    }
873                }
874            }
875            // Just lifetimes like `'a + 'b` is not a TraitObject.
876            if !at_least_one_trait {
877                let msg = "at least one trait is required for an object type";
878                return Err(error::new2(dyn_span, last_lifetime_span.unwrap(), msg));
879            }
880            Ok(bounds)
881        }
882    }
883
884    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
885    impl Parse for TypeImplTrait {
886        fn parse(input: ParseStream) -> Result<Self> {
887            let allow_plus = true;
888            Self::parse(input, allow_plus)
889        }
890    }
891
892    impl TypeImplTrait {
893        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
894        pub fn without_plus(input: ParseStream) -> Result<Self> {
895            let allow_plus = false;
896            Self::parse(input, allow_plus)
897        }
898
899        pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
900            let impl_token: crate::token::ImplToken![impl] = input.parse()?;
901            let allow_precise_capture = true;
902            let allow_const = true;
903            let bounds = TypeParamBound::parse_multiple(
904                input,
905                allow_plus,
906                allow_precise_capture,
907                allow_const,
908            )?;
909            let mut last_nontrait_span = None;
910            let mut at_least_one_trait = false;
911            for bound in &bounds {
912                match bound {
913                    TypeParamBound::Trait(_) => {
914                        at_least_one_trait = true;
915                        break;
916                    }
917                    TypeParamBound::Lifetime(lifetime) => {
918                        last_nontrait_span = Some(lifetime.ident.span());
919                    }
920                    TypeParamBound::PreciseCapture(precise_capture) => {
921                        #[cfg(feature = "full")]
922                        {
923                            last_nontrait_span = Some(precise_capture.gt_token.span);
924                        }
925                        #[cfg(not(feature = "full"))]
926                        {
927                            _ = precise_capture;
928                            unreachable!();
929                        }
930                    }
931                    TypeParamBound::Verbatim(_) => {
932                        // `[const] Trait`
933                        at_least_one_trait = true;
934                        break;
935                    }
936                }
937            }
938            if !at_least_one_trait {
939                let msg = "at least one trait must be specified";
940                return Err(error::new2(
941                    impl_token.span,
942                    last_nontrait_span.unwrap(),
943                    msg,
944                ));
945            }
946            Ok(TypeImplTrait { impl_token, bounds })
947        }
948    }
949
950    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
951    impl Parse for TypeGroup {
952        fn parse(input: ParseStream) -> Result<Self> {
953            let group = crate::group::parse_group(input)?;
954            Ok(TypeGroup {
955                group_token: group.token,
956                elem: group.content.parse()?,
957            })
958        }
959    }
960
961    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
962    impl Parse for TypeParen {
963        fn parse(input: ParseStream) -> Result<Self> {
964            let allow_plus = false;
965            Self::parse(input, allow_plus)
966        }
967    }
968
969    impl TypeParen {
970        fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
971            let content;
972            Ok(TypeParen {
973                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),
974                elem: Box::new({
975                    let allow_group_generic = true;
976                    ambig_ty(&content, allow_plus, allow_group_generic)?
977                }),
978            })
979        }
980    }
981
982    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
983    impl Parse for BareFnArg {
984        fn parse(input: ParseStream) -> Result<Self> {
985            let allow_self = false;
986            parse_bare_fn_arg(input, allow_self)
987        }
988    }
989
990    fn parse_bare_fn_arg(input: ParseStream, allow_self: bool) -> Result<BareFnArg> {
991        let attrs = input.call(Attribute::parse_outer)?;
992
993        let begin = input.fork();
994
995        let has_mut_self = allow_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self]);
996        if has_mut_self {
997            input.parse::<crate::token::MutToken![mut]>()?;
998        }
999
1000        let mut has_self = false;
1001        let mut name = if (input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) || {
1002            has_self = allow_self && input.peek(crate::token::SelfValueToken![self]);
1003            has_self
1004        }) && input.peek2(crate::token::ColonToken![:])
1005            && !input.peek2(crate::token::PathSepToken![::])
1006        {
1007            let name = input.call(Ident::parse_any)?;
1008            let colon: crate::token::ColonToken![:] = input.parse()?;
1009            Some((name, colon))
1010        } else {
1011            has_self = false;
1012            None
1013        };
1014
1015        let ty = if allow_self && !has_self && input.peek(crate::token::MutToken![mut]) && input.peek2(crate::token::SelfValueToken![self])
1016        {
1017            input.parse::<crate::token::MutToken![mut]>()?;
1018            input.parse::<crate::token::SelfValueToken![self]>()?;
1019            None
1020        } else if has_mut_self && name.is_none() {
1021            input.parse::<crate::token::SelfValueToken![self]>()?;
1022            None
1023        } else {
1024            Some(input.parse()?)
1025        };
1026
1027        let ty = match ty {
1028            Some(ty) if !has_mut_self => ty,
1029            _ => {
1030                name = None;
1031                Type::Verbatim(verbatim::between(&begin, input))
1032            }
1033        };
1034
1035        Ok(BareFnArg { attrs, name, ty })
1036    }
1037
1038    fn parse_bare_variadic(input: ParseStream, attrs: Vec<Attribute>) -> Result<BareVariadic> {
1039        Ok(BareVariadic {
1040            attrs,
1041            name: if input.peek(Ident) || input.peek(crate::token::UnderscoreToken![_]) {
1042                let name = input.call(Ident::parse_any)?;
1043                let colon: crate::token::ColonToken![:] = input.parse()?;
1044                Some((name, colon))
1045            } else {
1046                None
1047            },
1048            dots: input.parse()?,
1049            comma: input.parse()?,
1050        })
1051    }
1052
1053    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1054    impl Parse for Abi {
1055        fn parse(input: ParseStream) -> Result<Self> {
1056            Ok(Abi {
1057                extern_token: input.parse()?,
1058                name: input.parse()?,
1059            })
1060        }
1061    }
1062
1063    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1064    impl Parse for Option<Abi> {
1065        fn parse(input: ParseStream) -> Result<Self> {
1066            if input.peek(crate::token::ExternToken![extern]) {
1067                input.parse().map(Some)
1068            } else {
1069                Ok(None)
1070            }
1071        }
1072    }
1073}
1074
1075#[cfg(feature = "printing")]
1076mod printing {
1077    use crate::attr::FilterAttrs;
1078    use crate::path;
1079    use crate::path::printing::PathStyle;
1080    use crate::print::TokensOrDefault;
1081    use crate::ty::{
1082        Abi, BareFnArg, BareVariadic, ReturnType, TypeArray, TypeBareFn, TypeGroup, TypeImplTrait,
1083        TypeInfer, TypeMacro, TypeNever, TypeParen, TypePath, TypePtr, TypeReference, TypeSlice,
1084        TypeTraitObject, TypeTuple,
1085    };
1086    use proc_macro2::TokenStream;
1087    use quote::{ToTokens, TokenStreamExt as _};
1088
1089    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1090    impl ToTokens for TypeSlice {
1091        fn to_tokens(&self, tokens: &mut TokenStream) {
1092            self.bracket_token.surround(tokens, |tokens| {
1093                self.elem.to_tokens(tokens);
1094            });
1095        }
1096    }
1097
1098    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1099    impl ToTokens for TypeArray {
1100        fn to_tokens(&self, tokens: &mut TokenStream) {
1101            self.bracket_token.surround(tokens, |tokens| {
1102                self.elem.to_tokens(tokens);
1103                self.semi_token.to_tokens(tokens);
1104                self.len.to_tokens(tokens);
1105            });
1106        }
1107    }
1108
1109    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1110    impl ToTokens for TypePtr {
1111        fn to_tokens(&self, tokens: &mut TokenStream) {
1112            self.star_token.to_tokens(tokens);
1113            match &self.mutability {
1114                Some(tok) => tok.to_tokens(tokens),
1115                None => {
1116                    TokensOrDefault(&self.const_token).to_tokens(tokens);
1117                }
1118            }
1119            self.elem.to_tokens(tokens);
1120        }
1121    }
1122
1123    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1124    impl ToTokens for TypeReference {
1125        fn to_tokens(&self, tokens: &mut TokenStream) {
1126            self.and_token.to_tokens(tokens);
1127            self.lifetime.to_tokens(tokens);
1128            self.mutability.to_tokens(tokens);
1129            self.elem.to_tokens(tokens);
1130        }
1131    }
1132
1133    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1134    impl ToTokens for TypeBareFn {
1135        fn to_tokens(&self, tokens: &mut TokenStream) {
1136            self.lifetimes.to_tokens(tokens);
1137            self.unsafety.to_tokens(tokens);
1138            self.abi.to_tokens(tokens);
1139            self.fn_token.to_tokens(tokens);
1140            self.paren_token.surround(tokens, |tokens| {
1141                self.inputs.to_tokens(tokens);
1142                if let Some(variadic) = &self.variadic {
1143                    if !self.inputs.empty_or_trailing() {
1144                        let span = variadic.dots.spans[0];
1145                        crate::token::CommaToken![,](span).to_tokens(tokens);
1146                    }
1147                    variadic.to_tokens(tokens);
1148                }
1149            });
1150            self.output.to_tokens(tokens);
1151        }
1152    }
1153
1154    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1155    impl ToTokens for TypeNever {
1156        fn to_tokens(&self, tokens: &mut TokenStream) {
1157            self.bang_token.to_tokens(tokens);
1158        }
1159    }
1160
1161    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1162    impl ToTokens for TypeTuple {
1163        fn to_tokens(&self, tokens: &mut TokenStream) {
1164            self.paren_token.surround(tokens, |tokens| {
1165                self.elems.to_tokens(tokens);
1166                // If we only have one argument, we need a trailing comma to
1167                // distinguish TypeTuple from TypeParen.
1168                if self.elems.len() == 1 && !self.elems.trailing_punct() {
1169                    <crate::token::CommaToken![,]>::default().to_tokens(tokens);
1170                }
1171            });
1172        }
1173    }
1174
1175    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1176    impl ToTokens for TypePath {
1177        fn to_tokens(&self, tokens: &mut TokenStream) {
1178            path::printing::print_qpath(tokens, &self.qself, &self.path, PathStyle::AsWritten);
1179        }
1180    }
1181
1182    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1183    impl ToTokens for TypeTraitObject {
1184        fn to_tokens(&self, tokens: &mut TokenStream) {
1185            self.dyn_token.to_tokens(tokens);
1186            self.bounds.to_tokens(tokens);
1187        }
1188    }
1189
1190    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1191    impl ToTokens for TypeImplTrait {
1192        fn to_tokens(&self, tokens: &mut TokenStream) {
1193            self.impl_token.to_tokens(tokens);
1194            self.bounds.to_tokens(tokens);
1195        }
1196    }
1197
1198    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1199    impl ToTokens for TypeGroup {
1200        fn to_tokens(&self, tokens: &mut TokenStream) {
1201            self.group_token.surround(tokens, |tokens| {
1202                self.elem.to_tokens(tokens);
1203            });
1204        }
1205    }
1206
1207    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1208    impl ToTokens for TypeParen {
1209        fn to_tokens(&self, tokens: &mut TokenStream) {
1210            self.paren_token.surround(tokens, |tokens| {
1211                self.elem.to_tokens(tokens);
1212            });
1213        }
1214    }
1215
1216    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1217    impl ToTokens for TypeInfer {
1218        fn to_tokens(&self, tokens: &mut TokenStream) {
1219            self.underscore_token.to_tokens(tokens);
1220        }
1221    }
1222
1223    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1224    impl ToTokens for TypeMacro {
1225        fn to_tokens(&self, tokens: &mut TokenStream) {
1226            self.mac.to_tokens(tokens);
1227        }
1228    }
1229
1230    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1231    impl ToTokens for ReturnType {
1232        fn to_tokens(&self, tokens: &mut TokenStream) {
1233            match self {
1234                ReturnType::Default => {}
1235                ReturnType::Type(arrow, ty) => {
1236                    arrow.to_tokens(tokens);
1237                    ty.to_tokens(tokens);
1238                }
1239            }
1240        }
1241    }
1242
1243    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1244    impl ToTokens for BareFnArg {
1245        fn to_tokens(&self, tokens: &mut TokenStream) {
1246            tokens.append_all(self.attrs.outer());
1247            if let Some((name, colon)) = &self.name {
1248                name.to_tokens(tokens);
1249                colon.to_tokens(tokens);
1250            }
1251            self.ty.to_tokens(tokens);
1252        }
1253    }
1254
1255    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1256    impl ToTokens for BareVariadic {
1257        fn to_tokens(&self, tokens: &mut TokenStream) {
1258            tokens.append_all(self.attrs.outer());
1259            if let Some((name, colon)) = &self.name {
1260                name.to_tokens(tokens);
1261                colon.to_tokens(tokens);
1262            }
1263            self.dots.to_tokens(tokens);
1264            self.comma.to_tokens(tokens);
1265        }
1266    }
1267
1268    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1269    impl ToTokens for Abi {
1270        fn to_tokens(&self, tokens: &mut TokenStream) {
1271            self.extern_token.to_tokens(tokens);
1272            self.name.to_tokens(tokens);
1273        }
1274    }
1275}