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