xref: /linux/rust/syn/generics.rs (revision 808c999fc9e7c366fd47da564e69d579c1dc8279)
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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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 {
95     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     return_impl_trait! {
107         /// Iterator over the lifetime parameters in `self.params`.
108         pub fn lifetimes(&self) -> impl Iterator<Item = &LifetimeParam> [Lifetimes] {
109             Lifetimes(self.params.iter())
110         }
111     }
112 
113     return_impl_trait! {
114         /// Iterator over the lifetime parameters in `self.params`.
115         pub fn lifetimes_mut(&mut self) -> impl Iterator<Item = &mut LifetimeParam> [LifetimesMut] {
116             LifetimesMut(self.params.iter_mut())
117         }
118     }
119 
120     return_impl_trait! {
121         /// Iterator over the type parameters in `self.params`.
122         pub fn type_params(&self) -> impl Iterator<Item = &TypeParam> [TypeParams] {
123             TypeParams(self.params.iter())
124         }
125     }
126 
127     return_impl_trait! {
128         /// Iterator over the type parameters in `self.params`.
129         pub fn type_params_mut(&mut self) -> impl Iterator<Item = &mut TypeParam> [TypeParamsMut] {
130             TypeParamsMut(self.params.iter_mut())
131         }
132     }
133 
134     return_impl_trait! {
135         /// Iterator over the constant parameters in `self.params`.
136         pub fn const_params(&self) -> impl Iterator<Item = &ConstParam> [ConstParams] {
137             ConstParams(self.params.iter())
138         }
139     }
140 
141     return_impl_trait! {
142         /// Iterator over the constant parameters in `self.params`.
143         pub fn const_params_mut(&mut self) -> impl Iterator<Item = &mut ConstParam> [ConstParamsMut] {
144             ConstParamsMut(self.params.iter_mut())
145         }
146     }
147 
148     /// Initializes an empty `where`-clause if there is not one present already.
149     pub fn make_where_clause(&mut self) -> &mut WhereClause {
150         self.where_clause.get_or_insert_with(|| WhereClause {
151             where_token: <Token![where]>::default(),
152             predicates: Punctuated::new(),
153         })
154     }
155 
156     /// Split a type's generics into the pieces required for impl'ing a trait
157     /// for that type.
158     ///
159     /// ```
160     /// # use proc_macro2::{Span, Ident};
161     /// # use quote::quote;
162     /// #
163     /// # let generics: syn::Generics = Default::default();
164     /// # let name = Ident::new("MyType", Span::call_site());
165     /// #
166     /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
167     /// quote! {
168     ///     impl #impl_generics MyTrait for #name #ty_generics #where_clause {
169     ///         // ...
170     ///     }
171     /// }
172     /// # ;
173     /// ```
174     #[cfg(feature = "printing")]
175     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
176     pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
177         (
178             ImplGenerics(self),
179             TypeGenerics(self),
180             self.where_clause.as_ref(),
181         )
182     }
183 }
184 
185 pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
186 
187 impl<'a> Iterator for Lifetimes<'a> {
188     type Item = &'a LifetimeParam;
189 
190     fn next(&mut self) -> Option<Self::Item> {
191         if let GenericParam::Lifetime(lifetime) = self.0.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 
204     fn next(&mut self) -> Option<Self::Item> {
205         if let GenericParam::Lifetime(lifetime) = self.0.next()? {
206             Some(lifetime)
207         } else {
208             self.next()
209         }
210     }
211 }
212 
213 pub struct TypeParams<'a>(Iter<'a, GenericParam>);
214 
215 impl<'a> Iterator for TypeParams<'a> {
216     type Item = &'a TypeParam;
217 
218     fn next(&mut self) -> Option<Self::Item> {
219         if let GenericParam::Type(type_param) = self.0.next()? {
220             Some(type_param)
221         } else {
222             self.next()
223         }
224     }
225 }
226 
227 pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
228 
229 impl<'a> Iterator for TypeParamsMut<'a> {
230     type Item = &'a mut TypeParam;
231 
232     fn next(&mut self) -> Option<Self::Item> {
233         if let GenericParam::Type(type_param) = self.0.next()? {
234             Some(type_param)
235         } else {
236             self.next()
237         }
238     }
239 }
240 
241 pub struct ConstParams<'a>(Iter<'a, GenericParam>);
242 
243 impl<'a> Iterator for ConstParams<'a> {
244     type Item = &'a ConstParam;
245 
246     fn next(&mut self) -> Option<Self::Item> {
247         if let GenericParam::Const(const_param) = self.0.next()? {
248             Some(const_param)
249         } else {
250             self.next()
251         }
252     }
253 }
254 
255 pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
256 
257 impl<'a> Iterator for ConstParamsMut<'a> {
258     type Item = &'a mut ConstParam;
259 
260     fn next(&mut self) -> Option<Self::Item> {
261         if let GenericParam::Const(const_param) = self.0.next()? {
262             Some(const_param)
263         } else {
264             self.next()
265         }
266     }
267 }
268 
269 /// Returned by `Generics::split_for_impl`.
270 #[cfg(feature = "printing")]
271 #[cfg_attr(
272     docsrs,
273     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
274 )]
275 pub struct ImplGenerics<'a>(&'a Generics);
276 
277 /// Returned by `Generics::split_for_impl`.
278 #[cfg(feature = "printing")]
279 #[cfg_attr(
280     docsrs,
281     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
282 )]
283 pub struct TypeGenerics<'a>(&'a Generics);
284 
285 /// Returned by `TypeGenerics::as_turbofish`.
286 #[cfg(feature = "printing")]
287 #[cfg_attr(
288     docsrs,
289     doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
290 )]
291 pub struct Turbofish<'a>(&'a Generics);
292 
293 #[cfg(feature = "printing")]
294 macro_rules! generics_wrapper_impls {
295     ($ty:ident) => {
296         #[cfg(feature = "clone-impls")]
297         #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
298         impl<'a> Clone for $ty<'a> {
299             fn clone(&self) -> Self {
300                 $ty(self.0)
301             }
302         }
303 
304         #[cfg(feature = "extra-traits")]
305         #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
306         impl<'a> Debug for $ty<'a> {
307             fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
308                 formatter
309                     .debug_tuple(stringify!($ty))
310                     .field(self.0)
311                     .finish()
312             }
313         }
314 
315         #[cfg(feature = "extra-traits")]
316         #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
317         impl<'a> Eq for $ty<'a> {}
318 
319         #[cfg(feature = "extra-traits")]
320         #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
321         impl<'a> PartialEq for $ty<'a> {
322             fn eq(&self, other: &Self) -> bool {
323                 self.0 == other.0
324             }
325         }
326 
327         #[cfg(feature = "extra-traits")]
328         #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
329         impl<'a> Hash for $ty<'a> {
330             fn hash<H: Hasher>(&self, state: &mut H) {
331                 self.0.hash(state);
332             }
333         }
334     };
335 }
336 
337 #[cfg(feature = "printing")]
338 generics_wrapper_impls!(ImplGenerics);
339 #[cfg(feature = "printing")]
340 generics_wrapper_impls!(TypeGenerics);
341 #[cfg(feature = "printing")]
342 generics_wrapper_impls!(Turbofish);
343 
344 #[cfg(feature = "printing")]
345 impl<'a> TypeGenerics<'a> {
346     /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
347     pub fn as_turbofish(&self) -> Turbofish<'a> {
348         Turbofish(self.0)
349     }
350 }
351 
352 ast_struct! {
353     /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
354     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
355     pub struct BoundLifetimes {
356         pub for_token: Token![for],
357         pub lt_token: Token![<],
358         pub lifetimes: Punctuated<GenericParam, Token![,]>,
359         pub gt_token: Token![>],
360     }
361 }
362 
363 impl Default for BoundLifetimes {
364     fn default() -> Self {
365         BoundLifetimes {
366             for_token: Default::default(),
367             lt_token: Default::default(),
368             lifetimes: Punctuated::new(),
369             gt_token: Default::default(),
370         }
371     }
372 }
373 
374 impl LifetimeParam {
375     pub fn new(lifetime: Lifetime) -> Self {
376         LifetimeParam {
377             attrs: Vec::new(),
378             lifetime,
379             colon_token: None,
380             bounds: Punctuated::new(),
381         }
382     }
383 }
384 
385 impl From<Ident> for TypeParam {
386     fn from(ident: Ident) -> Self {
387         TypeParam {
388             attrs: vec![],
389             ident,
390             colon_token: None,
391             bounds: Punctuated::new(),
392             eq_token: None,
393             default: None,
394         }
395     }
396 }
397 
398 ast_enum_of_structs! {
399     /// A trait or lifetime used as a bound on a type parameter.
400     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
401     #[non_exhaustive]
402     pub enum TypeParamBound {
403         Trait(TraitBound),
404         Lifetime(Lifetime),
405         PreciseCapture(PreciseCapture),
406         Verbatim(TokenStream),
407     }
408 }
409 
410 ast_struct! {
411     /// A trait used as a bound on a type parameter.
412     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
413     pub struct TraitBound {
414         pub paren_token: Option<token::Paren>,
415         pub modifier: TraitBoundModifier,
416         /// The `for<'a>` in `for<'a> Foo<&'a T>`
417         pub lifetimes: Option<BoundLifetimes>,
418         /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
419         pub path: Path,
420     }
421 }
422 
423 ast_enum! {
424     /// A modifier on a trait bound, currently only used for the `?` in
425     /// `?Sized`.
426     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
427     pub enum TraitBoundModifier {
428         None,
429         Maybe(Token![?]),
430     }
431 }
432 
433 ast_struct! {
434     /// Precise capturing bound: the 'use&lt;&hellip;&gt;' in `impl Trait +
435     /// use<'a, T>`.
436     #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
437     pub struct PreciseCapture #full {
438         pub use_token: Token![use],
439         pub lt_token: Token![<],
440         pub params: Punctuated<CapturedParam, Token![,]>,
441         pub gt_token: Token![>],
442     }
443 }
444 
445 #[cfg(feature = "full")]
446 ast_enum! {
447     /// Single parameter in a precise capturing bound.
448     #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
449     #[non_exhaustive]
450     pub enum CapturedParam {
451         /// A lifetime parameter in precise capturing bound: `fn f<'a>() -> impl
452         /// Trait + use<'a>`.
453         Lifetime(Lifetime),
454         /// A type parameter or const generic parameter in precise capturing
455         /// bound: `fn f<T>() -> impl Trait + use<T>` or `fn f<const K: T>() ->
456         /// impl Trait + use<K>`.
457         Ident(Ident),
458     }
459 }
460 
461 ast_struct! {
462     /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
463     /// 'static`.
464     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
465     pub struct WhereClause {
466         pub where_token: Token![where],
467         pub predicates: Punctuated<WherePredicate, Token![,]>,
468     }
469 }
470 
471 ast_enum_of_structs! {
472     /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
473     ///
474     /// # Syntax tree enum
475     ///
476     /// This type is a [syntax tree enum].
477     ///
478     /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
479     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
480     #[non_exhaustive]
481     pub enum WherePredicate {
482         /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
483         Lifetime(PredicateLifetime),
484 
485         /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
486         Type(PredicateType),
487     }
488 }
489 
490 ast_struct! {
491     /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
492     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
493     pub struct PredicateLifetime {
494         pub lifetime: Lifetime,
495         pub colon_token: Token![:],
496         pub bounds: Punctuated<Lifetime, Token![+]>,
497     }
498 }
499 
500 ast_struct! {
501     /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
502     #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
503     pub struct PredicateType {
504         /// Any lifetimes from a `for` binding
505         pub lifetimes: Option<BoundLifetimes>,
506         /// The type being bounded
507         pub bounded_ty: Type,
508         pub colon_token: Token![:],
509         /// Trait and lifetime bounds (`Clone+Send+'static`)
510         pub bounds: Punctuated<TypeParamBound, Token![+]>,
511     }
512 }
513 
514 #[cfg(feature = "parsing")]
515 pub(crate) mod parsing {
516     use crate::attr::Attribute;
517     #[cfg(feature = "full")]
518     use crate::error;
519     use crate::error::{Error, Result};
520     use crate::ext::IdentExt as _;
521     use crate::generics::{
522         BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
523         PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
524         WherePredicate,
525     };
526     #[cfg(feature = "full")]
527     use crate::generics::{CapturedParam, PreciseCapture};
528     use crate::ident::Ident;
529     use crate::lifetime::Lifetime;
530     use crate::parse::{Parse, ParseStream};
531     use crate::path::{self, ParenthesizedGenericArguments, Path, PathArguments};
532     use crate::punctuated::Punctuated;
533     use crate::token;
534     use crate::ty::Type;
535     use crate::verbatim;
536 
537     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
538     impl Parse for Generics {
539         fn parse(input: ParseStream) -> Result<Self> {
540             if !input.peek(Token![<]) {
541                 return Ok(Generics::default());
542             }
543 
544             let lt_token: Token![<] = input.parse()?;
545 
546             let mut params = Punctuated::new();
547             loop {
548                 if input.peek(Token![>]) {
549                     break;
550                 }
551 
552                 let attrs = input.call(Attribute::parse_outer)?;
553                 let lookahead = input.lookahead1();
554                 if lookahead.peek(Lifetime) {
555                     params.push_value(GenericParam::Lifetime(LifetimeParam {
556                         attrs,
557                         ..input.parse()?
558                     }));
559                 } else if lookahead.peek(Ident) {
560                     params.push_value(GenericParam::Type(TypeParam {
561                         attrs,
562                         ..input.parse()?
563                     }));
564                 } else if lookahead.peek(Token![const]) {
565                     params.push_value(GenericParam::Const(ConstParam {
566                         attrs,
567                         ..input.parse()?
568                     }));
569                 } else if input.peek(Token![_]) {
570                     params.push_value(GenericParam::Type(TypeParam {
571                         attrs,
572                         ident: input.call(Ident::parse_any)?,
573                         colon_token: None,
574                         bounds: Punctuated::new(),
575                         eq_token: None,
576                         default: None,
577                     }));
578                 } else {
579                     return Err(lookahead.error());
580                 }
581 
582                 if input.peek(Token![>]) {
583                     break;
584                 }
585                 let punct = input.parse()?;
586                 params.push_punct(punct);
587             }
588 
589             let gt_token: Token![>] = input.parse()?;
590 
591             Ok(Generics {
592                 lt_token: Some(lt_token),
593                 params,
594                 gt_token: Some(gt_token),
595                 where_clause: None,
596             })
597         }
598     }
599 
600     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
601     impl Parse for GenericParam {
602         fn parse(input: ParseStream) -> Result<Self> {
603             let attrs = input.call(Attribute::parse_outer)?;
604 
605             let lookahead = input.lookahead1();
606             if lookahead.peek(Ident) {
607                 Ok(GenericParam::Type(TypeParam {
608                     attrs,
609                     ..input.parse()?
610                 }))
611             } else if lookahead.peek(Lifetime) {
612                 Ok(GenericParam::Lifetime(LifetimeParam {
613                     attrs,
614                     ..input.parse()?
615                 }))
616             } else if lookahead.peek(Token![const]) {
617                 Ok(GenericParam::Const(ConstParam {
618                     attrs,
619                     ..input.parse()?
620                 }))
621             } else {
622                 Err(lookahead.error())
623             }
624         }
625     }
626 
627     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
628     impl Parse for LifetimeParam {
629         fn parse(input: ParseStream) -> Result<Self> {
630             let has_colon;
631             Ok(LifetimeParam {
632                 attrs: input.call(Attribute::parse_outer)?,
633                 lifetime: input.parse()?,
634                 colon_token: {
635                     if input.peek(Token![:]) {
636                         has_colon = true;
637                         Some(input.parse()?)
638                     } else {
639                         has_colon = false;
640                         None
641                     }
642                 },
643                 bounds: {
644                     let mut bounds = Punctuated::new();
645                     if has_colon {
646                         loop {
647                             if input.peek(Token![,]) || input.peek(Token![>]) {
648                                 break;
649                             }
650                             let value = input.parse()?;
651                             bounds.push_value(value);
652                             if !input.peek(Token![+]) {
653                                 break;
654                             }
655                             let punct = input.parse()?;
656                             bounds.push_punct(punct);
657                         }
658                     }
659                     bounds
660                 },
661             })
662         }
663     }
664 
665     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
666     impl Parse for BoundLifetimes {
667         fn parse(input: ParseStream) -> Result<Self> {
668             Ok(BoundLifetimes {
669                 for_token: input.parse()?,
670                 lt_token: input.parse()?,
671                 lifetimes: {
672                     let mut lifetimes = Punctuated::new();
673                     while !input.peek(Token![>]) {
674                         lifetimes.push_value(input.parse()?);
675                         if input.peek(Token![>]) {
676                             break;
677                         }
678                         lifetimes.push_punct(input.parse()?);
679                     }
680                     lifetimes
681                 },
682                 gt_token: input.parse()?,
683             })
684         }
685     }
686 
687     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
688     impl Parse for Option<BoundLifetimes> {
689         fn parse(input: ParseStream) -> Result<Self> {
690             if input.peek(Token![for]) {
691                 input.parse().map(Some)
692             } else {
693                 Ok(None)
694             }
695         }
696     }
697 
698     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
699     impl Parse for TypeParam {
700         fn parse(input: ParseStream) -> Result<Self> {
701             let attrs = input.call(Attribute::parse_outer)?;
702             let ident: Ident = input.parse()?;
703             let colon_token: Option<Token![:]> = input.parse()?;
704 
705             let mut bounds = Punctuated::new();
706             if colon_token.is_some() {
707                 loop {
708                     if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) {
709                         break;
710                     }
711                     bounds.push_value({
712                         let allow_precise_capture = false;
713                         let allow_const = true;
714                         TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
715                     });
716                     if !input.peek(Token![+]) {
717                         break;
718                     }
719                     let punct: Token![+] = input.parse()?;
720                     bounds.push_punct(punct);
721                 }
722             }
723 
724             let eq_token: Option<Token![=]> = input.parse()?;
725             let default = if eq_token.is_some() {
726                 Some(input.parse::<Type>()?)
727             } else {
728                 None
729             };
730 
731             Ok(TypeParam {
732                 attrs,
733                 ident,
734                 colon_token,
735                 bounds,
736                 eq_token,
737                 default,
738             })
739         }
740     }
741 
742     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
743     impl Parse for TypeParamBound {
744         fn parse(input: ParseStream) -> Result<Self> {
745             let allow_precise_capture = true;
746             let allow_const = true;
747             Self::parse_single(input, allow_precise_capture, allow_const)
748         }
749     }
750 
751     impl TypeParamBound {
752         pub(crate) fn parse_single(
753             input: ParseStream,
754             #[cfg_attr(not(feature = "full"), allow(unused_variables))] allow_precise_capture: bool,
755             allow_const: bool,
756         ) -> Result<Self> {
757             if input.peek(Lifetime) {
758                 return input.parse().map(TypeParamBound::Lifetime);
759             }
760 
761             #[cfg(feature = "full")]
762             {
763                 if input.peek(Token![use]) {
764                     let precise_capture: PreciseCapture = input.parse()?;
765                     return if allow_precise_capture {
766                         Ok(TypeParamBound::PreciseCapture(precise_capture))
767                     } else {
768                         let msg = "`use<...>` precise capturing syntax is not allowed here";
769                         Err(error::new2(
770                             precise_capture.use_token.span,
771                             precise_capture.gt_token.span,
772                             msg,
773                         ))
774                     };
775                 }
776             }
777 
778             let begin = input.fork();
779 
780             let content;
781             let (paren_token, content) = if input.peek(token::Paren) {
782                 (Some(parenthesized!(content in input)), &content)
783             } else {
784                 (None, input)
785             };
786 
787             if let Some(mut bound) = TraitBound::do_parse(content, allow_const)? {
788                 bound.paren_token = paren_token;
789                 Ok(TypeParamBound::Trait(bound))
790             } else {
791                 Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input)))
792             }
793         }
794 
795         pub(crate) fn parse_multiple(
796             input: ParseStream,
797             allow_plus: bool,
798             allow_precise_capture: bool,
799             allow_const: bool,
800         ) -> Result<Punctuated<Self, Token![+]>> {
801             let mut bounds = Punctuated::new();
802             loop {
803                 let bound = Self::parse_single(input, allow_precise_capture, allow_const)?;
804                 bounds.push_value(bound);
805                 if !(allow_plus && input.peek(Token![+])) {
806                     break;
807                 }
808                 bounds.push_punct(input.parse()?);
809                 if !(input.peek(Ident::peek_any)
810                     || input.peek(Token![::])
811                     || input.peek(Token![?])
812                     || input.peek(Lifetime)
813                     || input.peek(token::Paren)
814                     || (allow_const && (input.peek(token::Bracket) || input.peek(Token![const]))))
815                 {
816                     break;
817                 }
818             }
819             Ok(bounds)
820         }
821     }
822 
823     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
824     impl Parse for TraitBound {
825         fn parse(input: ParseStream) -> Result<Self> {
826             let allow_const = false;
827             Self::do_parse(input, allow_const).map(Option::unwrap)
828         }
829     }
830 
831     impl TraitBound {
832         fn do_parse(input: ParseStream, allow_const: bool) -> Result<Option<Self>> {
833             let mut lifetimes: Option<BoundLifetimes> = input.parse()?;
834 
835             let is_conditionally_const = cfg!(feature = "full") && input.peek(token::Bracket);
836             let is_unconditionally_const = cfg!(feature = "full") && input.peek(Token![const]);
837             if is_conditionally_const {
838                 let conditionally_const;
839                 let bracket_token = bracketed!(conditionally_const in input);
840                 conditionally_const.parse::<Token![const]>()?;
841                 if !allow_const {
842                     let msg = "`[const]` is not allowed here";
843                     return Err(Error::new(bracket_token.span.join(), msg));
844                 }
845             } else if is_unconditionally_const {
846                 let const_token: Token![const] = input.parse()?;
847                 if !allow_const {
848                     let msg = "`const` is not allowed here";
849                     return Err(Error::new(const_token.span, msg));
850                 }
851             }
852 
853             let modifier: TraitBoundModifier = input.parse()?;
854             if lifetimes.is_none() && matches!(modifier, TraitBoundModifier::Maybe(_)) {
855                 lifetimes = input.parse()?;
856             }
857 
858             let mut path: Path = input.parse()?;
859             if path.segments.last().unwrap().arguments.is_empty()
860                 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
861             {
862                 input.parse::<Option<Token![::]>>()?;
863                 let args: ParenthesizedGenericArguments = input.parse()?;
864                 let parenthesized = PathArguments::Parenthesized(args);
865                 path.segments.last_mut().unwrap().arguments = parenthesized;
866             }
867 
868             if lifetimes.is_some() {
869                 match modifier {
870                     TraitBoundModifier::None => {}
871                     TraitBoundModifier::Maybe(maybe) => {
872                         let msg = "`for<...>` binder not allowed with `?` trait polarity modifier";
873                         return Err(Error::new(maybe.span, msg));
874                     }
875                 }
876             }
877 
878             if is_conditionally_const || is_unconditionally_const {
879                 Ok(None)
880             } else {
881                 Ok(Some(TraitBound {
882                     paren_token: None,
883                     modifier,
884                     lifetimes,
885                     path,
886                 }))
887             }
888         }
889     }
890 
891     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
892     impl Parse for TraitBoundModifier {
893         fn parse(input: ParseStream) -> Result<Self> {
894             if input.peek(Token![?]) {
895                 input.parse().map(TraitBoundModifier::Maybe)
896             } else {
897                 Ok(TraitBoundModifier::None)
898             }
899         }
900     }
901 
902     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
903     impl Parse for ConstParam {
904         fn parse(input: ParseStream) -> Result<Self> {
905             let mut default = None;
906             Ok(ConstParam {
907                 attrs: input.call(Attribute::parse_outer)?,
908                 const_token: input.parse()?,
909                 ident: input.parse()?,
910                 colon_token: input.parse()?,
911                 ty: input.parse()?,
912                 eq_token: {
913                     if input.peek(Token![=]) {
914                         let eq_token = input.parse()?;
915                         default = Some(path::parsing::const_argument(input)?);
916                         Some(eq_token)
917                     } else {
918                         None
919                     }
920                 },
921                 default,
922             })
923         }
924     }
925 
926     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
927     impl Parse for WhereClause {
928         fn parse(input: ParseStream) -> Result<Self> {
929             let where_token: Token![where] = input.parse()?;
930 
931             if choose_generics_over_qpath(input) {
932                 return Err(input
933                     .error("generic parameters on `where` clauses are reserved for future use"));
934             }
935 
936             Ok(WhereClause {
937                 where_token,
938                 predicates: {
939                     let mut predicates = Punctuated::new();
940                     loop {
941                         if input.is_empty()
942                             || input.peek(token::Brace)
943                             || input.peek(Token![,])
944                             || input.peek(Token![;])
945                             || input.peek(Token![:]) && !input.peek(Token![::])
946                             || input.peek(Token![=])
947                         {
948                             break;
949                         }
950                         let value = input.parse()?;
951                         predicates.push_value(value);
952                         if !input.peek(Token![,]) {
953                             break;
954                         }
955                         let punct = input.parse()?;
956                         predicates.push_punct(punct);
957                     }
958                     predicates
959                 },
960             })
961         }
962     }
963 
964     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
965     impl Parse for Option<WhereClause> {
966         fn parse(input: ParseStream) -> Result<Self> {
967             if input.peek(Token![where]) {
968                 input.parse().map(Some)
969             } else {
970                 Ok(None)
971             }
972         }
973     }
974 
975     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
976     impl Parse for WherePredicate {
977         fn parse(input: ParseStream) -> Result<Self> {
978             if input.peek(Lifetime) && input.peek2(Token![:]) {
979                 Ok(WherePredicate::Lifetime(PredicateLifetime {
980                     lifetime: input.parse()?,
981                     colon_token: input.parse()?,
982                     bounds: {
983                         let mut bounds = Punctuated::new();
984                         loop {
985                             if input.is_empty()
986                                 || input.peek(token::Brace)
987                                 || input.peek(Token![,])
988                                 || input.peek(Token![;])
989                                 || input.peek(Token![:])
990                                 || input.peek(Token![=])
991                             {
992                                 break;
993                             }
994                             let value = input.parse()?;
995                             bounds.push_value(value);
996                             if !input.peek(Token![+]) {
997                                 break;
998                             }
999                             let punct = input.parse()?;
1000                             bounds.push_punct(punct);
1001                         }
1002                         bounds
1003                     },
1004                 }))
1005             } else {
1006                 Ok(WherePredicate::Type(PredicateType {
1007                     lifetimes: input.parse()?,
1008                     bounded_ty: input.parse()?,
1009                     colon_token: input.parse()?,
1010                     bounds: {
1011                         let mut bounds = Punctuated::new();
1012                         loop {
1013                             if input.is_empty()
1014                                 || input.peek(token::Brace)
1015                                 || input.peek(Token![,])
1016                                 || input.peek(Token![;])
1017                                 || input.peek(Token![:]) && !input.peek(Token![::])
1018                                 || input.peek(Token![=])
1019                             {
1020                                 break;
1021                             }
1022                             bounds.push_value({
1023                                 let allow_precise_capture = false;
1024                                 let allow_const = true;
1025                                 TypeParamBound::parse_single(
1026                                     input,
1027                                     allow_precise_capture,
1028                                     allow_const,
1029                                 )?
1030                             });
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     #[cfg(feature = "full")]
1045     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1046     impl Parse for PreciseCapture {
1047         fn parse(input: ParseStream) -> Result<Self> {
1048             let use_token: Token![use] = input.parse()?;
1049             let lt_token: Token![<] = input.parse()?;
1050             let mut params = Punctuated::new();
1051             loop {
1052                 let lookahead = input.lookahead1();
1053                 params.push_value(
1054                     if lookahead.peek(Lifetime) || lookahead.peek(Ident) || input.peek(Token![Self])
1055                     {
1056                         input.parse::<CapturedParam>()?
1057                     } else if lookahead.peek(Token![>]) {
1058                         break;
1059                     } else {
1060                         return Err(lookahead.error());
1061                     },
1062                 );
1063                 let lookahead = input.lookahead1();
1064                 params.push_punct(if lookahead.peek(Token![,]) {
1065                     input.parse::<Token![,]>()?
1066                 } else if lookahead.peek(Token![>]) {
1067                     break;
1068                 } else {
1069                     return Err(lookahead.error());
1070                 });
1071             }
1072             let gt_token: Token![>] = input.parse()?;
1073             Ok(PreciseCapture {
1074                 use_token,
1075                 lt_token,
1076                 params,
1077                 gt_token,
1078             })
1079         }
1080     }
1081 
1082     #[cfg(feature = "full")]
1083     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1084     impl Parse for CapturedParam {
1085         fn parse(input: ParseStream) -> Result<Self> {
1086             let lookahead = input.lookahead1();
1087             if lookahead.peek(Lifetime) {
1088                 input.parse().map(CapturedParam::Lifetime)
1089             } else if lookahead.peek(Ident) || input.peek(Token![Self]) {
1090                 input.call(Ident::parse_any).map(CapturedParam::Ident)
1091             } else {
1092                 Err(lookahead.error())
1093             }
1094         }
1095     }
1096 
1097     pub(crate) fn choose_generics_over_qpath(input: ParseStream) -> bool {
1098         // Rust syntax has an ambiguity between generic parameters and qualified
1099         // paths. In `impl <T> :: Thing<T, U> {}` this may either be a generic
1100         // inherent impl `impl<T> ::Thing<T, U>` or a non-generic inherent impl
1101         // for an associated type `impl <T>::Thing<T, U>`.
1102         //
1103         // After `<` the following continuations can only begin generics, not a
1104         // qualified path:
1105         //
1106         //     `<` `>`                  - empty generic parameters
1107         //     `<` `#`                  - generic parameters with attribute
1108         //     `<` LIFETIME `>`         - single lifetime parameter
1109         //     `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
1110         //     `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
1111         //     `<` (LIFETIME|IDENT) `=` - generic parameter with a default
1112         //     `<` const                - generic const parameter
1113         //
1114         // The only truly ambiguous case is:
1115         //
1116         //     `<` IDENT `>` `::` IDENT ...
1117         //
1118         // which we disambiguate in favor of generics because this is almost
1119         // always the expected one in the context of real-world code.
1120         input.peek(Token![<])
1121             && (input.peek2(Token![>])
1122                 || input.peek2(Token![#])
1123                 || (input.peek2(Lifetime) || input.peek2(Ident))
1124                     && (input.peek3(Token![>])
1125                         || input.peek3(Token![,])
1126                         || input.peek3(Token![:]) && !input.peek3(Token![::])
1127                         || input.peek3(Token![=]))
1128                 || input.peek2(Token![const]))
1129     }
1130 
1131     #[cfg(feature = "full")]
1132     pub(crate) fn choose_generics_over_qpath_after_keyword(input: ParseStream) -> bool {
1133         let input = input.fork();
1134         input.call(Ident::parse_any).unwrap(); // `impl` or `for` or `where`
1135         choose_generics_over_qpath(&input)
1136     }
1137 }
1138 
1139 #[cfg(feature = "printing")]
1140 pub(crate) mod printing {
1141     use crate::attr::FilterAttrs;
1142     #[cfg(feature = "full")]
1143     use crate::expr;
1144     use crate::expr::Expr;
1145     #[cfg(feature = "full")]
1146     use crate::fixup::FixupContext;
1147     use crate::generics::{
1148         BoundLifetimes, ConstParam, GenericParam, Generics, ImplGenerics, LifetimeParam,
1149         PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, Turbofish, TypeGenerics,
1150         TypeParam, WhereClause,
1151     };
1152     #[cfg(feature = "full")]
1153     use crate::generics::{CapturedParam, PreciseCapture};
1154     use crate::print::TokensOrDefault;
1155     use crate::token;
1156     use proc_macro2::TokenStream;
1157     use quote::{ToTokens, TokenStreamExt};
1158 
1159     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1160     impl ToTokens for Generics {
1161         fn to_tokens(&self, tokens: &mut TokenStream) {
1162             if self.params.is_empty() {
1163                 return;
1164             }
1165 
1166             TokensOrDefault(&self.lt_token).to_tokens(tokens);
1167 
1168             // Print lifetimes before types and consts, regardless of their
1169             // order in self.params.
1170             let mut trailing_or_empty = true;
1171             for param in self.params.pairs() {
1172                 if let GenericParam::Lifetime(_) = **param.value() {
1173                     param.to_tokens(tokens);
1174                     trailing_or_empty = param.punct().is_some();
1175                 }
1176             }
1177             for param in self.params.pairs() {
1178                 match param.value() {
1179                     GenericParam::Type(_) | GenericParam::Const(_) => {
1180                         if !trailing_or_empty {
1181                             <Token![,]>::default().to_tokens(tokens);
1182                             trailing_or_empty = true;
1183                         }
1184                         param.to_tokens(tokens);
1185                     }
1186                     GenericParam::Lifetime(_) => {}
1187                 }
1188             }
1189 
1190             TokensOrDefault(&self.gt_token).to_tokens(tokens);
1191         }
1192     }
1193 
1194     impl<'a> ToTokens for ImplGenerics<'a> {
1195         fn to_tokens(&self, tokens: &mut TokenStream) {
1196             if self.0.params.is_empty() {
1197                 return;
1198             }
1199 
1200             TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1201 
1202             // Print lifetimes before types and consts, regardless of their
1203             // order in self.params.
1204             let mut trailing_or_empty = true;
1205             for param in self.0.params.pairs() {
1206                 if let GenericParam::Lifetime(_) = **param.value() {
1207                     param.to_tokens(tokens);
1208                     trailing_or_empty = param.punct().is_some();
1209                 }
1210             }
1211             for param in self.0.params.pairs() {
1212                 if let GenericParam::Lifetime(_) = **param.value() {
1213                     continue;
1214                 }
1215                 if !trailing_or_empty {
1216                     <Token![,]>::default().to_tokens(tokens);
1217                     trailing_or_empty = true;
1218                 }
1219                 match param.value() {
1220                     GenericParam::Lifetime(_) => unreachable!(),
1221                     GenericParam::Type(param) => {
1222                         // Leave off the type parameter defaults
1223                         tokens.append_all(param.attrs.outer());
1224                         param.ident.to_tokens(tokens);
1225                         if !param.bounds.is_empty() {
1226                             TokensOrDefault(&param.colon_token).to_tokens(tokens);
1227                             param.bounds.to_tokens(tokens);
1228                         }
1229                     }
1230                     GenericParam::Const(param) => {
1231                         // Leave off the const parameter defaults
1232                         tokens.append_all(param.attrs.outer());
1233                         param.const_token.to_tokens(tokens);
1234                         param.ident.to_tokens(tokens);
1235                         param.colon_token.to_tokens(tokens);
1236                         param.ty.to_tokens(tokens);
1237                     }
1238                 }
1239                 param.punct().to_tokens(tokens);
1240             }
1241 
1242             TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1243         }
1244     }
1245 
1246     impl<'a> ToTokens for TypeGenerics<'a> {
1247         fn to_tokens(&self, tokens: &mut TokenStream) {
1248             if self.0.params.is_empty() {
1249                 return;
1250             }
1251 
1252             TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1253 
1254             // Print lifetimes before types and consts, regardless of their
1255             // order in self.params.
1256             let mut trailing_or_empty = true;
1257             for param in self.0.params.pairs() {
1258                 if let GenericParam::Lifetime(def) = *param.value() {
1259                     // Leave off the lifetime bounds and attributes
1260                     def.lifetime.to_tokens(tokens);
1261                     param.punct().to_tokens(tokens);
1262                     trailing_or_empty = param.punct().is_some();
1263                 }
1264             }
1265             for param in self.0.params.pairs() {
1266                 if let GenericParam::Lifetime(_) = **param.value() {
1267                     continue;
1268                 }
1269                 if !trailing_or_empty {
1270                     <Token![,]>::default().to_tokens(tokens);
1271                     trailing_or_empty = true;
1272                 }
1273                 match param.value() {
1274                     GenericParam::Lifetime(_) => unreachable!(),
1275                     GenericParam::Type(param) => {
1276                         // Leave off the type parameter defaults
1277                         param.ident.to_tokens(tokens);
1278                     }
1279                     GenericParam::Const(param) => {
1280                         // Leave off the const parameter defaults
1281                         param.ident.to_tokens(tokens);
1282                     }
1283                 }
1284                 param.punct().to_tokens(tokens);
1285             }
1286 
1287             TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1288         }
1289     }
1290 
1291     impl<'a> ToTokens for Turbofish<'a> {
1292         fn to_tokens(&self, tokens: &mut TokenStream) {
1293             if !self.0.params.is_empty() {
1294                 <Token![::]>::default().to_tokens(tokens);
1295                 TypeGenerics(self.0).to_tokens(tokens);
1296             }
1297         }
1298     }
1299 
1300     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1301     impl ToTokens for BoundLifetimes {
1302         fn to_tokens(&self, tokens: &mut TokenStream) {
1303             self.for_token.to_tokens(tokens);
1304             self.lt_token.to_tokens(tokens);
1305             self.lifetimes.to_tokens(tokens);
1306             self.gt_token.to_tokens(tokens);
1307         }
1308     }
1309 
1310     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1311     impl ToTokens for LifetimeParam {
1312         fn to_tokens(&self, tokens: &mut TokenStream) {
1313             tokens.append_all(self.attrs.outer());
1314             self.lifetime.to_tokens(tokens);
1315             if !self.bounds.is_empty() {
1316                 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1317                 self.bounds.to_tokens(tokens);
1318             }
1319         }
1320     }
1321 
1322     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1323     impl ToTokens for TypeParam {
1324         fn to_tokens(&self, tokens: &mut TokenStream) {
1325             tokens.append_all(self.attrs.outer());
1326             self.ident.to_tokens(tokens);
1327             if !self.bounds.is_empty() {
1328                 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1329                 self.bounds.to_tokens(tokens);
1330             }
1331             if let Some(default) = &self.default {
1332                 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1333                 default.to_tokens(tokens);
1334             }
1335         }
1336     }
1337 
1338     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1339     impl ToTokens for TraitBound {
1340         fn to_tokens(&self, tokens: &mut TokenStream) {
1341             let to_tokens = |tokens: &mut TokenStream| {
1342                 self.modifier.to_tokens(tokens);
1343                 self.lifetimes.to_tokens(tokens);
1344                 self.path.to_tokens(tokens);
1345             };
1346             match &self.paren_token {
1347                 Some(paren) => paren.surround(tokens, to_tokens),
1348                 None => to_tokens(tokens),
1349             }
1350         }
1351     }
1352 
1353     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1354     impl ToTokens for TraitBoundModifier {
1355         fn to_tokens(&self, tokens: &mut TokenStream) {
1356             match self {
1357                 TraitBoundModifier::None => {}
1358                 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1359             }
1360         }
1361     }
1362 
1363     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1364     impl ToTokens for ConstParam {
1365         fn to_tokens(&self, tokens: &mut TokenStream) {
1366             tokens.append_all(self.attrs.outer());
1367             self.const_token.to_tokens(tokens);
1368             self.ident.to_tokens(tokens);
1369             self.colon_token.to_tokens(tokens);
1370             self.ty.to_tokens(tokens);
1371             if let Some(default) = &self.default {
1372                 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1373                 print_const_argument(default, tokens);
1374             }
1375         }
1376     }
1377 
1378     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1379     impl ToTokens for WhereClause {
1380         fn to_tokens(&self, tokens: &mut TokenStream) {
1381             if !self.predicates.is_empty() {
1382                 self.where_token.to_tokens(tokens);
1383                 self.predicates.to_tokens(tokens);
1384             }
1385         }
1386     }
1387 
1388     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1389     impl ToTokens for PredicateLifetime {
1390         fn to_tokens(&self, tokens: &mut TokenStream) {
1391             self.lifetime.to_tokens(tokens);
1392             self.colon_token.to_tokens(tokens);
1393             self.bounds.to_tokens(tokens);
1394         }
1395     }
1396 
1397     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1398     impl ToTokens for PredicateType {
1399         fn to_tokens(&self, tokens: &mut TokenStream) {
1400             self.lifetimes.to_tokens(tokens);
1401             self.bounded_ty.to_tokens(tokens);
1402             self.colon_token.to_tokens(tokens);
1403             self.bounds.to_tokens(tokens);
1404         }
1405     }
1406 
1407     #[cfg(feature = "full")]
1408     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1409     impl ToTokens for PreciseCapture {
1410         fn to_tokens(&self, tokens: &mut TokenStream) {
1411             self.use_token.to_tokens(tokens);
1412             self.lt_token.to_tokens(tokens);
1413 
1414             // Print lifetimes before types and consts, regardless of their
1415             // order in self.params.
1416             let mut trailing_or_empty = true;
1417             for param in self.params.pairs() {
1418                 if let CapturedParam::Lifetime(_) = **param.value() {
1419                     param.to_tokens(tokens);
1420                     trailing_or_empty = param.punct().is_some();
1421                 }
1422             }
1423             for param in self.params.pairs() {
1424                 if let CapturedParam::Ident(_) = **param.value() {
1425                     if !trailing_or_empty {
1426                         <Token![,]>::default().to_tokens(tokens);
1427                         trailing_or_empty = true;
1428                     }
1429                     param.to_tokens(tokens);
1430                 }
1431             }
1432 
1433             self.gt_token.to_tokens(tokens);
1434         }
1435     }
1436 
1437     #[cfg(feature = "full")]
1438     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1439     impl ToTokens for CapturedParam {
1440         fn to_tokens(&self, tokens: &mut TokenStream) {
1441             match self {
1442                 CapturedParam::Lifetime(lifetime) => lifetime.to_tokens(tokens),
1443                 CapturedParam::Ident(ident) => ident.to_tokens(tokens),
1444             }
1445         }
1446     }
1447 
1448     pub(crate) fn print_const_argument(expr: &Expr, tokens: &mut TokenStream) {
1449         match expr {
1450             Expr::Lit(expr) => expr.to_tokens(tokens),
1451 
1452             Expr::Path(expr)
1453                 if expr.attrs.is_empty()
1454                     && expr.qself.is_none()
1455                     && expr.path.get_ident().is_some() =>
1456             {
1457                 expr.to_tokens(tokens);
1458             }
1459 
1460             #[cfg(feature = "full")]
1461             Expr::Block(expr) => expr.to_tokens(tokens),
1462 
1463             #[cfg(not(feature = "full"))]
1464             Expr::Verbatim(expr) => expr.to_tokens(tokens),
1465 
1466             // ERROR CORRECTION: Add braces to make sure that the
1467             // generated code is valid.
1468             _ => token::Brace::default().surround(tokens, |tokens| {
1469                 #[cfg(feature = "full")]
1470                 expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
1471 
1472                 #[cfg(not(feature = "full"))]
1473                 expr.to_tokens(tokens);
1474             }),
1475         }
1476     }
1477 }
1478