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