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