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