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