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