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: &GenericParam = match self.0.next() {
182 Some(item: &GenericParam) => item,
183 None => return None,
184 };
185 if let GenericParam::Lifetime(lifetime: &LifetimeParam) = 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: &mut GenericParam = match self.0.next() {
200 Some(item: &mut GenericParam) => item,
201 None => return None,
202 };
203 if let GenericParam::Lifetime(lifetime: &mut LifetimeParam) = 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: &GenericParam = match self.0.next() {
218 Some(item: &GenericParam) => item,
219 None => return None,
220 };
221 if let GenericParam::Type(type_param: &TypeParam) = 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: &mut GenericParam = match self.0.next() {
236 Some(item: &mut GenericParam) => item,
237 None => return None,
238 };
239 if let GenericParam::Type(type_param: &mut TypeParam) = 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: &GenericParam = match self.0.next() {
254 Some(item: &GenericParam) => item,
255 None => return None,
256 };
257 if let GenericParam::Const(const_param: &ConstParam) = 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: &mut GenericParam = match self.0.next() {
272 Some(item: &mut GenericParam) => item,
273 None => return None,
274 };
275 if let GenericParam::Const(const_param: &mut ConstParam) = 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;
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