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