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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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(docsrs, 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 return_impl_trait! {
107 pub fn lifetimes(&self) -> impl Iterator<Item = &LifetimeParam> [Lifetimes] {
109 Lifetimes(self.params.iter())
110 }
111 }
112
113 return_impl_trait! {
114 pub fn lifetimes_mut(&mut self) -> impl Iterator<Item = &mut LifetimeParam> [LifetimesMut] {
116 LifetimesMut(self.params.iter_mut())
117 }
118 }
119
120 return_impl_trait! {
121 pub fn type_params(&self) -> impl Iterator<Item = &TypeParam> [TypeParams] {
123 TypeParams(self.params.iter())
124 }
125 }
126
127 return_impl_trait! {
128 pub fn type_params_mut(&mut self) -> impl Iterator<Item = &mut TypeParam> [TypeParamsMut] {
130 TypeParamsMut(self.params.iter_mut())
131 }
132 }
133
134 return_impl_trait! {
135 pub fn const_params(&self) -> impl Iterator<Item = &ConstParam> [ConstParams] {
137 ConstParams(self.params.iter())
138 }
139 }
140
141 return_impl_trait! {
142 pub fn const_params_mut(&mut self) -> impl Iterator<Item = &mut ConstParam> [ConstParamsMut] {
144 ConstParamsMut(self.params.iter_mut())
145 }
146 }
147
148 pub fn make_where_clause(&mut self) -> &mut WhereClause {
150 self.where_clause.get_or_insert_with(|| WhereClause {
151 where_token: <Token![where]>::default(),
152 predicates: Punctuated::new(),
153 })
154 }
155
156 #[cfg(feature = "printing")]
175 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
176 pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
177 (
178 ImplGenerics(self),
179 TypeGenerics(self),
180 self.where_clause.as_ref(),
181 )
182 }
183}
184
185pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
186
187impl<'a> Iterator for Lifetimes<'a> {
188 type Item = &'a LifetimeParam;
189
190 fn next(&mut self) -> Option<Self::Item> {
191 if let GenericParam::Lifetime(lifetime) = self.0.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 if let GenericParam::Lifetime(lifetime) = self.0.next()? {
206 Some(lifetime)
207 } else {
208 self.next()
209 }
210 }
211}
212
213pub struct TypeParams<'a>(Iter<'a, GenericParam>);
214
215impl<'a> Iterator for TypeParams<'a> {
216 type Item = &'a TypeParam;
217
218 fn next(&mut self) -> Option<Self::Item> {
219 if let GenericParam::Type(type_param) = self.0.next()? {
220 Some(type_param)
221 } else {
222 self.next()
223 }
224 }
225}
226
227pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
228
229impl<'a> Iterator for TypeParamsMut<'a> {
230 type Item = &'a mut TypeParam;
231
232 fn next(&mut self) -> Option<Self::Item> {
233 if let GenericParam::Type(type_param) = self.0.next()? {
234 Some(type_param)
235 } else {
236 self.next()
237 }
238 }
239}
240
241pub struct ConstParams<'a>(Iter<'a, GenericParam>);
242
243impl<'a> Iterator for ConstParams<'a> {
244 type Item = &'a ConstParam;
245
246 fn next(&mut self) -> Option<Self::Item> {
247 if let GenericParam::Const(const_param) = self.0.next()? {
248 Some(const_param)
249 } else {
250 self.next()
251 }
252 }
253}
254
255pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
256
257impl<'a> Iterator for ConstParamsMut<'a> {
258 type Item = &'a mut ConstParam;
259
260 fn next(&mut self) -> Option<Self::Item> {
261 if let GenericParam::Const(const_param) = self.0.next()? {
262 Some(const_param)
263 } else {
264 self.next()
265 }
266 }
267}
268
269#[cfg(feature = "printing")]
271#[cfg_attr(
272 docsrs,
273 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
274)]
275pub struct ImplGenerics<'a>(&'a Generics);
276
277#[cfg(feature = "printing")]
279#[cfg_attr(
280 docsrs,
281 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
282)]
283pub struct TypeGenerics<'a>(&'a Generics);
284
285#[cfg(feature = "printing")]
287#[cfg_attr(
288 docsrs,
289 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
290)]
291pub struct Turbofish<'a>(&'a Generics);
292
293#[cfg(feature = "printing")]
294macro_rules! generics_wrapper_impls {
295 ($ty:ident) => {
296 #[cfg(feature = "clone-impls")]
297 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
298 impl<'a> Clone for $ty<'a> {
299 fn clone(&self) -> Self {
300 $ty(self.0)
301 }
302 }
303
304 #[cfg(feature = "extra-traits")]
305 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
306 impl<'a> Debug for $ty<'a> {
307 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
308 formatter
309 .debug_tuple(stringify!($ty))
310 .field(self.0)
311 .finish()
312 }
313 }
314
315 #[cfg(feature = "extra-traits")]
316 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
317 impl<'a> Eq for $ty<'a> {}
318
319 #[cfg(feature = "extra-traits")]
320 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
321 impl<'a> PartialEq for $ty<'a> {
322 fn eq(&self, other: &Self) -> bool {
323 self.0 == other.0
324 }
325 }
326
327 #[cfg(feature = "extra-traits")]
328 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
329 impl<'a> Hash for $ty<'a> {
330 fn hash<H: Hasher>(&self, state: &mut H) {
331 self.0.hash(state);
332 }
333 }
334 };
335}
336
337#[cfg(feature = "printing")]
338generics_wrapper_impls!(ImplGenerics);
339#[cfg(feature = "printing")]
340generics_wrapper_impls!(TypeGenerics);
341#[cfg(feature = "printing")]
342generics_wrapper_impls!(Turbofish);
343
344#[cfg(feature = "printing")]
345impl<'a> TypeGenerics<'a> {
346 pub fn as_turbofish(&self) -> Turbofish {
348 Turbofish(self.0)
349 }
350}
351
352ast_struct! {
353 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
355 pub struct BoundLifetimes {
356 pub for_token: Token![for],
357 pub lt_token: Token![<],
358 pub lifetimes: Punctuated<GenericParam, Token![,]>,
359 pub gt_token: Token![>],
360 }
361}
362
363impl Default for BoundLifetimes {
364 fn default() -> Self {
365 BoundLifetimes {
366 for_token: Default::default(),
367 lt_token: Default::default(),
368 lifetimes: Punctuated::new(),
369 gt_token: Default::default(),
370 }
371 }
372}
373
374impl LifetimeParam {
375 pub fn new(lifetime: Lifetime) -> Self {
376 LifetimeParam {
377 attrs: Vec::new(),
378 lifetime,
379 colon_token: None,
380 bounds: Punctuated::new(),
381 }
382 }
383}
384
385impl From<Ident> for TypeParam {
386 fn from(ident: Ident) -> Self {
387 TypeParam {
388 attrs: vec![],
389 ident,
390 colon_token: None,
391 bounds: Punctuated::new(),
392 eq_token: None,
393 default: None,
394 }
395 }
396}
397
398ast_enum_of_structs! {
399 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
401 #[non_exhaustive]
402 pub enum TypeParamBound {
403 Trait(TraitBound),
404 Lifetime(Lifetime),
405 PreciseCapture(PreciseCapture),
406 Verbatim(TokenStream),
407 }
408}
409
410ast_struct! {
411 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
413 pub struct TraitBound {
414 pub paren_token: Option<token::Paren>,
415 pub modifier: TraitBoundModifier,
416 pub lifetimes: Option<BoundLifetimes>,
418 pub path: Path,
420 }
421}
422
423ast_enum! {
424 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
427 pub enum TraitBoundModifier {
428 None,
429 Maybe(Token![?]),
430 }
431}
432
433ast_struct! {
434 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
437 pub struct PreciseCapture #full {
438 pub use_token: Token![use],
439 pub lt_token: Token![<],
440 pub params: Punctuated<CapturedParam, Token![,]>,
441 pub gt_token: Token![>],
442 }
443}
444
445#[cfg(feature = "full")]
446ast_enum! {
447 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
449 #[non_exhaustive]
450 pub enum CapturedParam {
451 Lifetime(Lifetime),
454 Ident(Ident),
458 }
459}
460
461ast_struct! {
462 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
465 pub struct WhereClause {
466 pub where_token: Token![where],
467 pub predicates: Punctuated<WherePredicate, Token![,]>,
468 }
469}
470
471ast_enum_of_structs! {
472 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
480 #[non_exhaustive]
481 pub enum WherePredicate {
482 Lifetime(PredicateLifetime),
484
485 Type(PredicateType),
487 }
488}
489
490ast_struct! {
491 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
493 pub struct PredicateLifetime {
494 pub lifetime: Lifetime,
495 pub colon_token: Token![:],
496 pub bounds: Punctuated<Lifetime, Token![+]>,
497 }
498}
499
500ast_struct! {
501 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
503 pub struct PredicateType {
504 pub lifetimes: Option<BoundLifetimes>,
506 pub bounded_ty: Type,
508 pub colon_token: Token![:],
509 pub bounds: Punctuated<TypeParamBound, Token![+]>,
511 }
512}
513
514#[cfg(feature = "parsing")]
515pub(crate) mod parsing {
516 use crate::attr::Attribute;
517 use crate::error::{self, Result};
518 use crate::ext::IdentExt as _;
519 use crate::generics::{
520 BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
521 PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
522 WherePredicate,
523 };
524 #[cfg(feature = "full")]
525 use crate::generics::{CapturedParam, PreciseCapture};
526 use crate::ident::Ident;
527 use crate::lifetime::Lifetime;
528 use crate::parse::{Parse, ParseStream};
529 use crate::path::{self, ParenthesizedGenericArguments, Path, PathArguments};
530 use crate::punctuated::Punctuated;
531 use crate::token;
532 use crate::ty::Type;
533 use crate::verbatim;
534
535 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
536 impl Parse for Generics {
537 fn parse(input: ParseStream) -> Result<Self> {
538 if !input.peek(Token![<]) {
539 return Ok(Generics::default());
540 }
541
542 let lt_token: Token![<] = input.parse()?;
543
544 let mut params = Punctuated::new();
545 loop {
546 if input.peek(Token![>]) {
547 break;
548 }
549
550 let attrs = input.call(Attribute::parse_outer)?;
551 let lookahead = input.lookahead1();
552 if lookahead.peek(Lifetime) {
553 params.push_value(GenericParam::Lifetime(LifetimeParam {
554 attrs,
555 ..input.parse()?
556 }));
557 } else if lookahead.peek(Ident) {
558 params.push_value(GenericParam::Type(TypeParam {
559 attrs,
560 ..input.parse()?
561 }));
562 } else if lookahead.peek(Token![const]) {
563 params.push_value(GenericParam::Const(ConstParam {
564 attrs,
565 ..input.parse()?
566 }));
567 } else if input.peek(Token![_]) {
568 params.push_value(GenericParam::Type(TypeParam {
569 attrs,
570 ident: input.call(Ident::parse_any)?,
571 colon_token: None,
572 bounds: Punctuated::new(),
573 eq_token: None,
574 default: None,
575 }));
576 } else {
577 return Err(lookahead.error());
578 }
579
580 if input.peek(Token![>]) {
581 break;
582 }
583 let punct = input.parse()?;
584 params.push_punct(punct);
585 }
586
587 let gt_token: Token![>] = input.parse()?;
588
589 Ok(Generics {
590 lt_token: Some(lt_token),
591 params,
592 gt_token: Some(gt_token),
593 where_clause: None,
594 })
595 }
596 }
597
598 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
599 impl Parse for GenericParam {
600 fn parse(input: ParseStream) -> Result<Self> {
601 let attrs = input.call(Attribute::parse_outer)?;
602
603 let lookahead = input.lookahead1();
604 if lookahead.peek(Ident) {
605 Ok(GenericParam::Type(TypeParam {
606 attrs,
607 ..input.parse()?
608 }))
609 } else if lookahead.peek(Lifetime) {
610 Ok(GenericParam::Lifetime(LifetimeParam {
611 attrs,
612 ..input.parse()?
613 }))
614 } else if lookahead.peek(Token![const]) {
615 Ok(GenericParam::Const(ConstParam {
616 attrs,
617 ..input.parse()?
618 }))
619 } else {
620 Err(lookahead.error())
621 }
622 }
623 }
624
625 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
626 impl Parse for LifetimeParam {
627 fn parse(input: ParseStream) -> Result<Self> {
628 let has_colon;
629 Ok(LifetimeParam {
630 attrs: input.call(Attribute::parse_outer)?,
631 lifetime: input.parse()?,
632 colon_token: {
633 if input.peek(Token![:]) {
634 has_colon = true;
635 Some(input.parse()?)
636 } else {
637 has_colon = false;
638 None
639 }
640 },
641 bounds: {
642 let mut bounds = Punctuated::new();
643 if has_colon {
644 loop {
645 if input.peek(Token![,]) || input.peek(Token![>]) {
646 break;
647 }
648 let value = input.parse()?;
649 bounds.push_value(value);
650 if !input.peek(Token![+]) {
651 break;
652 }
653 let punct = input.parse()?;
654 bounds.push_punct(punct);
655 }
656 }
657 bounds
658 },
659 })
660 }
661 }
662
663 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
664 impl Parse for BoundLifetimes {
665 fn parse(input: ParseStream) -> Result<Self> {
666 Ok(BoundLifetimes {
667 for_token: input.parse()?,
668 lt_token: input.parse()?,
669 lifetimes: {
670 let mut lifetimes = Punctuated::new();
671 while !input.peek(Token![>]) {
672 let attrs = input.call(Attribute::parse_outer)?;
673 let lifetime: Lifetime = input.parse()?;
674 lifetimes.push_value(GenericParam::Lifetime(LifetimeParam {
675 attrs,
676 lifetime,
677 colon_token: None,
678 bounds: Punctuated::new(),
679 }));
680 if input.peek(Token![>]) {
681 break;
682 }
683 lifetimes.push_punct(input.parse()?);
684 }
685 lifetimes
686 },
687 gt_token: input.parse()?,
688 })
689 }
690 }
691
692 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
693 impl Parse for Option<BoundLifetimes> {
694 fn parse(input: ParseStream) -> Result<Self> {
695 if input.peek(Token![for]) {
696 input.parse().map(Some)
697 } else {
698 Ok(None)
699 }
700 }
701 }
702
703 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
704 impl Parse for TypeParam {
705 fn parse(input: ParseStream) -> Result<Self> {
706 let attrs = input.call(Attribute::parse_outer)?;
707 let ident: Ident = input.parse()?;
708 let colon_token: Option<Token![:]> = input.parse()?;
709
710 let mut bounds = Punctuated::new();
711 if colon_token.is_some() {
712 loop {
713 if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) {
714 break;
715 }
716 bounds.push_value({
717 let allow_precise_capture = false;
718 let allow_tilde_const = true;
719 TypeParamBound::parse_single(
720 input,
721 allow_precise_capture,
722 allow_tilde_const,
723 )?
724 });
725 if !input.peek(Token![+]) {
726 break;
727 }
728 let punct: Token![+] = input.parse()?;
729 bounds.push_punct(punct);
730 }
731 }
732
733 let eq_token: Option<Token![=]> = input.parse()?;
734 let default = if eq_token.is_some() {
735 Some(input.parse::<Type>()?)
736 } else {
737 None
738 };
739
740 Ok(TypeParam {
741 attrs,
742 ident,
743 colon_token,
744 bounds,
745 eq_token,
746 default,
747 })
748 }
749 }
750
751 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
752 impl Parse for TypeParamBound {
753 fn parse(input: ParseStream) -> Result<Self> {
754 let allow_precise_capture = true;
755 let allow_tilde_const = true;
756 Self::parse_single(input, allow_precise_capture, allow_tilde_const)
757 }
758 }
759
760 impl TypeParamBound {
761 pub(crate) fn parse_single(
762 input: ParseStream,
763 #[cfg_attr(not(feature = "full"), allow(unused_variables))] allow_precise_capture: bool,
764 allow_tilde_const: bool,
765 ) -> Result<Self> {
766 if input.peek(Lifetime) {
767 return input.parse().map(TypeParamBound::Lifetime);
768 }
769
770 let begin = input.fork();
771
772 #[cfg(feature = "full")]
773 {
774 if input.peek(Token![use]) {
775 let precise_capture: PreciseCapture = input.parse()?;
776 return if allow_precise_capture {
777 Ok(TypeParamBound::PreciseCapture(precise_capture))
778 } else {
779 let msg = "`use<...>` precise capturing syntax is not allowed here";
780 Err(error::new2(
781 precise_capture.use_token.span,
782 precise_capture.gt_token.span,
783 msg,
784 ))
785 };
786 }
787 }
788
789 let content;
790 let (paren_token, content) = if input.peek(token::Paren) {
791 (Some(parenthesized!(content in input)), &content)
792 } else {
793 (None, input)
794 };
795
796 let is_tilde_const =
797 cfg!(feature = "full") && content.peek(Token![~]) && content.peek2(Token![const]);
798 if is_tilde_const {
799 let tilde_token: Token![~] = content.parse()?;
800 let const_token: Token![const] = content.parse()?;
801 if !allow_tilde_const {
802 let msg = "`~const` is not allowed here";
803 return Err(error::new2(tilde_token.span, const_token.span, msg));
804 }
805 }
806
807 let mut bound: TraitBound = content.parse()?;
808 bound.paren_token = paren_token;
809
810 if is_tilde_const {
811 Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input)))
812 } else {
813 Ok(TypeParamBound::Trait(bound))
814 }
815 }
816
817 pub(crate) fn parse_multiple(
818 input: ParseStream,
819 allow_plus: bool,
820 allow_precise_capture: bool,
821 allow_tilde_const: bool,
822 ) -> Result<Punctuated<Self, Token![+]>> {
823 let mut bounds = Punctuated::new();
824 loop {
825 let bound = Self::parse_single(input, allow_precise_capture, allow_tilde_const)?;
826 bounds.push_value(bound);
827 if !(allow_plus && input.peek(Token![+])) {
828 break;
829 }
830 bounds.push_punct(input.parse()?);
831 if !(input.peek(Ident::peek_any)
832 || input.peek(Token![::])
833 || input.peek(Token![?])
834 || input.peek(Lifetime)
835 || input.peek(token::Paren)
836 || input.peek(Token![~]))
837 {
838 break;
839 }
840 }
841 Ok(bounds)
842 }
843 }
844
845 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
846 impl Parse for TraitBound {
847 fn parse(input: ParseStream) -> Result<Self> {
848 let modifier: TraitBoundModifier = input.parse()?;
849 let lifetimes: Option<BoundLifetimes> = input.parse()?;
850
851 let mut path: Path = input.parse()?;
852 if path.segments.last().unwrap().arguments.is_empty()
853 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
854 {
855 input.parse::<Option<Token![::]>>()?;
856 let args: ParenthesizedGenericArguments = input.parse()?;
857 let parenthesized = PathArguments::Parenthesized(args);
858 path.segments.last_mut().unwrap().arguments = parenthesized;
859 }
860
861 Ok(TraitBound {
862 paren_token: None,
863 modifier,
864 lifetimes,
865 path,
866 })
867 }
868 }
869
870 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
871 impl Parse for TraitBoundModifier {
872 fn parse(input: ParseStream) -> Result<Self> {
873 if input.peek(Token![?]) {
874 input.parse().map(TraitBoundModifier::Maybe)
875 } else {
876 Ok(TraitBoundModifier::None)
877 }
878 }
879 }
880
881 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
882 impl Parse for ConstParam {
883 fn parse(input: ParseStream) -> Result<Self> {
884 let mut default = None;
885 Ok(ConstParam {
886 attrs: input.call(Attribute::parse_outer)?,
887 const_token: input.parse()?,
888 ident: input.parse()?,
889 colon_token: input.parse()?,
890 ty: input.parse()?,
891 eq_token: {
892 if input.peek(Token![=]) {
893 let eq_token = input.parse()?;
894 default = Some(path::parsing::const_argument(input)?);
895 Some(eq_token)
896 } else {
897 None
898 }
899 },
900 default,
901 })
902 }
903 }
904
905 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
906 impl Parse for WhereClause {
907 fn parse(input: ParseStream) -> Result<Self> {
908 Ok(WhereClause {
909 where_token: input.parse()?,
910 predicates: {
911 let mut predicates = Punctuated::new();
912 loop {
913 if input.is_empty()
914 || input.peek(token::Brace)
915 || input.peek(Token![,])
916 || input.peek(Token![;])
917 || input.peek(Token![:]) && !input.peek(Token![::])
918 || input.peek(Token![=])
919 {
920 break;
921 }
922 let value = input.parse()?;
923 predicates.push_value(value);
924 if !input.peek(Token![,]) {
925 break;
926 }
927 let punct = input.parse()?;
928 predicates.push_punct(punct);
929 }
930 predicates
931 },
932 })
933 }
934 }
935
936 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
937 impl Parse for Option<WhereClause> {
938 fn parse(input: ParseStream) -> Result<Self> {
939 if input.peek(Token![where]) {
940 input.parse().map(Some)
941 } else {
942 Ok(None)
943 }
944 }
945 }
946
947 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
948 impl Parse for WherePredicate {
949 fn parse(input: ParseStream) -> Result<Self> {
950 if input.peek(Lifetime) && input.peek2(Token![:]) {
951 Ok(WherePredicate::Lifetime(PredicateLifetime {
952 lifetime: input.parse()?,
953 colon_token: input.parse()?,
954 bounds: {
955 let mut bounds = Punctuated::new();
956 loop {
957 if input.is_empty()
958 || input.peek(token::Brace)
959 || input.peek(Token![,])
960 || input.peek(Token![;])
961 || input.peek(Token![:])
962 || input.peek(Token![=])
963 {
964 break;
965 }
966 let value = input.parse()?;
967 bounds.push_value(value);
968 if !input.peek(Token![+]) {
969 break;
970 }
971 let punct = input.parse()?;
972 bounds.push_punct(punct);
973 }
974 bounds
975 },
976 }))
977 } else {
978 Ok(WherePredicate::Type(PredicateType {
979 lifetimes: input.parse()?,
980 bounded_ty: input.parse()?,
981 colon_token: input.parse()?,
982 bounds: {
983 let mut bounds = Punctuated::new();
984 loop {
985 if input.is_empty()
986 || input.peek(token::Brace)
987 || input.peek(Token![,])
988 || input.peek(Token![;])
989 || input.peek(Token![:]) && !input.peek(Token![::])
990 || input.peek(Token![=])
991 {
992 break;
993 }
994 bounds.push_value({
995 let allow_precise_capture = false;
996 let allow_tilde_const = true;
997 TypeParamBound::parse_single(
998 input,
999 allow_precise_capture,
1000 allow_tilde_const,
1001 )?
1002 });
1003 if !input.peek(Token![+]) {
1004 break;
1005 }
1006 let punct = input.parse()?;
1007 bounds.push_punct(punct);
1008 }
1009 bounds
1010 },
1011 }))
1012 }
1013 }
1014 }
1015
1016 #[cfg(feature = "full")]
1017 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1018 impl Parse for PreciseCapture {
1019 fn parse(input: ParseStream) -> Result<Self> {
1020 let use_token: Token![use] = input.parse()?;
1021 let lt_token: Token![<] = input.parse()?;
1022 let mut params = Punctuated::new();
1023 loop {
1024 let lookahead = input.lookahead1();
1025 params.push_value(
1026 if lookahead.peek(Lifetime) || lookahead.peek(Ident) || input.peek(Token![Self])
1027 {
1028 input.parse::<CapturedParam>()?
1029 } else if lookahead.peek(Token![>]) {
1030 break;
1031 } else {
1032 return Err(lookahead.error());
1033 },
1034 );
1035 let lookahead = input.lookahead1();
1036 params.push_punct(if lookahead.peek(Token![,]) {
1037 input.parse::<Token![,]>()?
1038 } else if lookahead.peek(Token![>]) {
1039 break;
1040 } else {
1041 return Err(lookahead.error());
1042 });
1043 }
1044 let gt_token: Token![>] = input.parse()?;
1045 Ok(PreciseCapture {
1046 use_token,
1047 lt_token,
1048 params,
1049 gt_token,
1050 })
1051 }
1052 }
1053
1054 #[cfg(feature = "full")]
1055 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1056 impl Parse for CapturedParam {
1057 fn parse(input: ParseStream) -> Result<Self> {
1058 let lookahead = input.lookahead1();
1059 if lookahead.peek(Lifetime) {
1060 input.parse().map(CapturedParam::Lifetime)
1061 } else if lookahead.peek(Ident) || input.peek(Token![Self]) {
1062 input.call(Ident::parse_any).map(CapturedParam::Ident)
1063 } else {
1064 Err(lookahead.error())
1065 }
1066 }
1067 }
1068}
1069
1070#[cfg(feature = "printing")]
1071pub(crate) mod printing {
1072 use crate::attr::FilterAttrs;
1073 #[cfg(feature = "full")]
1074 use crate::expr;
1075 use crate::expr::Expr;
1076 #[cfg(feature = "full")]
1077 use crate::fixup::FixupContext;
1078 use crate::generics::{
1079 BoundLifetimes, ConstParam, GenericParam, Generics, ImplGenerics, LifetimeParam,
1080 PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, Turbofish, TypeGenerics,
1081 TypeParam, WhereClause,
1082 };
1083 #[cfg(feature = "full")]
1084 use crate::generics::{CapturedParam, PreciseCapture};
1085 use crate::print::TokensOrDefault;
1086 use crate::token;
1087 use proc_macro2::TokenStream;
1088 use quote::{ToTokens, TokenStreamExt};
1089
1090 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1091 impl ToTokens for Generics {
1092 fn to_tokens(&self, tokens: &mut TokenStream) {
1093 if self.params.is_empty() {
1094 return;
1095 }
1096
1097 TokensOrDefault(&self.lt_token).to_tokens(tokens);
1098
1099 let mut trailing_or_empty = true;
1102 for param in self.params.pairs() {
1103 if let GenericParam::Lifetime(_) = **param.value() {
1104 param.to_tokens(tokens);
1105 trailing_or_empty = param.punct().is_some();
1106 }
1107 }
1108 for param in self.params.pairs() {
1109 match param.value() {
1110 GenericParam::Type(_) | GenericParam::Const(_) => {
1111 if !trailing_or_empty {
1112 <Token![,]>::default().to_tokens(tokens);
1113 trailing_or_empty = true;
1114 }
1115 param.to_tokens(tokens);
1116 }
1117 GenericParam::Lifetime(_) => {}
1118 }
1119 }
1120
1121 TokensOrDefault(&self.gt_token).to_tokens(tokens);
1122 }
1123 }
1124
1125 impl<'a> ToTokens for ImplGenerics<'a> {
1126 fn to_tokens(&self, tokens: &mut TokenStream) {
1127 if self.0.params.is_empty() {
1128 return;
1129 }
1130
1131 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1132
1133 let mut trailing_or_empty = true;
1136 for param in self.0.params.pairs() {
1137 if let GenericParam::Lifetime(_) = **param.value() {
1138 param.to_tokens(tokens);
1139 trailing_or_empty = param.punct().is_some();
1140 }
1141 }
1142 for param in self.0.params.pairs() {
1143 if let GenericParam::Lifetime(_) = **param.value() {
1144 continue;
1145 }
1146 if !trailing_or_empty {
1147 <Token![,]>::default().to_tokens(tokens);
1148 trailing_or_empty = true;
1149 }
1150 match param.value() {
1151 GenericParam::Lifetime(_) => unreachable!(),
1152 GenericParam::Type(param) => {
1153 tokens.append_all(param.attrs.outer());
1155 param.ident.to_tokens(tokens);
1156 if !param.bounds.is_empty() {
1157 TokensOrDefault(¶m.colon_token).to_tokens(tokens);
1158 param.bounds.to_tokens(tokens);
1159 }
1160 }
1161 GenericParam::Const(param) => {
1162 tokens.append_all(param.attrs.outer());
1164 param.const_token.to_tokens(tokens);
1165 param.ident.to_tokens(tokens);
1166 param.colon_token.to_tokens(tokens);
1167 param.ty.to_tokens(tokens);
1168 }
1169 }
1170 param.punct().to_tokens(tokens);
1171 }
1172
1173 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1174 }
1175 }
1176
1177 impl<'a> ToTokens for TypeGenerics<'a> {
1178 fn to_tokens(&self, tokens: &mut TokenStream) {
1179 if self.0.params.is_empty() {
1180 return;
1181 }
1182
1183 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1184
1185 let mut trailing_or_empty = true;
1188 for param in self.0.params.pairs() {
1189 if let GenericParam::Lifetime(def) = *param.value() {
1190 def.lifetime.to_tokens(tokens);
1192 param.punct().to_tokens(tokens);
1193 trailing_or_empty = param.punct().is_some();
1194 }
1195 }
1196 for param in self.0.params.pairs() {
1197 if let GenericParam::Lifetime(_) = **param.value() {
1198 continue;
1199 }
1200 if !trailing_or_empty {
1201 <Token![,]>::default().to_tokens(tokens);
1202 trailing_or_empty = true;
1203 }
1204 match param.value() {
1205 GenericParam::Lifetime(_) => unreachable!(),
1206 GenericParam::Type(param) => {
1207 param.ident.to_tokens(tokens);
1209 }
1210 GenericParam::Const(param) => {
1211 param.ident.to_tokens(tokens);
1213 }
1214 }
1215 param.punct().to_tokens(tokens);
1216 }
1217
1218 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1219 }
1220 }
1221
1222 impl<'a> ToTokens for Turbofish<'a> {
1223 fn to_tokens(&self, tokens: &mut TokenStream) {
1224 if !self.0.params.is_empty() {
1225 <Token![::]>::default().to_tokens(tokens);
1226 TypeGenerics(self.0).to_tokens(tokens);
1227 }
1228 }
1229 }
1230
1231 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1232 impl ToTokens for BoundLifetimes {
1233 fn to_tokens(&self, tokens: &mut TokenStream) {
1234 self.for_token.to_tokens(tokens);
1235 self.lt_token.to_tokens(tokens);
1236 self.lifetimes.to_tokens(tokens);
1237 self.gt_token.to_tokens(tokens);
1238 }
1239 }
1240
1241 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1242 impl ToTokens for LifetimeParam {
1243 fn to_tokens(&self, tokens: &mut TokenStream) {
1244 tokens.append_all(self.attrs.outer());
1245 self.lifetime.to_tokens(tokens);
1246 if !self.bounds.is_empty() {
1247 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1248 self.bounds.to_tokens(tokens);
1249 }
1250 }
1251 }
1252
1253 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1254 impl ToTokens for TypeParam {
1255 fn to_tokens(&self, tokens: &mut TokenStream) {
1256 tokens.append_all(self.attrs.outer());
1257 self.ident.to_tokens(tokens);
1258 if !self.bounds.is_empty() {
1259 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1260 self.bounds.to_tokens(tokens);
1261 }
1262 if let Some(default) = &self.default {
1263 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1264 default.to_tokens(tokens);
1265 }
1266 }
1267 }
1268
1269 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1270 impl ToTokens for TraitBound {
1271 fn to_tokens(&self, tokens: &mut TokenStream) {
1272 let to_tokens = |tokens: &mut TokenStream| {
1273 self.modifier.to_tokens(tokens);
1274 self.lifetimes.to_tokens(tokens);
1275 self.path.to_tokens(tokens);
1276 };
1277 match &self.paren_token {
1278 Some(paren) => paren.surround(tokens, to_tokens),
1279 None => to_tokens(tokens),
1280 }
1281 }
1282 }
1283
1284 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1285 impl ToTokens for TraitBoundModifier {
1286 fn to_tokens(&self, tokens: &mut TokenStream) {
1287 match self {
1288 TraitBoundModifier::None => {}
1289 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1290 }
1291 }
1292 }
1293
1294 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1295 impl ToTokens for ConstParam {
1296 fn to_tokens(&self, tokens: &mut TokenStream) {
1297 tokens.append_all(self.attrs.outer());
1298 self.const_token.to_tokens(tokens);
1299 self.ident.to_tokens(tokens);
1300 self.colon_token.to_tokens(tokens);
1301 self.ty.to_tokens(tokens);
1302 if let Some(default) = &self.default {
1303 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1304 print_const_argument(default, tokens);
1305 }
1306 }
1307 }
1308
1309 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1310 impl ToTokens for WhereClause {
1311 fn to_tokens(&self, tokens: &mut TokenStream) {
1312 if !self.predicates.is_empty() {
1313 self.where_token.to_tokens(tokens);
1314 self.predicates.to_tokens(tokens);
1315 }
1316 }
1317 }
1318
1319 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1320 impl ToTokens for PredicateLifetime {
1321 fn to_tokens(&self, tokens: &mut TokenStream) {
1322 self.lifetime.to_tokens(tokens);
1323 self.colon_token.to_tokens(tokens);
1324 self.bounds.to_tokens(tokens);
1325 }
1326 }
1327
1328 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1329 impl ToTokens for PredicateType {
1330 fn to_tokens(&self, tokens: &mut TokenStream) {
1331 self.lifetimes.to_tokens(tokens);
1332 self.bounded_ty.to_tokens(tokens);
1333 self.colon_token.to_tokens(tokens);
1334 self.bounds.to_tokens(tokens);
1335 }
1336 }
1337
1338 #[cfg(feature = "full")]
1339 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1340 impl ToTokens for PreciseCapture {
1341 fn to_tokens(&self, tokens: &mut TokenStream) {
1342 self.use_token.to_tokens(tokens);
1343 self.lt_token.to_tokens(tokens);
1344
1345 let mut trailing_or_empty = true;
1348 for param in self.params.pairs() {
1349 if let CapturedParam::Lifetime(_) = **param.value() {
1350 param.to_tokens(tokens);
1351 trailing_or_empty = param.punct().is_some();
1352 }
1353 }
1354 for param in self.params.pairs() {
1355 if let CapturedParam::Ident(_) = **param.value() {
1356 if !trailing_or_empty {
1357 <Token![,]>::default().to_tokens(tokens);
1358 trailing_or_empty = true;
1359 }
1360 param.to_tokens(tokens);
1361 }
1362 }
1363
1364 self.gt_token.to_tokens(tokens);
1365 }
1366 }
1367
1368 #[cfg(feature = "full")]
1369 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1370 impl ToTokens for CapturedParam {
1371 fn to_tokens(&self, tokens: &mut TokenStream) {
1372 match self {
1373 CapturedParam::Lifetime(lifetime) => lifetime.to_tokens(tokens),
1374 CapturedParam::Ident(ident) => ident.to_tokens(tokens),
1375 }
1376 }
1377 }
1378
1379 pub(crate) fn print_const_argument(expr: &Expr, tokens: &mut TokenStream) {
1380 match expr {
1381 Expr::Lit(expr) => expr.to_tokens(tokens),
1382
1383 Expr::Path(expr)
1384 if expr.attrs.is_empty()
1385 && expr.qself.is_none()
1386 && expr.path.get_ident().is_some() =>
1387 {
1388 expr.to_tokens(tokens);
1389 }
1390
1391 #[cfg(feature = "full")]
1392 Expr::Block(expr) => expr.to_tokens(tokens),
1393
1394 #[cfg(not(feature = "full"))]
1395 Expr::Verbatim(expr) => expr.to_tokens(tokens),
1396
1397 _ => token::Brace::default().surround(tokens, |tokens| {
1400 #[cfg(feature = "full")]
1401 expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
1402
1403 #[cfg(not(feature = "full"))]
1404 expr.to_tokens(tokens);
1405 }),
1406 }
1407 }
1408}