• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::*;
2 use crate::punctuated::{Iter, IterMut, Punctuated};
3 #[cfg(all(feature = "printing", feature = "extra-traits"))]
4 use std::fmt::{self, Debug};
5 #[cfg(all(feature = "printing", feature = "extra-traits"))]
6 use std::hash::{Hash, Hasher};
7 
8 ast_struct! {
9     /// Lifetimes and type parameters attached to a declaration of a function,
10     /// enum, trait, etc.
11     ///
12     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
13     /// feature.*
14     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
15     pub struct Generics {
16         pub lt_token: Option<Token![<]>,
17         pub params: Punctuated<GenericParam, Token![,]>,
18         pub gt_token: Option<Token![>]>,
19         pub where_clause: Option<WhereClause>,
20     }
21 }
22 
23 ast_enum_of_structs! {
24     /// A generic type parameter, lifetime, or const generic: `T: Into<String>`,
25     /// `'a: 'b`, `const LEN: usize`.
26     ///
27     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
28     /// feature.*
29     ///
30     /// # Syntax tree enum
31     ///
32     /// This type is a [syntax tree enum].
33     ///
34     /// [syntax tree enum]: Expr#syntax-tree-enums
35     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
36     pub enum GenericParam {
37         /// A generic type parameter: `T: Into<String>`.
38         Type(TypeParam),
39 
40         /// A lifetime definition: `'a: 'b + 'c + 'd`.
41         Lifetime(LifetimeDef),
42 
43         /// A const generic parameter: `const LENGTH: usize`.
44         Const(ConstParam),
45     }
46 }
47 
48 ast_struct! {
49     /// A generic type parameter: `T: Into<String>`.
50     ///
51     /// *This type is available only if Syn is built with the `"derive"` or
52     /// `"full"` feature.*
53     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
54     pub struct TypeParam {
55         pub attrs: Vec<Attribute>,
56         pub ident: Ident,
57         pub colon_token: Option<Token![:]>,
58         pub bounds: Punctuated<TypeParamBound, Token![+]>,
59         pub eq_token: Option<Token![=]>,
60         pub default: Option<Type>,
61     }
62 }
63 
64 ast_struct! {
65     /// A lifetime definition: `'a: 'b + 'c + 'd`.
66     ///
67     /// *This type is available only if Syn is built with the `"derive"` or
68     /// `"full"` feature.*
69     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
70     pub struct LifetimeDef {
71         pub attrs: Vec<Attribute>,
72         pub lifetime: Lifetime,
73         pub colon_token: Option<Token![:]>,
74         pub bounds: Punctuated<Lifetime, Token![+]>,
75     }
76 }
77 
78 ast_struct! {
79     /// A const generic parameter: `const LENGTH: usize`.
80     ///
81     /// *This type is available only if Syn is built with the `"derive"` or
82     /// `"full"` feature.*
83     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
84     pub struct ConstParam {
85         pub attrs: Vec<Attribute>,
86         pub const_token: Token![const],
87         pub ident: Ident,
88         pub colon_token: Token![:],
89         pub ty: Type,
90         pub eq_token: Option<Token![=]>,
91         pub default: Option<Expr>,
92     }
93 }
94 
95 impl Default for Generics {
default() -> Self96     fn default() -> Self {
97         Generics {
98             lt_token: None,
99             params: Punctuated::new(),
100             gt_token: None,
101             where_clause: None,
102         }
103     }
104 }
105 
106 impl Generics {
107     /// Returns an
108     /// <code
109     ///   style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
110     ///   href="struct.TypeParam.html"><code
111     ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
112     ///   style="padding-left:0;">&gt;</code>
113     /// over the type parameters in `self.params`.
type_params(&self) -> TypeParams114     pub fn type_params(&self) -> TypeParams {
115         TypeParams(self.params.iter())
116     }
117 
118     /// Returns an
119     /// <code
120     ///   style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
121     ///   href="struct.TypeParam.html"><code
122     ///   style="padding-left:0;padding-right:0;">TypeParam</code></a><code
123     ///   style="padding-left:0;">&gt;</code>
124     /// over the type parameters in `self.params`.
type_params_mut(&mut self) -> TypeParamsMut125     pub fn type_params_mut(&mut self) -> TypeParamsMut {
126         TypeParamsMut(self.params.iter_mut())
127     }
128 
129     /// Returns an
130     /// <code
131     ///   style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
132     ///   href="struct.LifetimeDef.html"><code
133     ///   style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
134     ///   style="padding-left:0;">&gt;</code>
135     /// over the lifetime parameters in `self.params`.
lifetimes(&self) -> Lifetimes136     pub fn lifetimes(&self) -> Lifetimes {
137         Lifetimes(self.params.iter())
138     }
139 
140     /// Returns an
141     /// <code
142     ///   style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
143     ///   href="struct.LifetimeDef.html"><code
144     ///   style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
145     ///   style="padding-left:0;">&gt;</code>
146     /// over the lifetime parameters in `self.params`.
lifetimes_mut(&mut self) -> LifetimesMut147     pub fn lifetimes_mut(&mut self) -> LifetimesMut {
148         LifetimesMut(self.params.iter_mut())
149     }
150 
151     /// Returns an
152     /// <code
153     ///   style="padding-right:0;">Iterator&lt;Item = &amp;</code><a
154     ///   href="struct.ConstParam.html"><code
155     ///   style="padding-left:0;padding-right:0;">ConstParam</code></a><code
156     ///   style="padding-left:0;">&gt;</code>
157     /// over the constant parameters in `self.params`.
const_params(&self) -> ConstParams158     pub fn const_params(&self) -> ConstParams {
159         ConstParams(self.params.iter())
160     }
161 
162     /// Returns an
163     /// <code
164     ///   style="padding-right:0;">Iterator&lt;Item = &amp;mut </code><a
165     ///   href="struct.ConstParam.html"><code
166     ///   style="padding-left:0;padding-right:0;">ConstParam</code></a><code
167     ///   style="padding-left:0;">&gt;</code>
168     /// over the constant parameters in `self.params`.
const_params_mut(&mut self) -> ConstParamsMut169     pub fn const_params_mut(&mut self) -> ConstParamsMut {
170         ConstParamsMut(self.params.iter_mut())
171     }
172 
173     /// Initializes an empty `where`-clause if there is not one present already.
make_where_clause(&mut self) -> &mut WhereClause174     pub fn make_where_clause(&mut self) -> &mut WhereClause {
175         // This is Option::get_or_insert_with in Rust 1.20.
176         if self.where_clause.is_none() {
177             self.where_clause = Some(WhereClause {
178                 where_token: <Token![where]>::default(),
179                 predicates: Punctuated::new(),
180             });
181         }
182         match &mut self.where_clause {
183             Some(where_clause) => where_clause,
184             None => unreachable!(),
185         }
186     }
187 }
188 
189 pub struct TypeParams<'a>(Iter<'a, GenericParam>);
190 
191 impl<'a> Iterator for TypeParams<'a> {
192     type Item = &'a TypeParam;
193 
next(&mut self) -> Option<Self::Item>194     fn next(&mut self) -> Option<Self::Item> {
195         let next = match self.0.next() {
196             Some(item) => item,
197             None => return None,
198         };
199         if let GenericParam::Type(type_param) = next {
200             Some(type_param)
201         } else {
202             self.next()
203         }
204     }
205 }
206 
207 pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
208 
209 impl<'a> Iterator for TypeParamsMut<'a> {
210     type Item = &'a mut TypeParam;
211 
next(&mut self) -> Option<Self::Item>212     fn next(&mut self) -> Option<Self::Item> {
213         let next = match self.0.next() {
214             Some(item) => item,
215             None => return None,
216         };
217         if let GenericParam::Type(type_param) = next {
218             Some(type_param)
219         } else {
220             self.next()
221         }
222     }
223 }
224 
225 pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
226 
227 impl<'a> Iterator for Lifetimes<'a> {
228     type Item = &'a LifetimeDef;
229 
next(&mut self) -> Option<Self::Item>230     fn next(&mut self) -> Option<Self::Item> {
231         let next = match self.0.next() {
232             Some(item) => item,
233             None => return None,
234         };
235         if let GenericParam::Lifetime(lifetime) = next {
236             Some(lifetime)
237         } else {
238             self.next()
239         }
240     }
241 }
242 
243 pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
244 
245 impl<'a> Iterator for LifetimesMut<'a> {
246     type Item = &'a mut LifetimeDef;
247 
next(&mut self) -> Option<Self::Item>248     fn next(&mut self) -> Option<Self::Item> {
249         let next = match self.0.next() {
250             Some(item) => item,
251             None => return None,
252         };
253         if let GenericParam::Lifetime(lifetime) = next {
254             Some(lifetime)
255         } else {
256             self.next()
257         }
258     }
259 }
260 
261 pub struct ConstParams<'a>(Iter<'a, GenericParam>);
262 
263 impl<'a> Iterator for ConstParams<'a> {
264     type Item = &'a ConstParam;
265 
next(&mut self) -> Option<Self::Item>266     fn next(&mut self) -> Option<Self::Item> {
267         let next = match self.0.next() {
268             Some(item) => item,
269             None => return None,
270         };
271         if let GenericParam::Const(const_param) = next {
272             Some(const_param)
273         } else {
274             self.next()
275         }
276     }
277 }
278 
279 pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
280 
281 impl<'a> Iterator for ConstParamsMut<'a> {
282     type Item = &'a mut ConstParam;
283 
next(&mut self) -> Option<Self::Item>284     fn next(&mut self) -> Option<Self::Item> {
285         let next = match self.0.next() {
286             Some(item) => item,
287             None => return None,
288         };
289         if let GenericParam::Const(const_param) = next {
290             Some(const_param)
291         } else {
292             self.next()
293         }
294     }
295 }
296 
297 /// Returned by `Generics::split_for_impl`.
298 ///
299 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
300 /// feature and the `"printing"` feature.*
301 #[cfg(feature = "printing")]
302 #[cfg_attr(
303     doc_cfg,
304     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
305 )]
306 pub struct ImplGenerics<'a>(&'a Generics);
307 
308 /// Returned by `Generics::split_for_impl`.
309 ///
310 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
311 /// feature and the `"printing"` feature.*
312 #[cfg(feature = "printing")]
313 #[cfg_attr(
314     doc_cfg,
315     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
316 )]
317 pub struct TypeGenerics<'a>(&'a Generics);
318 
319 /// Returned by `TypeGenerics::as_turbofish`.
320 ///
321 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
322 /// feature and the `"printing"` feature.*
323 #[cfg(feature = "printing")]
324 #[cfg_attr(
325     doc_cfg,
326     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
327 )]
328 pub struct Turbofish<'a>(&'a Generics);
329 
330 #[cfg(feature = "printing")]
331 impl Generics {
332     /// Split a type's generics into the pieces required for impl'ing a trait
333     /// for that type.
334     ///
335     /// ```
336     /// # use proc_macro2::{Span, Ident};
337     /// # use quote::quote;
338     /// #
339     /// # let generics: syn::Generics = Default::default();
340     /// # let name = Ident::new("MyType", Span::call_site());
341     /// #
342     /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
343     /// quote! {
344     ///     impl #impl_generics MyTrait for #name #ty_generics #where_clause {
345     ///         // ...
346     ///     }
347     /// }
348     /// # ;
349     /// ```
350     ///
351     /// *This method is available only if Syn is built with the `"derive"` or
352     /// `"full"` feature and the `"printing"` feature.*
353     #[cfg_attr(
354         doc_cfg,
355         doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
356     )]
split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>)357     pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
358         (
359             ImplGenerics(self),
360             TypeGenerics(self),
361             self.where_clause.as_ref(),
362         )
363     }
364 }
365 
366 #[cfg(feature = "printing")]
367 macro_rules! generics_wrapper_impls {
368     ($ty:ident) => {
369         #[cfg(feature = "clone-impls")]
370         #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
371         impl<'a> Clone for $ty<'a> {
372             fn clone(&self) -> Self {
373                 $ty(self.0)
374             }
375         }
376 
377         #[cfg(feature = "extra-traits")]
378         #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
379         impl<'a> Debug for $ty<'a> {
380             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
381                 formatter
382                     .debug_tuple(stringify!($ty))
383                     .field(self.0)
384                     .finish()
385             }
386         }
387 
388         #[cfg(feature = "extra-traits")]
389         #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
390         impl<'a> Eq for $ty<'a> {}
391 
392         #[cfg(feature = "extra-traits")]
393         #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
394         impl<'a> PartialEq for $ty<'a> {
395             fn eq(&self, other: &Self) -> bool {
396                 self.0 == other.0
397             }
398         }
399 
400         #[cfg(feature = "extra-traits")]
401         #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
402         impl<'a> Hash for $ty<'a> {
403             fn hash<H: Hasher>(&self, state: &mut H) {
404                 self.0.hash(state);
405             }
406         }
407     };
408 }
409 
410 #[cfg(feature = "printing")]
411 generics_wrapper_impls!(ImplGenerics);
412 #[cfg(feature = "printing")]
413 generics_wrapper_impls!(TypeGenerics);
414 #[cfg(feature = "printing")]
415 generics_wrapper_impls!(Turbofish);
416 
417 #[cfg(feature = "printing")]
418 impl<'a> TypeGenerics<'a> {
419     /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
420     ///
421     /// *This method is available only if Syn is built with the `"derive"` or
422     /// `"full"` feature and the `"printing"` feature.*
as_turbofish(&self) -> Turbofish423     pub fn as_turbofish(&self) -> Turbofish {
424         Turbofish(self.0)
425     }
426 }
427 
428 ast_struct! {
429     /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
430     ///
431     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
432     /// feature.*
433     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
434     pub struct BoundLifetimes {
435         pub for_token: Token![for],
436         pub lt_token: Token![<],
437         pub lifetimes: Punctuated<LifetimeDef, Token![,]>,
438         pub gt_token: Token![>],
439     }
440 }
441 
442 impl Default for BoundLifetimes {
default() -> Self443     fn default() -> Self {
444         BoundLifetimes {
445             for_token: Default::default(),
446             lt_token: Default::default(),
447             lifetimes: Punctuated::new(),
448             gt_token: Default::default(),
449         }
450     }
451 }
452 
453 impl LifetimeDef {
new(lifetime: Lifetime) -> Self454     pub fn new(lifetime: Lifetime) -> Self {
455         LifetimeDef {
456             attrs: Vec::new(),
457             lifetime,
458             colon_token: None,
459             bounds: Punctuated::new(),
460         }
461     }
462 }
463 
464 impl From<Ident> for TypeParam {
from(ident: Ident) -> Self465     fn from(ident: Ident) -> Self {
466         TypeParam {
467             attrs: vec![],
468             ident,
469             colon_token: None,
470             bounds: Punctuated::new(),
471             eq_token: None,
472             default: None,
473         }
474     }
475 }
476 
477 ast_enum_of_structs! {
478     /// A trait or lifetime used as a bound on a type parameter.
479     ///
480     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
481     /// feature.*
482     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
483     pub enum TypeParamBound {
484         Trait(TraitBound),
485         Lifetime(Lifetime),
486     }
487 }
488 
489 ast_struct! {
490     /// A trait used as a bound on a type parameter.
491     ///
492     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
493     /// feature.*
494     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
495     pub struct TraitBound {
496         pub paren_token: Option<token::Paren>,
497         pub modifier: TraitBoundModifier,
498         /// The `for<'a>` in `for<'a> Foo<&'a T>`
499         pub lifetimes: Option<BoundLifetimes>,
500         /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
501         pub path: Path,
502     }
503 }
504 
505 ast_enum! {
506     /// A modifier on a trait bound, currently only used for the `?` in
507     /// `?Sized`.
508     ///
509     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
510     /// feature.*
511     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
512     pub enum TraitBoundModifier {
513         None,
514         Maybe(Token![?]),
515     }
516 }
517 
518 ast_struct! {
519     /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
520     /// 'static`.
521     ///
522     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
523     /// feature.*
524     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
525     pub struct WhereClause {
526         pub where_token: Token![where],
527         pub predicates: Punctuated<WherePredicate, Token![,]>,
528     }
529 }
530 
531 ast_enum_of_structs! {
532     /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
533     ///
534     /// *This type is available only if Syn is built with the `"derive"` or `"full"`
535     /// feature.*
536     ///
537     /// # Syntax tree enum
538     ///
539     /// This type is a [syntax tree enum].
540     ///
541     /// [syntax tree enum]: Expr#syntax-tree-enums
542     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
543     pub enum WherePredicate {
544         /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
545         Type(PredicateType),
546 
547         /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
548         Lifetime(PredicateLifetime),
549 
550         /// An equality predicate in a `where` clause (unsupported).
551         Eq(PredicateEq),
552     }
553 }
554 
555 ast_struct! {
556     /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
557     ///
558     /// *This type is available only if Syn is built with the `"derive"` or
559     /// `"full"` feature.*
560     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
561     pub struct PredicateType {
562         /// Any lifetimes from a `for` binding
563         pub lifetimes: Option<BoundLifetimes>,
564         /// The type being bounded
565         pub bounded_ty: Type,
566         pub colon_token: Token![:],
567         /// Trait and lifetime bounds (`Clone+Send+'static`)
568         pub bounds: Punctuated<TypeParamBound, Token![+]>,
569     }
570 }
571 
572 ast_struct! {
573     /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
574     ///
575     /// *This type is available only if Syn is built with the `"derive"` or
576     /// `"full"` feature.*
577     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
578     pub struct PredicateLifetime {
579         pub lifetime: Lifetime,
580         pub colon_token: Token![:],
581         pub bounds: Punctuated<Lifetime, Token![+]>,
582     }
583 }
584 
585 ast_struct! {
586     /// An equality predicate in a `where` clause (unsupported).
587     ///
588     /// *This type is available only if Syn is built with the `"derive"` or
589     /// `"full"` feature.*
590     #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
591     pub struct PredicateEq {
592         pub lhs_ty: Type,
593         pub eq_token: Token![=],
594         pub rhs_ty: Type,
595     }
596 }
597 
598 #[cfg(feature = "parsing")]
599 pub mod parsing {
600     use super::*;
601     use crate::ext::IdentExt;
602     use crate::parse::{Parse, ParseStream, Result};
603 
604     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
605     impl Parse for Generics {
parse(input: ParseStream) -> Result<Self>606         fn parse(input: ParseStream) -> Result<Self> {
607             if !input.peek(Token![<]) {
608                 return Ok(Generics::default());
609             }
610 
611             let lt_token: Token![<] = input.parse()?;
612 
613             let mut params = Punctuated::new();
614             loop {
615                 if input.peek(Token![>]) {
616                     break;
617                 }
618 
619                 let attrs = input.call(Attribute::parse_outer)?;
620                 let lookahead = input.lookahead1();
621                 if lookahead.peek(Lifetime) {
622                     params.push_value(GenericParam::Lifetime(LifetimeDef {
623                         attrs,
624                         ..input.parse()?
625                     }));
626                 } else if lookahead.peek(Ident) {
627                     params.push_value(GenericParam::Type(TypeParam {
628                         attrs,
629                         ..input.parse()?
630                     }));
631                 } else if lookahead.peek(Token![const]) {
632                     params.push_value(GenericParam::Const(ConstParam {
633                         attrs,
634                         ..input.parse()?
635                     }));
636                 } else if input.peek(Token![_]) {
637                     params.push_value(GenericParam::Type(TypeParam {
638                         attrs,
639                         ident: input.call(Ident::parse_any)?,
640                         colon_token: None,
641                         bounds: Punctuated::new(),
642                         eq_token: None,
643                         default: None,
644                     }));
645                 } else {
646                     return Err(lookahead.error());
647                 }
648 
649                 if input.peek(Token![>]) {
650                     break;
651                 }
652                 let punct = input.parse()?;
653                 params.push_punct(punct);
654             }
655 
656             let gt_token: Token![>] = input.parse()?;
657 
658             Ok(Generics {
659                 lt_token: Some(lt_token),
660                 params,
661                 gt_token: Some(gt_token),
662                 where_clause: None,
663             })
664         }
665     }
666 
667     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
668     impl Parse for GenericParam {
parse(input: ParseStream) -> Result<Self>669         fn parse(input: ParseStream) -> Result<Self> {
670             let attrs = input.call(Attribute::parse_outer)?;
671 
672             let lookahead = input.lookahead1();
673             if lookahead.peek(Ident) {
674                 Ok(GenericParam::Type(TypeParam {
675                     attrs,
676                     ..input.parse()?
677                 }))
678             } else if lookahead.peek(Lifetime) {
679                 Ok(GenericParam::Lifetime(LifetimeDef {
680                     attrs,
681                     ..input.parse()?
682                 }))
683             } else if lookahead.peek(Token![const]) {
684                 Ok(GenericParam::Const(ConstParam {
685                     attrs,
686                     ..input.parse()?
687                 }))
688             } else {
689                 Err(lookahead.error())
690             }
691         }
692     }
693 
694     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
695     impl Parse for LifetimeDef {
parse(input: ParseStream) -> Result<Self>696         fn parse(input: ParseStream) -> Result<Self> {
697             let has_colon;
698             Ok(LifetimeDef {
699                 attrs: input.call(Attribute::parse_outer)?,
700                 lifetime: input.parse()?,
701                 colon_token: {
702                     if input.peek(Token![:]) {
703                         has_colon = true;
704                         Some(input.parse()?)
705                     } else {
706                         has_colon = false;
707                         None
708                     }
709                 },
710                 bounds: {
711                     let mut bounds = Punctuated::new();
712                     if has_colon {
713                         loop {
714                             if input.peek(Token![,]) || input.peek(Token![>]) {
715                                 break;
716                             }
717                             let value = input.parse()?;
718                             bounds.push_value(value);
719                             if !input.peek(Token![+]) {
720                                 break;
721                             }
722                             let punct = input.parse()?;
723                             bounds.push_punct(punct);
724                         }
725                     }
726                     bounds
727                 },
728             })
729         }
730     }
731 
732     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
733     impl Parse for BoundLifetimes {
parse(input: ParseStream) -> Result<Self>734         fn parse(input: ParseStream) -> Result<Self> {
735             Ok(BoundLifetimes {
736                 for_token: input.parse()?,
737                 lt_token: input.parse()?,
738                 lifetimes: {
739                     let mut lifetimes = Punctuated::new();
740                     while !input.peek(Token![>]) {
741                         lifetimes.push_value(input.parse()?);
742                         if input.peek(Token![>]) {
743                             break;
744                         }
745                         lifetimes.push_punct(input.parse()?);
746                     }
747                     lifetimes
748                 },
749                 gt_token: input.parse()?,
750             })
751         }
752     }
753 
754     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
755     impl Parse for Option<BoundLifetimes> {
parse(input: ParseStream) -> Result<Self>756         fn parse(input: ParseStream) -> Result<Self> {
757             if input.peek(Token![for]) {
758                 input.parse().map(Some)
759             } else {
760                 Ok(None)
761             }
762         }
763     }
764 
765     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
766     impl Parse for TypeParam {
parse(input: ParseStream) -> Result<Self>767         fn parse(input: ParseStream) -> Result<Self> {
768             let attrs = input.call(Attribute::parse_outer)?;
769             let ident: Ident = input.parse()?;
770             let colon_token: Option<Token![:]> = input.parse()?;
771 
772             let begin_bound = input.fork();
773             let mut is_maybe_const = false;
774             let mut bounds = Punctuated::new();
775             if colon_token.is_some() {
776                 loop {
777                     if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) {
778                         break;
779                     }
780                     if input.peek(Token![?]) && input.peek2(Token![const]) {
781                         input.parse::<Token![?]>()?;
782                         input.parse::<Token![const]>()?;
783                         is_maybe_const = true;
784                     }
785                     let value: TypeParamBound = input.parse()?;
786                     bounds.push_value(value);
787                     if !input.peek(Token![+]) {
788                         break;
789                     }
790                     let punct: Token![+] = input.parse()?;
791                     bounds.push_punct(punct);
792                 }
793             }
794 
795             let mut eq_token: Option<Token![=]> = input.parse()?;
796             let mut default = if eq_token.is_some() {
797                 Some(input.parse::<Type>()?)
798             } else {
799                 None
800             };
801 
802             if is_maybe_const {
803                 bounds.clear();
804                 eq_token = None;
805                 default = Some(Type::Verbatim(verbatim::between(begin_bound, input)));
806             }
807 
808             Ok(TypeParam {
809                 attrs,
810                 ident,
811                 colon_token,
812                 bounds,
813                 eq_token,
814                 default,
815             })
816         }
817     }
818 
819     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
820     impl Parse for TypeParamBound {
parse(input: ParseStream) -> Result<Self>821         fn parse(input: ParseStream) -> Result<Self> {
822             if input.peek(Lifetime) {
823                 return input.parse().map(TypeParamBound::Lifetime);
824             }
825 
826             if input.peek(token::Paren) {
827                 let content;
828                 let paren_token = parenthesized!(content in input);
829                 let mut bound: TraitBound = content.parse()?;
830                 bound.paren_token = Some(paren_token);
831                 return Ok(TypeParamBound::Trait(bound));
832             }
833 
834             input.parse().map(TypeParamBound::Trait)
835         }
836     }
837 
838     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
839     impl Parse for TraitBound {
parse(input: ParseStream) -> Result<Self>840         fn parse(input: ParseStream) -> Result<Self> {
841             let modifier: TraitBoundModifier = input.parse()?;
842             let lifetimes: Option<BoundLifetimes> = input.parse()?;
843 
844             let mut path: Path = input.parse()?;
845             if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) {
846                 let parenthesized = PathArguments::Parenthesized(input.parse()?);
847                 path.segments.last_mut().unwrap().arguments = parenthesized;
848             }
849 
850             Ok(TraitBound {
851                 paren_token: None,
852                 modifier,
853                 lifetimes,
854                 path,
855             })
856         }
857     }
858 
859     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
860     impl Parse for TraitBoundModifier {
parse(input: ParseStream) -> Result<Self>861         fn parse(input: ParseStream) -> Result<Self> {
862             if input.peek(Token![?]) {
863                 input.parse().map(TraitBoundModifier::Maybe)
864             } else {
865                 Ok(TraitBoundModifier::None)
866             }
867         }
868     }
869 
870     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
871     impl Parse for ConstParam {
parse(input: ParseStream) -> Result<Self>872         fn parse(input: ParseStream) -> Result<Self> {
873             let mut default = None;
874             Ok(ConstParam {
875                 attrs: input.call(Attribute::parse_outer)?,
876                 const_token: input.parse()?,
877                 ident: input.parse()?,
878                 colon_token: input.parse()?,
879                 ty: input.parse()?,
880                 eq_token: {
881                     if input.peek(Token![=]) {
882                         let eq_token = input.parse()?;
883                         default = Some(path::parsing::const_argument(input)?);
884                         Some(eq_token)
885                     } else {
886                         None
887                     }
888                 },
889                 default,
890             })
891         }
892     }
893 
894     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
895     impl Parse for WhereClause {
parse(input: ParseStream) -> Result<Self>896         fn parse(input: ParseStream) -> Result<Self> {
897             Ok(WhereClause {
898                 where_token: input.parse()?,
899                 predicates: {
900                     let mut predicates = Punctuated::new();
901                     loop {
902                         if input.is_empty()
903                             || input.peek(token::Brace)
904                             || input.peek(Token![,])
905                             || input.peek(Token![;])
906                             || input.peek(Token![:]) && !input.peek(Token![::])
907                             || input.peek(Token![=])
908                         {
909                             break;
910                         }
911                         let value = input.parse()?;
912                         predicates.push_value(value);
913                         if !input.peek(Token![,]) {
914                             break;
915                         }
916                         let punct = input.parse()?;
917                         predicates.push_punct(punct);
918                     }
919                     predicates
920                 },
921             })
922         }
923     }
924 
925     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
926     impl Parse for Option<WhereClause> {
parse(input: ParseStream) -> Result<Self>927         fn parse(input: ParseStream) -> Result<Self> {
928             if input.peek(Token![where]) {
929                 input.parse().map(Some)
930             } else {
931                 Ok(None)
932             }
933         }
934     }
935 
936     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
937     impl Parse for WherePredicate {
parse(input: ParseStream) -> Result<Self>938         fn parse(input: ParseStream) -> Result<Self> {
939             if input.peek(Lifetime) && input.peek2(Token![:]) {
940                 Ok(WherePredicate::Lifetime(PredicateLifetime {
941                     lifetime: input.parse()?,
942                     colon_token: input.parse()?,
943                     bounds: {
944                         let mut bounds = Punctuated::new();
945                         loop {
946                             if input.is_empty()
947                                 || input.peek(token::Brace)
948                                 || input.peek(Token![,])
949                                 || input.peek(Token![;])
950                                 || input.peek(Token![:])
951                                 || input.peek(Token![=])
952                             {
953                                 break;
954                             }
955                             let value = input.parse()?;
956                             bounds.push_value(value);
957                             if !input.peek(Token![+]) {
958                                 break;
959                             }
960                             let punct = input.parse()?;
961                             bounds.push_punct(punct);
962                         }
963                         bounds
964                     },
965                 }))
966             } else {
967                 Ok(WherePredicate::Type(PredicateType {
968                     lifetimes: input.parse()?,
969                     bounded_ty: input.parse()?,
970                     colon_token: input.parse()?,
971                     bounds: {
972                         let mut bounds = Punctuated::new();
973                         loop {
974                             if input.is_empty()
975                                 || input.peek(token::Brace)
976                                 || input.peek(Token![,])
977                                 || input.peek(Token![;])
978                                 || input.peek(Token![:]) && !input.peek(Token![::])
979                                 || input.peek(Token![=])
980                             {
981                                 break;
982                             }
983                             let value = input.parse()?;
984                             bounds.push_value(value);
985                             if !input.peek(Token![+]) {
986                                 break;
987                             }
988                             let punct = input.parse()?;
989                             bounds.push_punct(punct);
990                         }
991                         bounds
992                     },
993                 }))
994             }
995         }
996     }
997 }
998 
999 #[cfg(feature = "printing")]
1000 mod printing {
1001     use super::*;
1002     use crate::attr::FilterAttrs;
1003     use crate::print::TokensOrDefault;
1004     use proc_macro2::TokenStream;
1005     #[cfg(feature = "full")]
1006     use proc_macro2::TokenTree;
1007     use quote::{ToTokens, TokenStreamExt};
1008 
1009     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1010     impl ToTokens for Generics {
to_tokens(&self, tokens: &mut TokenStream)1011         fn to_tokens(&self, tokens: &mut TokenStream) {
1012             if self.params.is_empty() {
1013                 return;
1014             }
1015 
1016             TokensOrDefault(&self.lt_token).to_tokens(tokens);
1017 
1018             // Print lifetimes before types and consts, regardless of their
1019             // order in self.params.
1020             //
1021             // TODO: ordering rules for const parameters vs type parameters have
1022             // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1023             let mut trailing_or_empty = true;
1024             for param in self.params.pairs() {
1025                 if let GenericParam::Lifetime(_) = **param.value() {
1026                     param.to_tokens(tokens);
1027                     trailing_or_empty = param.punct().is_some();
1028                 }
1029             }
1030             for param in self.params.pairs() {
1031                 match **param.value() {
1032                     GenericParam::Type(_) | GenericParam::Const(_) => {
1033                         if !trailing_or_empty {
1034                             <Token![,]>::default().to_tokens(tokens);
1035                             trailing_or_empty = true;
1036                         }
1037                         param.to_tokens(tokens);
1038                     }
1039                     GenericParam::Lifetime(_) => {}
1040                 }
1041             }
1042 
1043             TokensOrDefault(&self.gt_token).to_tokens(tokens);
1044         }
1045     }
1046 
1047     impl<'a> ToTokens for ImplGenerics<'a> {
to_tokens(&self, tokens: &mut TokenStream)1048         fn to_tokens(&self, tokens: &mut TokenStream) {
1049             if self.0.params.is_empty() {
1050                 return;
1051             }
1052 
1053             TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1054 
1055             // Print lifetimes before types and consts, regardless of their
1056             // order in self.params.
1057             //
1058             // TODO: ordering rules for const parameters vs type parameters have
1059             // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1060             let mut trailing_or_empty = true;
1061             for param in self.0.params.pairs() {
1062                 if let GenericParam::Lifetime(_) = **param.value() {
1063                     param.to_tokens(tokens);
1064                     trailing_or_empty = param.punct().is_some();
1065                 }
1066             }
1067             for param in self.0.params.pairs() {
1068                 if let GenericParam::Lifetime(_) = **param.value() {
1069                     continue;
1070                 }
1071                 if !trailing_or_empty {
1072                     <Token![,]>::default().to_tokens(tokens);
1073                     trailing_or_empty = true;
1074                 }
1075                 match *param.value() {
1076                     GenericParam::Lifetime(_) => unreachable!(),
1077                     GenericParam::Type(param) => {
1078                         // Leave off the type parameter defaults
1079                         tokens.append_all(param.attrs.outer());
1080                         param.ident.to_tokens(tokens);
1081                         if !param.bounds.is_empty() {
1082                             TokensOrDefault(&param.colon_token).to_tokens(tokens);
1083                             param.bounds.to_tokens(tokens);
1084                         }
1085                     }
1086                     GenericParam::Const(param) => {
1087                         // Leave off the const parameter defaults
1088                         tokens.append_all(param.attrs.outer());
1089                         param.const_token.to_tokens(tokens);
1090                         param.ident.to_tokens(tokens);
1091                         param.colon_token.to_tokens(tokens);
1092                         param.ty.to_tokens(tokens);
1093                     }
1094                 }
1095                 param.punct().to_tokens(tokens);
1096             }
1097 
1098             TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1099         }
1100     }
1101 
1102     impl<'a> ToTokens for TypeGenerics<'a> {
to_tokens(&self, tokens: &mut TokenStream)1103         fn to_tokens(&self, tokens: &mut TokenStream) {
1104             if self.0.params.is_empty() {
1105                 return;
1106             }
1107 
1108             TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1109 
1110             // Print lifetimes before types and consts, regardless of their
1111             // order in self.params.
1112             //
1113             // TODO: ordering rules for const parameters vs type parameters have
1114             // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1115             let mut trailing_or_empty = true;
1116             for param in self.0.params.pairs() {
1117                 if let GenericParam::Lifetime(def) = *param.value() {
1118                     // Leave off the lifetime bounds and attributes
1119                     def.lifetime.to_tokens(tokens);
1120                     param.punct().to_tokens(tokens);
1121                     trailing_or_empty = param.punct().is_some();
1122                 }
1123             }
1124             for param in self.0.params.pairs() {
1125                 if let GenericParam::Lifetime(_) = **param.value() {
1126                     continue;
1127                 }
1128                 if !trailing_or_empty {
1129                     <Token![,]>::default().to_tokens(tokens);
1130                     trailing_or_empty = true;
1131                 }
1132                 match *param.value() {
1133                     GenericParam::Lifetime(_) => unreachable!(),
1134                     GenericParam::Type(param) => {
1135                         // Leave off the type parameter defaults
1136                         param.ident.to_tokens(tokens);
1137                     }
1138                     GenericParam::Const(param) => {
1139                         // Leave off the const parameter defaults
1140                         param.ident.to_tokens(tokens);
1141                     }
1142                 }
1143                 param.punct().to_tokens(tokens);
1144             }
1145 
1146             TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1147         }
1148     }
1149 
1150     impl<'a> ToTokens for Turbofish<'a> {
to_tokens(&self, tokens: &mut TokenStream)1151         fn to_tokens(&self, tokens: &mut TokenStream) {
1152             if !self.0.params.is_empty() {
1153                 <Token![::]>::default().to_tokens(tokens);
1154                 TypeGenerics(self.0).to_tokens(tokens);
1155             }
1156         }
1157     }
1158 
1159     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1160     impl ToTokens for BoundLifetimes {
to_tokens(&self, tokens: &mut TokenStream)1161         fn to_tokens(&self, tokens: &mut TokenStream) {
1162             self.for_token.to_tokens(tokens);
1163             self.lt_token.to_tokens(tokens);
1164             self.lifetimes.to_tokens(tokens);
1165             self.gt_token.to_tokens(tokens);
1166         }
1167     }
1168 
1169     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1170     impl ToTokens for LifetimeDef {
to_tokens(&self, tokens: &mut TokenStream)1171         fn to_tokens(&self, tokens: &mut TokenStream) {
1172             tokens.append_all(self.attrs.outer());
1173             self.lifetime.to_tokens(tokens);
1174             if !self.bounds.is_empty() {
1175                 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1176                 self.bounds.to_tokens(tokens);
1177             }
1178         }
1179     }
1180 
1181     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1182     impl ToTokens for TypeParam {
to_tokens(&self, tokens: &mut TokenStream)1183         fn to_tokens(&self, tokens: &mut TokenStream) {
1184             tokens.append_all(self.attrs.outer());
1185             self.ident.to_tokens(tokens);
1186             if !self.bounds.is_empty() {
1187                 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1188                 self.bounds.to_tokens(tokens);
1189             }
1190             if let Some(default) = &self.default {
1191                 #[cfg(feature = "full")]
1192                 {
1193                     if self.eq_token.is_none() {
1194                         if let Type::Verbatim(default) = default {
1195                             let mut iter = default.clone().into_iter().peekable();
1196                             while let Some(token) = iter.next() {
1197                                 if let TokenTree::Punct(q) = token {
1198                                     if q.as_char() == '?' {
1199                                         if let Some(TokenTree::Ident(c)) = iter.peek() {
1200                                             if c == "const" {
1201                                                 if self.bounds.is_empty() {
1202                                                     TokensOrDefault(&self.colon_token)
1203                                                         .to_tokens(tokens);
1204                                                 }
1205                                                 return default.to_tokens(tokens);
1206                                             }
1207                                         }
1208                                     }
1209                                 }
1210                             }
1211                         }
1212                     }
1213                 }
1214                 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1215                 default.to_tokens(tokens);
1216             }
1217         }
1218     }
1219 
1220     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1221     impl ToTokens for TraitBound {
to_tokens(&self, tokens: &mut TokenStream)1222         fn to_tokens(&self, tokens: &mut TokenStream) {
1223             let to_tokens = |tokens: &mut TokenStream| {
1224                 self.modifier.to_tokens(tokens);
1225                 self.lifetimes.to_tokens(tokens);
1226                 self.path.to_tokens(tokens);
1227             };
1228             match &self.paren_token {
1229                 Some(paren) => paren.surround(tokens, to_tokens),
1230                 None => to_tokens(tokens),
1231             }
1232         }
1233     }
1234 
1235     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1236     impl ToTokens for TraitBoundModifier {
to_tokens(&self, tokens: &mut TokenStream)1237         fn to_tokens(&self, tokens: &mut TokenStream) {
1238             match self {
1239                 TraitBoundModifier::None => {}
1240                 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1241             }
1242         }
1243     }
1244 
1245     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1246     impl ToTokens for ConstParam {
to_tokens(&self, tokens: &mut TokenStream)1247         fn to_tokens(&self, tokens: &mut TokenStream) {
1248             tokens.append_all(self.attrs.outer());
1249             self.const_token.to_tokens(tokens);
1250             self.ident.to_tokens(tokens);
1251             self.colon_token.to_tokens(tokens);
1252             self.ty.to_tokens(tokens);
1253             if let Some(default) = &self.default {
1254                 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1255                 default.to_tokens(tokens);
1256             }
1257         }
1258     }
1259 
1260     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1261     impl ToTokens for WhereClause {
to_tokens(&self, tokens: &mut TokenStream)1262         fn to_tokens(&self, tokens: &mut TokenStream) {
1263             if !self.predicates.is_empty() {
1264                 self.where_token.to_tokens(tokens);
1265                 self.predicates.to_tokens(tokens);
1266             }
1267         }
1268     }
1269 
1270     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1271     impl ToTokens for PredicateType {
to_tokens(&self, tokens: &mut TokenStream)1272         fn to_tokens(&self, tokens: &mut TokenStream) {
1273             self.lifetimes.to_tokens(tokens);
1274             self.bounded_ty.to_tokens(tokens);
1275             self.colon_token.to_tokens(tokens);
1276             self.bounds.to_tokens(tokens);
1277         }
1278     }
1279 
1280     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1281     impl ToTokens for PredicateLifetime {
to_tokens(&self, tokens: &mut TokenStream)1282         fn to_tokens(&self, tokens: &mut TokenStream) {
1283             self.lifetime.to_tokens(tokens);
1284             self.colon_token.to_tokens(tokens);
1285             self.bounds.to_tokens(tokens);
1286         }
1287     }
1288 
1289     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1290     impl ToTokens for PredicateEq {
to_tokens(&self, tokens: &mut TokenStream)1291         fn to_tokens(&self, tokens: &mut TokenStream) {
1292             self.lhs_ty.to_tokens(tokens);
1293             self.eq_token.to_tokens(tokens);
1294             self.rhs_ty.to_tokens(tokens);
1295         }
1296     }
1297 }
1298