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