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