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::parse(input, allow_plus)?;
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(Ident::peek_any)
590                             || input.peek(Token![::])
591                             || input.peek(Token![?])
592                             || input.peek(Lifetime)
593                             || input.peek(token::Paren))
594                         {
595                             break;
596                         }
597                         bounds.push_value(input.parse()?);
598                     }
599                 }
600                 return Ok(Type::TraitObject(TypeTraitObject {
601                     dyn_token: None,
602                     bounds,
603                 }));
604             }
605 
606             Ok(Type::Path(ty))
607         } else if lookahead.peek(token::Bracket) {
608             let content;
609             let bracket_token = bracketed!(content in input);
610             let elem: Type = content.parse()?;
611             if content.peek(Token![;]) {
612                 Ok(Type::Array(TypeArray {
613                     bracket_token,
614                     elem: Box::new(elem),
615                     semi_token: content.parse()?,
616                     len: content.parse()?,
617                 }))
618             } else {
619                 Ok(Type::Slice(TypeSlice {
620                     bracket_token,
621                     elem: Box::new(elem),
622                 }))
623             }
624         } else if lookahead.peek(Token![*]) {
625             input.parse().map(Type::Ptr)
626         } else if lookahead.peek(Token![&]) {
627             input.parse().map(Type::Reference)
628         } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
629             input.parse().map(Type::Never)
630         } else if lookahead.peek(Token![impl]) {
631             TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait)
632         } else if lookahead.peek(Token![_]) {
633             input.parse().map(Type::Infer)
634         } else if lookahead.peek(Lifetime) {
635             input.parse().map(Type::TraitObject)
636         } else {
637             Err(lookahead.error())
638         }
639     }
640 
641     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
642     impl Parse for TypeSlice {
parse(input: ParseStream) -> Result<Self>643         fn parse(input: ParseStream) -> Result<Self> {
644             let content;
645             Ok(TypeSlice {
646                 bracket_token: bracketed!(content in input),
647                 elem: content.parse()?,
648             })
649         }
650     }
651 
652     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
653     impl Parse for TypeArray {
parse(input: ParseStream) -> Result<Self>654         fn parse(input: ParseStream) -> Result<Self> {
655             let content;
656             Ok(TypeArray {
657                 bracket_token: bracketed!(content in input),
658                 elem: content.parse()?,
659                 semi_token: content.parse()?,
660                 len: content.parse()?,
661             })
662         }
663     }
664 
665     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
666     impl Parse for TypePtr {
parse(input: ParseStream) -> Result<Self>667         fn parse(input: ParseStream) -> Result<Self> {
668             let star_token: Token![*] = input.parse()?;
669 
670             let lookahead = input.lookahead1();
671             let (const_token, mutability) = if lookahead.peek(Token![const]) {
672                 (Some(input.parse()?), None)
673             } else if lookahead.peek(Token![mut]) {
674                 (None, Some(input.parse()?))
675             } else {
676                 return Err(lookahead.error());
677             };
678 
679             Ok(TypePtr {
680                 star_token,
681                 const_token,
682                 mutability,
683                 elem: Box::new(input.call(Type::without_plus)?),
684             })
685         }
686     }
687 
688     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
689     impl Parse for TypeReference {
parse(input: ParseStream) -> Result<Self>690         fn parse(input: ParseStream) -> Result<Self> {
691             Ok(TypeReference {
692                 and_token: input.parse()?,
693                 lifetime: input.parse()?,
694                 mutability: input.parse()?,
695                 // & binds tighter than +, so we don't allow + here.
696                 elem: Box::new(input.call(Type::without_plus)?),
697             })
698         }
699     }
700 
701     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
702     impl Parse for TypeBareFn {
parse(input: ParseStream) -> Result<Self>703         fn parse(input: ParseStream) -> Result<Self> {
704             let allow_mut_self = false;
705             parse_bare_fn(input, allow_mut_self).map(Option::unwrap)
706         }
707     }
708 
parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>>709     fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> {
710         let args;
711         let mut variadic = None;
712         let mut has_mut_self = false;
713 
714         let bare_fn = TypeBareFn {
715             lifetimes: input.parse()?,
716             unsafety: input.parse()?,
717             abi: input.parse()?,
718             fn_token: input.parse()?,
719             paren_token: parenthesized!(args in input),
720             inputs: {
721                 let mut inputs = Punctuated::new();
722 
723                 while !args.is_empty() {
724                     let attrs = args.call(Attribute::parse_outer)?;
725 
726                     if inputs.empty_or_trailing() && args.peek(Token![...]) {
727                         variadic = Some(Variadic {
728                             attrs,
729                             dots: args.parse()?,
730                         });
731                         break;
732                     }
733 
734                     if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? {
735                         inputs.push_value(BareFnArg { attrs, ..arg });
736                     } else {
737                         has_mut_self = true;
738                     }
739                     if args.is_empty() {
740                         break;
741                     }
742 
743                     inputs.push_punct(args.parse()?);
744                 }
745 
746                 inputs
747             },
748             variadic,
749             output: input.call(ReturnType::without_plus)?,
750         };
751 
752         if has_mut_self {
753             Ok(None)
754         } else {
755             Ok(Some(bare_fn))
756         }
757     }
758 
759     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
760     impl Parse for TypeNever {
parse(input: ParseStream) -> Result<Self>761         fn parse(input: ParseStream) -> Result<Self> {
762             Ok(TypeNever {
763                 bang_token: input.parse()?,
764             })
765         }
766     }
767 
768     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
769     impl Parse for TypeInfer {
parse(input: ParseStream) -> Result<Self>770         fn parse(input: ParseStream) -> Result<Self> {
771             Ok(TypeInfer {
772                 underscore_token: input.parse()?,
773             })
774         }
775     }
776 
777     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
778     impl Parse for TypeTuple {
parse(input: ParseStream) -> Result<Self>779         fn parse(input: ParseStream) -> Result<Self> {
780             let content;
781             let paren_token = parenthesized!(content in input);
782 
783             if content.is_empty() {
784                 return Ok(TypeTuple {
785                     paren_token,
786                     elems: Punctuated::new(),
787                 });
788             }
789 
790             let first: Type = content.parse()?;
791             Ok(TypeTuple {
792                 paren_token,
793                 elems: {
794                     let mut elems = Punctuated::new();
795                     elems.push_value(first);
796                     elems.push_punct(content.parse()?);
797                     while !content.is_empty() {
798                         elems.push_value(content.parse()?);
799                         if content.is_empty() {
800                             break;
801                         }
802                         elems.push_punct(content.parse()?);
803                     }
804                     elems
805                 },
806             })
807         }
808     }
809 
810     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
811     impl Parse for TypeMacro {
parse(input: ParseStream) -> Result<Self>812         fn parse(input: ParseStream) -> Result<Self> {
813             Ok(TypeMacro {
814                 mac: input.parse()?,
815             })
816         }
817     }
818 
819     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
820     impl Parse for TypePath {
parse(input: ParseStream) -> Result<Self>821         fn parse(input: ParseStream) -> Result<Self> {
822             let (qself, mut path) = path::parsing::qpath(input, false)?;
823 
824             if path.segments.last().unwrap().arguments.is_empty()
825                 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
826             {
827                 input.parse::<Option<Token![::]>>()?;
828                 let args: ParenthesizedGenericArguments = input.parse()?;
829                 let parenthesized = PathArguments::Parenthesized(args);
830                 path.segments.last_mut().unwrap().arguments = parenthesized;
831             }
832 
833             Ok(TypePath { qself, path })
834         }
835     }
836 
837     impl ReturnType {
838         #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
without_plus(input: ParseStream) -> Result<Self>839         pub fn without_plus(input: ParseStream) -> Result<Self> {
840             let allow_plus = false;
841             Self::parse(input, allow_plus)
842         }
843 
parse(input: ParseStream, allow_plus: bool) -> Result<Self>844         pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
845             if input.peek(Token![->]) {
846                 let arrow = input.parse()?;
847                 let ty = ambig_ty(input, allow_plus)?;
848                 Ok(ReturnType::Type(arrow, Box::new(ty)))
849             } else {
850                 Ok(ReturnType::Default)
851             }
852         }
853     }
854 
855     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
856     impl Parse for ReturnType {
parse(input: ParseStream) -> Result<Self>857         fn parse(input: ParseStream) -> Result<Self> {
858             let allow_plus = true;
859             Self::parse(input, allow_plus)
860         }
861     }
862 
863     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
864     impl Parse for TypeTraitObject {
parse(input: ParseStream) -> Result<Self>865         fn parse(input: ParseStream) -> Result<Self> {
866             let allow_plus = true;
867             Self::parse(input, allow_plus)
868         }
869     }
870 
at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool871     fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
872         for bound in bounds {
873             if let TypeParamBound::Trait(_) = *bound {
874                 return true;
875             }
876         }
877         false
878     }
879 
880     impl TypeTraitObject {
881         #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
without_plus(input: ParseStream) -> Result<Self>882         pub fn without_plus(input: ParseStream) -> Result<Self> {
883             let allow_plus = false;
884             Self::parse(input, allow_plus)
885         }
886 
887         // Only allow multiple trait references if allow_plus is true.
parse(input: ParseStream, allow_plus: bool) -> Result<Self>888         pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
889             Ok(TypeTraitObject {
890                 dyn_token: input.parse()?,
891                 bounds: Self::parse_bounds(input, allow_plus)?,
892             })
893         }
894 
parse_bounds( input: ParseStream, allow_plus: bool, ) -> Result<Punctuated<TypeParamBound, Token![+]>>895         fn parse_bounds(
896             input: ParseStream,
897             allow_plus: bool,
898         ) -> Result<Punctuated<TypeParamBound, Token![+]>> {
899             let mut bounds = Punctuated::new();
900             loop {
901                 bounds.push_value(input.parse()?);
902                 if !(allow_plus && input.peek(Token![+])) {
903                     break;
904                 }
905                 bounds.push_punct(input.parse()?);
906                 if !(input.peek(Ident::peek_any)
907                     || input.peek(Token![::])
908                     || input.peek(Token![?])
909                     || input.peek(Lifetime)
910                     || input.peek(token::Paren))
911                 {
912                     break;
913                 }
914             }
915             // Just lifetimes like `'a + 'b` is not a TraitObject.
916             if !at_least_one_type(&bounds) {
917                 return Err(input.error("expected at least one type"));
918             }
919             Ok(bounds)
920         }
921     }
922 
923     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
924     impl Parse for TypeImplTrait {
parse(input: ParseStream) -> Result<Self>925         fn parse(input: ParseStream) -> Result<Self> {
926             let allow_plus = true;
927             Self::parse(input, allow_plus)
928         }
929     }
930 
931     impl TypeImplTrait {
932         #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
without_plus(input: ParseStream) -> Result<Self>933         pub fn without_plus(input: ParseStream) -> Result<Self> {
934             let allow_plus = false;
935             Self::parse(input, allow_plus)
936         }
937 
parse(input: ParseStream, allow_plus: bool) -> Result<Self>938         pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
939             Ok(TypeImplTrait {
940                 impl_token: input.parse()?,
941                 bounds: TypeTraitObject::parse_bounds(input, allow_plus)?,
942             })
943         }
944     }
945 
946     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
947     impl Parse for TypeGroup {
parse(input: ParseStream) -> Result<Self>948         fn parse(input: ParseStream) -> Result<Self> {
949             let group = crate::group::parse_group(input)?;
950             Ok(TypeGroup {
951                 group_token: group.token,
952                 elem: group.content.parse()?,
953             })
954         }
955     }
956 
957     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
958     impl Parse for TypeParen {
parse(input: ParseStream) -> Result<Self>959         fn parse(input: ParseStream) -> Result<Self> {
960             let allow_plus = false;
961             Self::parse(input, allow_plus)
962         }
963     }
964 
965     impl TypeParen {
parse(input: ParseStream, allow_plus: bool) -> Result<Self>966         fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
967             let content;
968             Ok(TypeParen {
969                 paren_token: parenthesized!(content in input),
970                 elem: Box::new(ambig_ty(&content, allow_plus)?),
971             })
972         }
973     }
974 
975     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
976     impl Parse for BareFnArg {
parse(input: ParseStream) -> Result<Self>977         fn parse(input: ParseStream) -> Result<Self> {
978             let allow_mut_self = false;
979             parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap)
980         }
981     }
982 
parse_bare_fn_arg( input: ParseStream, mut allow_mut_self: bool, ) -> Result<Option<BareFnArg>>983     fn parse_bare_fn_arg(
984         input: ParseStream,
985         mut allow_mut_self: bool,
986     ) -> Result<Option<BareFnArg>> {
987         let mut has_mut_self = false;
988         let arg = BareFnArg {
989             attrs: input.call(Attribute::parse_outer)?,
990             name: {
991                 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self]))
992                     && input.peek2(Token![:])
993                     && !input.peek2(Token![::])
994                 {
995                     let name = input.call(Ident::parse_any)?;
996                     let colon: Token![:] = input.parse()?;
997                     Some((name, colon))
998                 } else if allow_mut_self
999                     && input.peek(Token![mut])
1000                     && input.peek2(Token![self])
1001                     && input.peek3(Token![:])
1002                     && !input.peek3(Token![::])
1003                 {
1004                     has_mut_self = true;
1005                     allow_mut_self = false;
1006                     input.parse::<Token![mut]>()?;
1007                     input.parse::<Token![self]>()?;
1008                     input.parse::<Token![:]>()?;
1009                     None
1010                 } else {
1011                     None
1012                 }
1013             },
1014             ty: if !has_mut_self && input.peek(Token![...]) {
1015                 let dot3 = input.parse::<Token![...]>()?;
1016                 let args = vec![
1017                     TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1018                     TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1019                     TokenTree::Punct(Punct::new('.', Spacing::Alone)),
1020                 ];
1021                 let tokens: TokenStream = args
1022                     .into_iter()
1023                     .zip(&dot3.spans)
1024                     .map(|(mut arg, span)| {
1025                         arg.set_span(*span);
1026                         arg
1027                     })
1028                     .collect();
1029                 Type::Verbatim(tokens)
1030             } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) {
1031                 has_mut_self = true;
1032                 input.parse::<Token![mut]>()?;
1033                 Type::Path(TypePath {
1034                     qself: None,
1035                     path: input.parse::<Token![self]>()?.into(),
1036                 })
1037             } else {
1038                 input.parse()?
1039             },
1040         };
1041 
1042         if has_mut_self {
1043             Ok(None)
1044         } else {
1045             Ok(Some(arg))
1046         }
1047     }
1048 
1049     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1050     impl Parse for Abi {
parse(input: ParseStream) -> Result<Self>1051         fn parse(input: ParseStream) -> Result<Self> {
1052             Ok(Abi {
1053                 extern_token: input.parse()?,
1054                 name: input.parse()?,
1055             })
1056         }
1057     }
1058 
1059     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1060     impl Parse for Option<Abi> {
parse(input: ParseStream) -> Result<Self>1061         fn parse(input: ParseStream) -> Result<Self> {
1062             if input.peek(Token![extern]) {
1063                 input.parse().map(Some)
1064             } else {
1065                 Ok(None)
1066             }
1067         }
1068     }
1069 }
1070 
1071 #[cfg(feature = "printing")]
1072 mod printing {
1073     use super::*;
1074     use crate::attr::FilterAttrs;
1075     use crate::print::TokensOrDefault;
1076     use proc_macro2::TokenStream;
1077     use quote::{ToTokens, TokenStreamExt};
1078 
1079     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1080     impl ToTokens for TypeSlice {
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             });
1085         }
1086     }
1087 
1088     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1089     impl ToTokens for TypeArray {
to_tokens(&self, tokens: &mut TokenStream)1090         fn to_tokens(&self, tokens: &mut TokenStream) {
1091             self.bracket_token.surround(tokens, |tokens| {
1092                 self.elem.to_tokens(tokens);
1093                 self.semi_token.to_tokens(tokens);
1094                 self.len.to_tokens(tokens);
1095             });
1096         }
1097     }
1098 
1099     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1100     impl ToTokens for TypePtr {
to_tokens(&self, tokens: &mut TokenStream)1101         fn to_tokens(&self, tokens: &mut TokenStream) {
1102             self.star_token.to_tokens(tokens);
1103             match &self.mutability {
1104                 Some(tok) => tok.to_tokens(tokens),
1105                 None => {
1106                     TokensOrDefault(&self.const_token).to_tokens(tokens);
1107                 }
1108             }
1109             self.elem.to_tokens(tokens);
1110         }
1111     }
1112 
1113     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1114     impl ToTokens for TypeReference {
to_tokens(&self, tokens: &mut TokenStream)1115         fn to_tokens(&self, tokens: &mut TokenStream) {
1116             self.and_token.to_tokens(tokens);
1117             self.lifetime.to_tokens(tokens);
1118             self.mutability.to_tokens(tokens);
1119             self.elem.to_tokens(tokens);
1120         }
1121     }
1122 
1123     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1124     impl ToTokens for TypeBareFn {
to_tokens(&self, tokens: &mut TokenStream)1125         fn to_tokens(&self, tokens: &mut TokenStream) {
1126             self.lifetimes.to_tokens(tokens);
1127             self.unsafety.to_tokens(tokens);
1128             self.abi.to_tokens(tokens);
1129             self.fn_token.to_tokens(tokens);
1130             self.paren_token.surround(tokens, |tokens| {
1131                 self.inputs.to_tokens(tokens);
1132                 if let Some(variadic) = &self.variadic {
1133                     if !self.inputs.empty_or_trailing() {
1134                         let span = variadic.dots.spans[0];
1135                         Token![,](span).to_tokens(tokens);
1136                     }
1137                     variadic.to_tokens(tokens);
1138                 }
1139             });
1140             self.output.to_tokens(tokens);
1141         }
1142     }
1143 
1144     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1145     impl ToTokens for TypeNever {
to_tokens(&self, tokens: &mut TokenStream)1146         fn to_tokens(&self, tokens: &mut TokenStream) {
1147             self.bang_token.to_tokens(tokens);
1148         }
1149     }
1150 
1151     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1152     impl ToTokens for TypeTuple {
to_tokens(&self, tokens: &mut TokenStream)1153         fn to_tokens(&self, tokens: &mut TokenStream) {
1154             self.paren_token.surround(tokens, |tokens| {
1155                 self.elems.to_tokens(tokens);
1156             });
1157         }
1158     }
1159 
1160     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1161     impl ToTokens for TypePath {
to_tokens(&self, tokens: &mut TokenStream)1162         fn to_tokens(&self, tokens: &mut TokenStream) {
1163             private::print_path(tokens, &self.qself, &self.path);
1164         }
1165     }
1166 
1167     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1168     impl ToTokens for TypeTraitObject {
to_tokens(&self, tokens: &mut TokenStream)1169         fn to_tokens(&self, tokens: &mut TokenStream) {
1170             self.dyn_token.to_tokens(tokens);
1171             self.bounds.to_tokens(tokens);
1172         }
1173     }
1174 
1175     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1176     impl ToTokens for TypeImplTrait {
to_tokens(&self, tokens: &mut TokenStream)1177         fn to_tokens(&self, tokens: &mut TokenStream) {
1178             self.impl_token.to_tokens(tokens);
1179             self.bounds.to_tokens(tokens);
1180         }
1181     }
1182 
1183     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1184     impl ToTokens for TypeGroup {
to_tokens(&self, tokens: &mut TokenStream)1185         fn to_tokens(&self, tokens: &mut TokenStream) {
1186             self.group_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 TypeParen {
to_tokens(&self, tokens: &mut TokenStream)1194         fn to_tokens(&self, tokens: &mut TokenStream) {
1195             self.paren_token.surround(tokens, |tokens| {
1196                 self.elem.to_tokens(tokens);
1197             });
1198         }
1199     }
1200 
1201     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1202     impl ToTokens for TypeInfer {
to_tokens(&self, tokens: &mut TokenStream)1203         fn to_tokens(&self, tokens: &mut TokenStream) {
1204             self.underscore_token.to_tokens(tokens);
1205         }
1206     }
1207 
1208     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1209     impl ToTokens for TypeMacro {
to_tokens(&self, tokens: &mut TokenStream)1210         fn to_tokens(&self, tokens: &mut TokenStream) {
1211             self.mac.to_tokens(tokens);
1212         }
1213     }
1214 
1215     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1216     impl ToTokens for ReturnType {
to_tokens(&self, tokens: &mut TokenStream)1217         fn to_tokens(&self, tokens: &mut TokenStream) {
1218             match self {
1219                 ReturnType::Default => {}
1220                 ReturnType::Type(arrow, ty) => {
1221                     arrow.to_tokens(tokens);
1222                     ty.to_tokens(tokens);
1223                 }
1224             }
1225         }
1226     }
1227 
1228     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1229     impl ToTokens for BareFnArg {
to_tokens(&self, tokens: &mut TokenStream)1230         fn to_tokens(&self, tokens: &mut TokenStream) {
1231             tokens.append_all(self.attrs.outer());
1232             if let Some((name, colon)) = &self.name {
1233                 name.to_tokens(tokens);
1234                 colon.to_tokens(tokens);
1235             }
1236             self.ty.to_tokens(tokens);
1237         }
1238     }
1239 
1240     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1241     impl ToTokens for Variadic {
to_tokens(&self, tokens: &mut TokenStream)1242         fn to_tokens(&self, tokens: &mut TokenStream) {
1243             tokens.append_all(self.attrs.outer());
1244             self.dots.to_tokens(tokens);
1245         }
1246     }
1247 
1248     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1249     impl ToTokens for Abi {
to_tokens(&self, tokens: &mut TokenStream)1250         fn to_tokens(&self, tokens: &mut TokenStream) {
1251             self.extern_token.to_tokens(tokens);
1252             self.name.to_tokens(tokens);
1253         }
1254     }
1255 }
1256