Skip to main content

syn_impersonated/
generics.rs

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