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             {
416                 return Err(lookahead.error());
417             }
418         }
419 
420         if lookahead.peek(token::Paren) {
421             let content;
422             let paren_token = parenthesized!(content in input);
423             if content.is_empty() {
424                 return Ok(Type::Tuple(TypeTuple {
425                     paren_token,
426                     elems: Punctuated::new(),
427                 }));
428             }
429             if content.peek(Lifetime) {
430                 return Ok(Type::Paren(TypeParen {
431                     paren_token,
432                     elem: Box::new(Type::TraitObject(content.parse()?)),
433                 }));
434             }
435             if content.peek(Token![?]) {
436                 return Ok(Type::TraitObject(TypeTraitObject {
437                     dyn_token: None,
438                     bounds: {
439                         let mut bounds = Punctuated::new();
440                         bounds.push_value(TypeParamBound::Trait(TraitBound {
441                             paren_token: Some(paren_token),
442                             ..content.parse()?
443                         }));
444                         while let Some(plus) = input.parse()? {
445                             bounds.push_punct(plus);
446                             bounds.push_value(input.parse()?);
447                         }
448                         bounds
449                     },
450                 }));
451             }
452             let mut first: Type = content.parse()?;
453             if content.peek(Token![,]) {
454                 return Ok(Type::Tuple(TypeTuple {
455                     paren_token,
456                     elems: {
457                         let mut elems = Punctuated::new();
458                         elems.push_value(first);
459                         elems.push_punct(content.parse()?);
460                         while !content.is_empty() {
461                             elems.push_value(content.parse()?);
462                             if content.is_empty() {
463                                 break;
464                             }
465                             elems.push_punct(content.parse()?);
466                         }
467                         elems
468                     },
469                 }));
470             }
471             if allow_plus && input.peek(Token![+]) {
472                 loop {
473                     let first = match first {
474                         Type::Path(TypePath { qself: None, path }) => {
475                             TypeParamBound::Trait(TraitBound {
476                                 paren_token: Some(paren_token),
477                                 modifier: TraitBoundModifier::None,
478                                 lifetimes: None,
479                                 path,
480                             })
481                         }
482                         Type::TraitObject(TypeTraitObject {
483                             dyn_token: None,
484                             bounds,
485                         }) => {
486                             if bounds.len() > 1 || bounds.trailing_punct() {
487                                 first = Type::TraitObject(TypeTraitObject {
488                                     dyn_token: None,
489                                     bounds,
490                                 });
491                                 break;
492                             }
493                             match bounds.into_iter().next().unwrap() {
494                                 TypeParamBound::Trait(trait_bound) => {
495                                     TypeParamBound::Trait(TraitBound {
496                                         paren_token: Some(paren_token),
497                                         ..trait_bound
498                                     })
499                                 }
500                                 other @ TypeParamBound::Lifetime(_) => other,
501                             }
502                         }
503                         _ => break,
504                     };
505                     return Ok(Type::TraitObject(TypeTraitObject {
506                         dyn_token: None,
507                         bounds: {
508                             let mut bounds = Punctuated::new();
509                             bounds.push_value(first);
510                             while let Some(plus) = input.parse()? {
511                                 bounds.push_punct(plus);
512                                 bounds.push_value(input.parse()?);
513                             }
514                             bounds
515                         },
516                     }));
517                 }
518             }
519             Ok(Type::Paren(TypeParen {
520                 paren_token,
521                 elem: Box::new(first),
522             }))
523         } else if lookahead.peek(Token![fn])
524             || lookahead.peek(Token![unsafe])
525             || lookahead.peek(Token![extern])
526         {
527             let allow_mut_self = true;
528             if let Some(mut bare_fn) = parse_bare_fn(input, allow_mut_self)? {
529                 bare_fn.lifetimes = lifetimes;
530                 Ok(Type::BareFn(bare_fn))
531             } else {
532                 Ok(Type::Verbatim(verbatim::between(begin, input)))
533             }
534         } else if lookahead.peek(Ident)
535             || input.peek(Token![super])
536             || input.peek(Token![self])
537             || input.peek(Token![Self])
538             || input.peek(Token![crate])
539             || lookahead.peek(Token![::])
540             || lookahead.peek(Token![<])
541         {
542             if input.peek(Token![dyn]) {
543                 let mut trait_object: TypeTraitObject = input.parse()?;
544                 if lifetimes.is_some() {
545                     match trait_object.bounds.iter_mut().next().unwrap() {
546                         TypeParamBound::Trait(trait_bound) => {
547                             trait_bound.lifetimes = lifetimes;
548                         }
549                         TypeParamBound::Lifetime(_) => unreachable!(),
550                     }
551                 }
552                 return Ok(Type::TraitObject(trait_object));
553             }
554 
555             let ty: TypePath = input.parse()?;
556             if ty.qself.is_some() {
557                 return Ok(Type::Path(ty));
558             }
559 
560             if input.peek(Token![!]) && !input.peek(Token![!=]) {
561                 let mut contains_arguments = false;
562                 for segment in &ty.path.segments {
563                     match segment.arguments {
564                         PathArguments::None => {}
565                         PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => {
566                             contains_arguments = true;
567                         }
568                     }
569                 }
570 
571                 if !contains_arguments {
572                     let bang_token: Token![!] = input.parse()?;
573                     let (delimiter, tokens) = mac::parse_delimiter(input)?;
574                     return Ok(Type::Macro(TypeMacro {
575                         mac: Macro {
576                             path: ty.path,
577                             bang_token,
578                             delimiter,
579                             tokens,
580                         },
581                     }));
582                 }
583             }
584 
585             if lifetimes.is_some() || allow_plus && input.peek(Token![+]) {
586                 let mut bounds = Punctuated::new();
587                 bounds.push_value(TypeParamBound::Trait(TraitBound {
588                     paren_token: None,
589                     modifier: TraitBoundModifier::None,
590                     lifetimes,
591                     path: ty.path,
592                 }));
593                 if allow_plus {
594                     while input.peek(Token![+]) {
595                         bounds.push_punct(input.parse()?);
596                         if input.peek(Token![>]) {
597                             break;
598                         }
599                         bounds.push_value(input.parse()?);
600                     }
601                 }
602                 return Ok(Type::TraitObject(TypeTraitObject {
603                     dyn_token: None,
604                     bounds,
605                 }));
606             }
607 
608             Ok(Type::Path(ty))
609         } else if lookahead.peek(token::Bracket) {
610             let content;
611             let bracket_token = bracketed!(content in input);
612             let elem: Type = content.parse()?;
613             if content.peek(Token![;]) {
614                 Ok(Type::Array(TypeArray {
615                     bracket_token,
616                     elem: Box::new(elem),
617                     semi_token: content.parse()?,
618                     len: content.parse()?,
619                 }))
620             } else {
621                 Ok(Type::Slice(TypeSlice {
622                     bracket_token,
623                     elem: Box::new(elem),
624                 }))
625             }
626         } else if lookahead.peek(Token![*]) {
627             input.parse().map(Type::Ptr)
628         } else if lookahead.peek(Token![&]) {
629             input.parse().map(Type::Reference)
630         } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) {
631             input.parse().map(Type::Never)
632         } else if lookahead.peek(Token![impl]) {
633             input.parse().map(Type::ImplTrait)
634         } else if lookahead.peek(Token![_]) {
635             input.parse().map(Type::Infer)
636         } else if lookahead.peek(Lifetime) {
637             input.parse().map(Type::TraitObject)
638         } else {
639             Err(lookahead.error())
640         }
641     }
642 
643     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
644     impl Parse for TypeSlice {
parse(input: ParseStream) -> Result<Self>645         fn parse(input: ParseStream) -> Result<Self> {
646             let content;
647             Ok(TypeSlice {
648                 bracket_token: bracketed!(content in input),
649                 elem: content.parse()?,
650             })
651         }
652     }
653 
654     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
655     impl Parse for TypeArray {
parse(input: ParseStream) -> Result<Self>656         fn parse(input: ParseStream) -> Result<Self> {
657             let content;
658             Ok(TypeArray {
659                 bracket_token: bracketed!(content in input),
660                 elem: content.parse()?,
661                 semi_token: content.parse()?,
662                 len: content.parse()?,
663             })
664         }
665     }
666 
667     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
668     impl Parse for TypePtr {
parse(input: ParseStream) -> Result<Self>669         fn parse(input: ParseStream) -> Result<Self> {
670             let star_token: Token![*] = input.parse()?;
671 
672             let lookahead = input.lookahead1();
673             let (const_token, mutability) = if lookahead.peek(Token![const]) {
674                 (Some(input.parse()?), None)
675             } else if lookahead.peek(Token![mut]) {
676                 (None, Some(input.parse()?))
677             } else {
678                 return Err(lookahead.error());
679             };
680 
681             Ok(TypePtr {
682                 star_token,
683                 const_token,
684                 mutability,
685                 elem: Box::new(input.call(Type::without_plus)?),
686             })
687         }
688     }
689 
690     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
691     impl Parse for TypeReference {
parse(input: ParseStream) -> Result<Self>692         fn parse(input: ParseStream) -> Result<Self> {
693             Ok(TypeReference {
694                 and_token: input.parse()?,
695                 lifetime: input.parse()?,
696                 mutability: input.parse()?,
697                 // & binds tighter than +, so we don't allow + here.
698                 elem: Box::new(input.call(Type::without_plus)?),
699             })
700         }
701     }
702 
703     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
704     impl Parse for TypeBareFn {
parse(input: ParseStream) -> Result<Self>705         fn parse(input: ParseStream) -> Result<Self> {
706             let allow_mut_self = false;
707             parse_bare_fn(input, allow_mut_self).map(Option::unwrap)
708         }
709     }
710 
parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>>711     fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> {
712         let args;
713         let mut variadic = None;
714         let mut has_mut_self = false;
715 
716         let bare_fn = TypeBareFn {
717             lifetimes: input.parse()?,
718             unsafety: input.parse()?,
719             abi: input.parse()?,
720             fn_token: input.parse()?,
721             paren_token: parenthesized!(args in input),
722             inputs: {
723                 let mut inputs = Punctuated::new();
724 
725                 while !args.is_empty() {
726                     let attrs = args.call(Attribute::parse_outer)?;
727 
728                     if inputs.empty_or_trailing() && args.peek(Token![...]) {
729                         variadic = Some(Variadic {
730                             attrs,
731                             dots: args.parse()?,
732                         });
733                         break;
734                     }
735 
736                     if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? {
737                         inputs.push_value(BareFnArg { attrs, ..arg });
738                     } else {
739                         has_mut_self = true;
740                     }
741                     if args.is_empty() {
742                         break;
743                     }
744 
745                     inputs.push_punct(args.parse()?);
746                 }
747 
748                 inputs
749             },
750             variadic,
751             output: input.call(ReturnType::without_plus)?,
752         };
753 
754         if has_mut_self {
755             Ok(None)
756         } else {
757             Ok(Some(bare_fn))
758         }
759     }
760 
761     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
762     impl Parse for TypeNever {
parse(input: ParseStream) -> Result<Self>763         fn parse(input: ParseStream) -> Result<Self> {
764             Ok(TypeNever {
765                 bang_token: input.parse()?,
766             })
767         }
768     }
769 
770     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
771     impl Parse for TypeInfer {
parse(input: ParseStream) -> Result<Self>772         fn parse(input: ParseStream) -> Result<Self> {
773             Ok(TypeInfer {
774                 underscore_token: input.parse()?,
775             })
776         }
777     }
778 
779     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
780     impl Parse for TypeTuple {
parse(input: ParseStream) -> Result<Self>781         fn parse(input: ParseStream) -> Result<Self> {
782             let content;
783             let paren_token = parenthesized!(content in input);
784 
785             if content.is_empty() {
786                 return Ok(TypeTuple {
787                     paren_token,
788                     elems: Punctuated::new(),
789                 });
790             }
791 
792             let first: Type = content.parse()?;
793             Ok(TypeTuple {
794                 paren_token,
795                 elems: {
796                     let mut elems = Punctuated::new();
797                     elems.push_value(first);
798                     elems.push_punct(content.parse()?);
799                     while !content.is_empty() {
800                         elems.push_value(content.parse()?);
801                         if content.is_empty() {
802                             break;
803                         }
804                         elems.push_punct(content.parse()?);
805                     }
806                     elems
807                 },
808             })
809         }
810     }
811 
812     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
813     impl Parse for TypeMacro {
parse(input: ParseStream) -> Result<Self>814         fn parse(input: ParseStream) -> Result<Self> {
815             Ok(TypeMacro {
816                 mac: input.parse()?,
817             })
818         }
819     }
820 
821     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
822     impl Parse for TypePath {
parse(input: ParseStream) -> Result<Self>823         fn parse(input: ParseStream) -> Result<Self> {
824             let (qself, mut path) = path::parsing::qpath(input, false)?;
825 
826             if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) {
827                 let args: ParenthesizedGenericArguments = input.parse()?;
828                 let parenthesized = PathArguments::Parenthesized(args);
829                 path.segments.last_mut().unwrap().arguments = parenthesized;
830             }
831 
832             Ok(TypePath { qself, path })
833         }
834     }
835 
836     impl ReturnType {
without_plus(input: ParseStream) -> Result<Self>837         pub fn without_plus(input: ParseStream) -> Result<Self> {
838             let allow_plus = false;
839             Self::parse(input, allow_plus)
840         }
841 
842         #[doc(hidden)]
parse(input: ParseStream, allow_plus: bool) -> Result<Self>843         pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
844             if input.peek(Token![->]) {
845                 let arrow = input.parse()?;
846                 let ty = ambig_ty(input, allow_plus)?;
847                 Ok(ReturnType::Type(arrow, Box::new(ty)))
848             } else {
849                 Ok(ReturnType::Default)
850             }
851         }
852     }
853 
854     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
855     impl Parse for ReturnType {
parse(input: ParseStream) -> Result<Self>856         fn parse(input: ParseStream) -> Result<Self> {
857             Self::parse(input, true)
858         }
859     }
860 
861     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
862     impl Parse for TypeTraitObject {
parse(input: ParseStream) -> Result<Self>863         fn parse(input: ParseStream) -> Result<Self> {
864             Self::parse(input, true)
865         }
866     }
867 
at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool868     fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool {
869         for bound in bounds {
870             if let TypeParamBound::Trait(_) = *bound {
871                 return true;
872             }
873         }
874         false
875     }
876 
877     impl TypeTraitObject {
without_plus(input: ParseStream) -> Result<Self>878         pub fn without_plus(input: ParseStream) -> Result<Self> {
879             let allow_plus = false;
880             Self::parse(input, allow_plus)
881         }
882 
883         // Only allow multiple trait references if allow_plus is true.
884         #[doc(hidden)]
parse(input: ParseStream, allow_plus: bool) -> Result<Self>885         pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
886             Ok(TypeTraitObject {
887                 dyn_token: input.parse()?,
888                 bounds: {
889                     let mut bounds = Punctuated::new();
890                     if allow_plus {
891                         loop {
892                             bounds.push_value(input.parse()?);
893                             if !input.peek(Token![+]) {
894                                 break;
895                             }
896                             bounds.push_punct(input.parse()?);
897                             if input.peek(Token![>]) {
898                                 break;
899                             }
900                         }
901                     } else {
902                         bounds.push_value(input.parse()?);
903                     }
904                     // Just lifetimes like `'a + 'b` is not a TraitObject.
905                     if !at_least_one_type(&bounds) {
906                         return Err(input.error("expected at least one type"));
907                     }
908                     bounds
909                 },
910             })
911         }
912     }
913 
914     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
915     impl Parse for TypeImplTrait {
parse(input: ParseStream) -> Result<Self>916         fn parse(input: ParseStream) -> Result<Self> {
917             Ok(TypeImplTrait {
918                 impl_token: input.parse()?,
919                 // NOTE: rust-lang/rust#34511 includes discussion about whether
920                 // or not + should be allowed in ImplTrait directly without ().
921                 bounds: {
922                     let mut bounds = Punctuated::new();
923                     loop {
924                         bounds.push_value(input.parse()?);
925                         if !input.peek(Token![+]) {
926                             break;
927                         }
928                         bounds.push_punct(input.parse()?);
929                     }
930                     bounds
931                 },
932             })
933         }
934     }
935 
936     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
937     impl Parse for TypeGroup {
parse(input: ParseStream) -> Result<Self>938         fn parse(input: ParseStream) -> Result<Self> {
939             let group = crate::group::parse_group(input)?;
940             Ok(TypeGroup {
941                 group_token: group.token,
942                 elem: group.content.parse()?,
943             })
944         }
945     }
946 
947     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
948     impl Parse for TypeParen {
parse(input: ParseStream) -> Result<Self>949         fn parse(input: ParseStream) -> Result<Self> {
950             let allow_plus = false;
951             Self::parse(input, allow_plus)
952         }
953     }
954 
955     impl TypeParen {
parse(input: ParseStream, allow_plus: bool) -> Result<Self>956         fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> {
957             let content;
958             Ok(TypeParen {
959                 paren_token: parenthesized!(content in input),
960                 elem: Box::new(ambig_ty(&content, allow_plus)?),
961             })
962         }
963     }
964 
965     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
966     impl Parse for BareFnArg {
parse(input: ParseStream) -> Result<Self>967         fn parse(input: ParseStream) -> Result<Self> {
968             let allow_mut_self = false;
969             parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap)
970         }
971     }
972 
parse_bare_fn_arg( input: ParseStream, mut allow_mut_self: bool, ) -> Result<Option<BareFnArg>>973     fn parse_bare_fn_arg(
974         input: ParseStream,
975         mut allow_mut_self: bool,
976     ) -> Result<Option<BareFnArg>> {
977         let mut has_mut_self = false;
978         let arg = BareFnArg {
979             attrs: input.call(Attribute::parse_outer)?,
980             name: {
981                 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self]))
982                     && input.peek2(Token![:])
983                     && !input.peek2(Token![::])
984                 {
985                     let name = input.call(Ident::parse_any)?;
986                     let colon: Token![:] = input.parse()?;
987                     Some((name, colon))
988                 } else if allow_mut_self
989                     && input.peek(Token![mut])
990                     && input.peek2(Token![self])
991                     && input.peek3(Token![:])
992                     && !input.peek3(Token![::])
993                 {
994                     has_mut_self = true;
995                     allow_mut_self = false;
996                     input.parse::<Token![mut]>()?;
997                     input.parse::<Token![self]>()?;
998                     input.parse::<Token![:]>()?;
999                     None
1000                 } else {
1001                     None
1002                 }
1003             },
1004             ty: if !has_mut_self && input.peek(Token![...]) {
1005                 let dot3 = input.parse::<Token![...]>()?;
1006                 let args = vec![
1007                     TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1008                     TokenTree::Punct(Punct::new('.', Spacing::Joint)),
1009                     TokenTree::Punct(Punct::new('.', Spacing::Alone)),
1010                 ];
1011                 let tokens: TokenStream = args
1012                     .into_iter()
1013                     .zip(&dot3.spans)
1014                     .map(|(mut arg, span)| {
1015                         arg.set_span(*span);
1016                         arg
1017                     })
1018                     .collect();
1019                 Type::Verbatim(tokens)
1020             } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) {
1021                 has_mut_self = true;
1022                 input.parse::<Token![mut]>()?;
1023                 Type::Path(TypePath {
1024                     qself: None,
1025                     path: input.parse::<Token![self]>()?.into(),
1026                 })
1027             } else {
1028                 input.parse()?
1029             },
1030         };
1031 
1032         if has_mut_self {
1033             Ok(None)
1034         } else {
1035             Ok(Some(arg))
1036         }
1037     }
1038 
1039     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1040     impl Parse for Abi {
parse(input: ParseStream) -> Result<Self>1041         fn parse(input: ParseStream) -> Result<Self> {
1042             Ok(Abi {
1043                 extern_token: input.parse()?,
1044                 name: input.parse()?,
1045             })
1046         }
1047     }
1048 
1049     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
1050     impl Parse for Option<Abi> {
parse(input: ParseStream) -> Result<Self>1051         fn parse(input: ParseStream) -> Result<Self> {
1052             if input.peek(Token![extern]) {
1053                 input.parse().map(Some)
1054             } else {
1055                 Ok(None)
1056             }
1057         }
1058     }
1059 }
1060 
1061 #[cfg(feature = "printing")]
1062 mod printing {
1063     use super::*;
1064     use crate::attr::FilterAttrs;
1065     use crate::print::TokensOrDefault;
1066     use proc_macro2::TokenStream;
1067     use quote::{ToTokens, TokenStreamExt};
1068 
1069     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1070     impl ToTokens for TypeSlice {
to_tokens(&self, tokens: &mut TokenStream)1071         fn to_tokens(&self, tokens: &mut TokenStream) {
1072             self.bracket_token.surround(tokens, |tokens| {
1073                 self.elem.to_tokens(tokens);
1074             });
1075         }
1076     }
1077 
1078     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1079     impl ToTokens for TypeArray {
to_tokens(&self, tokens: &mut TokenStream)1080         fn to_tokens(&self, tokens: &mut TokenStream) {
1081             self.bracket_token.surround(tokens, |tokens| {
1082                 self.elem.to_tokens(tokens);
1083                 self.semi_token.to_tokens(tokens);
1084                 self.len.to_tokens(tokens);
1085             });
1086         }
1087     }
1088 
1089     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1090     impl ToTokens for TypePtr {
to_tokens(&self, tokens: &mut TokenStream)1091         fn to_tokens(&self, tokens: &mut TokenStream) {
1092             self.star_token.to_tokens(tokens);
1093             match &self.mutability {
1094                 Some(tok) => tok.to_tokens(tokens),
1095                 None => {
1096                     TokensOrDefault(&self.const_token).to_tokens(tokens);
1097                 }
1098             }
1099             self.elem.to_tokens(tokens);
1100         }
1101     }
1102 
1103     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1104     impl ToTokens for TypeReference {
to_tokens(&self, tokens: &mut TokenStream)1105         fn to_tokens(&self, tokens: &mut TokenStream) {
1106             self.and_token.to_tokens(tokens);
1107             self.lifetime.to_tokens(tokens);
1108             self.mutability.to_tokens(tokens);
1109             self.elem.to_tokens(tokens);
1110         }
1111     }
1112 
1113     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1114     impl ToTokens for TypeBareFn {
to_tokens(&self, tokens: &mut TokenStream)1115         fn to_tokens(&self, tokens: &mut TokenStream) {
1116             self.lifetimes.to_tokens(tokens);
1117             self.unsafety.to_tokens(tokens);
1118             self.abi.to_tokens(tokens);
1119             self.fn_token.to_tokens(tokens);
1120             self.paren_token.surround(tokens, |tokens| {
1121                 self.inputs.to_tokens(tokens);
1122                 if let Some(variadic) = &self.variadic {
1123                     if !self.inputs.empty_or_trailing() {
1124                         let span = variadic.dots.spans[0];
1125                         Token![,](span).to_tokens(tokens);
1126                     }
1127                     variadic.to_tokens(tokens);
1128                 }
1129             });
1130             self.output.to_tokens(tokens);
1131         }
1132     }
1133 
1134     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1135     impl ToTokens for TypeNever {
to_tokens(&self, tokens: &mut TokenStream)1136         fn to_tokens(&self, tokens: &mut TokenStream) {
1137             self.bang_token.to_tokens(tokens);
1138         }
1139     }
1140 
1141     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1142     impl ToTokens for TypeTuple {
to_tokens(&self, tokens: &mut TokenStream)1143         fn to_tokens(&self, tokens: &mut TokenStream) {
1144             self.paren_token.surround(tokens, |tokens| {
1145                 self.elems.to_tokens(tokens);
1146             });
1147         }
1148     }
1149 
1150     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1151     impl ToTokens for TypePath {
to_tokens(&self, tokens: &mut TokenStream)1152         fn to_tokens(&self, tokens: &mut TokenStream) {
1153             private::print_path(tokens, &self.qself, &self.path);
1154         }
1155     }
1156 
1157     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1158     impl ToTokens for TypeTraitObject {
to_tokens(&self, tokens: &mut TokenStream)1159         fn to_tokens(&self, tokens: &mut TokenStream) {
1160             self.dyn_token.to_tokens(tokens);
1161             self.bounds.to_tokens(tokens);
1162         }
1163     }
1164 
1165     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1166     impl ToTokens for TypeImplTrait {
to_tokens(&self, tokens: &mut TokenStream)1167         fn to_tokens(&self, tokens: &mut TokenStream) {
1168             self.impl_token.to_tokens(tokens);
1169             self.bounds.to_tokens(tokens);
1170         }
1171     }
1172 
1173     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1174     impl ToTokens for TypeGroup {
to_tokens(&self, tokens: &mut TokenStream)1175         fn to_tokens(&self, tokens: &mut TokenStream) {
1176             self.group_token.surround(tokens, |tokens| {
1177                 self.elem.to_tokens(tokens);
1178             });
1179         }
1180     }
1181 
1182     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1183     impl ToTokens for TypeParen {
to_tokens(&self, tokens: &mut TokenStream)1184         fn to_tokens(&self, tokens: &mut TokenStream) {
1185             self.paren_token.surround(tokens, |tokens| {
1186                 self.elem.to_tokens(tokens);
1187             });
1188         }
1189     }
1190 
1191     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1192     impl ToTokens for TypeInfer {
to_tokens(&self, tokens: &mut TokenStream)1193         fn to_tokens(&self, tokens: &mut TokenStream) {
1194             self.underscore_token.to_tokens(tokens);
1195         }
1196     }
1197 
1198     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1199     impl ToTokens for TypeMacro {
to_tokens(&self, tokens: &mut TokenStream)1200         fn to_tokens(&self, tokens: &mut TokenStream) {
1201             self.mac.to_tokens(tokens);
1202         }
1203     }
1204 
1205     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1206     impl ToTokens for ReturnType {
to_tokens(&self, tokens: &mut TokenStream)1207         fn to_tokens(&self, tokens: &mut TokenStream) {
1208             match self {
1209                 ReturnType::Default => {}
1210                 ReturnType::Type(arrow, ty) => {
1211                     arrow.to_tokens(tokens);
1212                     ty.to_tokens(tokens);
1213                 }
1214             }
1215         }
1216     }
1217 
1218     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1219     impl ToTokens for BareFnArg {
to_tokens(&self, tokens: &mut TokenStream)1220         fn to_tokens(&self, tokens: &mut TokenStream) {
1221             tokens.append_all(self.attrs.outer());
1222             if let Some((name, colon)) = &self.name {
1223                 name.to_tokens(tokens);
1224                 colon.to_tokens(tokens);
1225             }
1226             self.ty.to_tokens(tokens);
1227         }
1228     }
1229 
1230     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1231     impl ToTokens for Variadic {
to_tokens(&self, tokens: &mut TokenStream)1232         fn to_tokens(&self, tokens: &mut TokenStream) {
1233             tokens.append_all(self.attrs.outer());
1234             self.dots.to_tokens(tokens);
1235         }
1236     }
1237 
1238     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1239     impl ToTokens for Abi {
to_tokens(&self, tokens: &mut TokenStream)1240         fn to_tokens(&self, tokens: &mut TokenStream) {
1241             self.extern_token.to_tokens(tokens);
1242             self.name.to_tokens(tokens);
1243         }
1244     }
1245 }
1246