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