syn_pub_items/
generics.rs

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