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