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