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