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