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