Skip to main content

syn/
generics.rs

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