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 alloc::vec::Vec;
10#[cfg(all(feature = "printing", feature = "extra-traits"))]
11use core::fmt::{self, Debug};
12#[cfg(all(feature = "printing", feature = "extra-traits"))]
13use core::hash::{Hash, Hasher};
14use proc_macro2::TokenStream;
15
16ast_struct! {
17 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
27 pub struct Generics {
28 pub lt_token: Option<Token![<]>,
29 pub params: Punctuated<GenericParam, Token![,]>,
30 pub gt_token: Option<Token![>]>,
31 pub where_clause: Option<WhereClause>,
32 }
33}
34
35ast_enum_of_structs! {
36 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
45 pub enum GenericParam {
46 Lifetime(LifetimeParam),
48
49 Type(TypeParam),
51
52 Const(ConstParam),
54 }
55}
56
57ast_struct! {
58 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
60 pub struct LifetimeParam {
61 pub attrs: Vec<Attribute>,
62 pub lifetime: Lifetime,
63 pub colon_token: Option<Token![:]>,
64 pub bounds: Punctuated<Lifetime, Token![+]>,
65 }
66}
67
68ast_struct! {
69 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
71 pub struct TypeParam {
72 pub attrs: Vec<Attribute>,
73 pub ident: Ident,
74 pub colon_token: Option<Token![:]>,
75 pub bounds: Punctuated<TypeParamBound, Token![+]>,
76 pub eq_token: Option<Token![=]>,
77 pub default: Option<Type>,
78 }
79}
80
81ast_struct! {
82 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
84 pub struct ConstParam {
85 pub attrs: Vec<Attribute>,
86 pub const_token: Token![const],
87 pub ident: Ident,
88 pub colon_token: Token![:],
89 pub ty: Type,
90 pub eq_token: Option<Token![=]>,
91 pub default: Option<Expr>,
92 }
93}
94
95impl Default for Generics {
96 fn default() -> Self {
97 Generics {
98 lt_token: None,
99 params: Punctuated::new(),
100 gt_token: None,
101 where_clause: None,
102 }
103 }
104}
105
106impl Generics {
107 return_impl_trait! {
108 pub fn lifetimes(&self) -> impl Iterator<Item = &LifetimeParam> [Lifetimes] {
110 Lifetimes(self.params.iter())
111 }
112 }
113
114 return_impl_trait! {
115 pub fn lifetimes_mut(&mut self) -> impl Iterator<Item = &mut LifetimeParam> [LifetimesMut] {
117 LifetimesMut(self.params.iter_mut())
118 }
119 }
120
121 return_impl_trait! {
122 pub fn type_params(&self) -> impl Iterator<Item = &TypeParam> [TypeParams] {
124 TypeParams(self.params.iter())
125 }
126 }
127
128 return_impl_trait! {
129 pub fn type_params_mut(&mut self) -> impl Iterator<Item = &mut TypeParam> [TypeParamsMut] {
131 TypeParamsMut(self.params.iter_mut())
132 }
133 }
134
135 return_impl_trait! {
136 pub fn const_params(&self) -> impl Iterator<Item = &ConstParam> [ConstParams] {
138 ConstParams(self.params.iter())
139 }
140 }
141
142 return_impl_trait! {
143 pub fn const_params_mut(&mut self) -> impl Iterator<Item = &mut ConstParam> [ConstParamsMut] {
145 ConstParamsMut(self.params.iter_mut())
146 }
147 }
148
149 pub fn make_where_clause(&mut self) -> &mut WhereClause {
151 self.where_clause.get_or_insert_with(|| WhereClause {
152 where_token: <Token![where]>::default(),
153 predicates: Punctuated::new(),
154 })
155 }
156
157 #[cfg(feature = "printing")]
176 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
177 pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) {
178 (
179 ImplGenerics(self),
180 TypeGenerics(self),
181 self.where_clause.as_ref(),
182 )
183 }
184}
185
186pub struct Lifetimes<'a>(Iter<'a, GenericParam>);
187
188impl<'a> Iterator for Lifetimes<'a> {
189 type Item = &'a LifetimeParam;
190
191 fn next(&mut self) -> Option<Self::Item> {
192 if let GenericParam::Lifetime(lifetime) = self.0.next()? {
193 Some(lifetime)
194 } else {
195 self.next()
196 }
197 }
198}
199
200pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>);
201
202impl<'a> Iterator for LifetimesMut<'a> {
203 type Item = &'a mut LifetimeParam;
204
205 fn next(&mut self) -> Option<Self::Item> {
206 if let GenericParam::Lifetime(lifetime) = self.0.next()? {
207 Some(lifetime)
208 } else {
209 self.next()
210 }
211 }
212}
213
214pub struct TypeParams<'a>(Iter<'a, GenericParam>);
215
216impl<'a> Iterator for TypeParams<'a> {
217 type Item = &'a TypeParam;
218
219 fn next(&mut self) -> Option<Self::Item> {
220 if let GenericParam::Type(type_param) = self.0.next()? {
221 Some(type_param)
222 } else {
223 self.next()
224 }
225 }
226}
227
228pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>);
229
230impl<'a> Iterator for TypeParamsMut<'a> {
231 type Item = &'a mut TypeParam;
232
233 fn next(&mut self) -> Option<Self::Item> {
234 if let GenericParam::Type(type_param) = self.0.next()? {
235 Some(type_param)
236 } else {
237 self.next()
238 }
239 }
240}
241
242pub struct ConstParams<'a>(Iter<'a, GenericParam>);
243
244impl<'a> Iterator for ConstParams<'a> {
245 type Item = &'a ConstParam;
246
247 fn next(&mut self) -> Option<Self::Item> {
248 if let GenericParam::Const(const_param) = self.0.next()? {
249 Some(const_param)
250 } else {
251 self.next()
252 }
253 }
254}
255
256pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>);
257
258impl<'a> Iterator for ConstParamsMut<'a> {
259 type Item = &'a mut ConstParam;
260
261 fn next(&mut self) -> Option<Self::Item> {
262 if let GenericParam::Const(const_param) = self.0.next()? {
263 Some(const_param)
264 } else {
265 self.next()
266 }
267 }
268}
269
270#[cfg(feature = "printing")]
272#[cfg_attr(
273 docsrs,
274 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
275)]
276pub struct ImplGenerics<'a>(&'a Generics);
277
278#[cfg(feature = "printing")]
280#[cfg_attr(
281 docsrs,
282 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
283)]
284pub struct TypeGenerics<'a>(&'a Generics);
285
286#[cfg(feature = "printing")]
288#[cfg_attr(
289 docsrs,
290 doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing")))
291)]
292pub struct Turbofish<'a>(&'a Generics);
293
294#[cfg(feature = "printing")]
295macro_rules! generics_wrapper_impls {
296 ($ty:ident) => {
297 #[cfg(feature = "clone-impls")]
298 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
299 impl<'a> Clone for $ty<'a> {
300 fn clone(&self) -> Self {
301 $ty(self.0)
302 }
303 }
304
305 #[cfg(feature = "extra-traits")]
306 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
307 impl<'a> Debug for $ty<'a> {
308 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
309 formatter
310 .debug_tuple(stringify!($ty))
311 .field(self.0)
312 .finish()
313 }
314 }
315
316 #[cfg(feature = "extra-traits")]
317 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
318 impl<'a> Eq for $ty<'a> {}
319
320 #[cfg(feature = "extra-traits")]
321 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
322 impl<'a> PartialEq for $ty<'a> {
323 fn eq(&self, other: &Self) -> bool {
324 self.0 == other.0
325 }
326 }
327
328 #[cfg(feature = "extra-traits")]
329 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
330 impl<'a> Hash for $ty<'a> {
331 fn hash<H: Hasher>(&self, state: &mut H) {
332 self.0.hash(state);
333 }
334 }
335 };
336}
337
338#[cfg(feature = "printing")]
339generics_wrapper_impls!(ImplGenerics);
340#[cfg(feature = "printing")]
341generics_wrapper_impls!(TypeGenerics);
342#[cfg(feature = "printing")]
343generics_wrapper_impls!(Turbofish);
344
345#[cfg(feature = "printing")]
346impl<'a> TypeGenerics<'a> {
347 pub fn as_turbofish(&self) -> Turbofish<'a> {
349 Turbofish(self.0)
350 }
351}
352
353ast_struct! {
354 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
356 pub struct BoundLifetimes {
357 pub for_token: Token![for],
358 pub lt_token: Token![<],
359 pub lifetimes: Punctuated<GenericParam, Token![,]>,
360 pub gt_token: Token![>],
361 }
362}
363
364impl Default for BoundLifetimes {
365 fn default() -> Self {
366 BoundLifetimes {
367 for_token: Default::default(),
368 lt_token: Default::default(),
369 lifetimes: Punctuated::new(),
370 gt_token: Default::default(),
371 }
372 }
373}
374
375impl LifetimeParam {
376 pub fn new(lifetime: Lifetime) -> Self {
377 LifetimeParam {
378 attrs: Vec::new(),
379 lifetime,
380 colon_token: None,
381 bounds: Punctuated::new(),
382 }
383 }
384}
385
386impl From<Ident> for TypeParam {
387 fn from(ident: Ident) -> Self {
388 TypeParam {
389 attrs: Vec::new(),
390 ident,
391 colon_token: None,
392 bounds: Punctuated::new(),
393 eq_token: None,
394 default: None,
395 }
396 }
397}
398
399ast_enum_of_structs! {
400 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
402 #[non_exhaustive]
403 pub enum TypeParamBound {
404 Trait(TraitBound),
405 Lifetime(Lifetime),
406 PreciseCapture(PreciseCapture),
407 Verbatim(TokenStream),
408 }
409}
410
411ast_struct! {
412 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
414 pub struct TraitBound {
415 pub paren_token: Option<token::Paren>,
416 pub modifier: TraitBoundModifier,
417 pub lifetimes: Option<BoundLifetimes>,
419 pub path: Path,
421 }
422}
423
424ast_enum! {
425 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
428 pub enum TraitBoundModifier {
429 None,
430 Maybe(Token![?]),
431 }
432}
433
434ast_struct! {
435 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
438 pub struct PreciseCapture #full {
439 pub use_token: Token![use],
440 pub lt_token: Token![<],
441 pub params: Punctuated<CapturedParam, Token![,]>,
442 pub gt_token: Token![>],
443 }
444}
445
446#[cfg(feature = "full")]
447ast_enum! {
448 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
450 #[non_exhaustive]
451 pub enum CapturedParam {
452 Lifetime(Lifetime),
455 Ident(Ident),
459 }
460}
461
462ast_struct! {
463 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
466 pub struct WhereClause {
467 pub where_token: Token![where],
468 pub predicates: Punctuated<WherePredicate, Token![,]>,
469 }
470}
471
472ast_enum_of_structs! {
473 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
481 #[non_exhaustive]
482 pub enum WherePredicate {
483 Lifetime(PredicateLifetime),
485
486 Type(PredicateType),
488 }
489}
490
491ast_struct! {
492 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
494 pub struct PredicateLifetime {
495 pub lifetime: Lifetime,
496 pub colon_token: Token![:],
497 pub bounds: Punctuated<Lifetime, Token![+]>,
498 }
499}
500
501ast_struct! {
502 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
504 pub struct PredicateType {
505 pub lifetimes: Option<BoundLifetimes>,
507 pub bounded_ty: Type,
509 pub colon_token: Token![:],
510 pub bounds: Punctuated<TypeParamBound, Token![+]>,
512 }
513}
514
515#[cfg(feature = "parsing")]
516pub(crate) mod parsing {
517 use crate::attr::Attribute;
518 #[cfg(feature = "full")]
519 use crate::error;
520 use crate::error::{Error, Result};
521 use crate::ext::IdentExt as _;
522 use crate::generics::{
523 BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
524 PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
525 WherePredicate,
526 };
527 #[cfg(feature = "full")]
528 use crate::generics::{CapturedParam, PreciseCapture};
529 use crate::ident::Ident;
530 use crate::lifetime::Lifetime;
531 use crate::parse::{Parse, ParseStream};
532 use crate::path::{self, ParenthesizedGenericArguments, Path, PathArguments};
533 use crate::punctuated::Punctuated;
534 use crate::token;
535 use crate::ty::Type;
536 use crate::verbatim;
537
538 #[cfg_attr(docsrs, 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(docsrs, 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(docsrs, 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.is_empty() || 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(docsrs, 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 lifetimes.push_value(input.parse()?);
676 if input.peek(Token![>]) {
677 break;
678 }
679 lifetimes.push_punct(input.parse()?);
680 }
681 lifetimes
682 },
683 gt_token: input.parse()?,
684 })
685 }
686 }
687
688 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
689 impl Parse for Option<BoundLifetimes> {
690 fn parse(input: ParseStream) -> Result<Self> {
691 if input.peek(Token![for]) {
692 input.parse().map(Some)
693 } else {
694 Ok(None)
695 }
696 }
697 }
698
699 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
700 impl Parse for TypeParam {
701 fn parse(input: ParseStream) -> Result<Self> {
702 let attrs = input.call(Attribute::parse_outer)?;
703 let ident: Ident = input.parse()?;
704 let colon_token: Option<Token![:]> = input.parse()?;
705
706 let mut bounds = Punctuated::new();
707 if colon_token.is_some() {
708 loop {
709 if input.is_empty()
710 || input.peek(Token![,])
711 || input.peek(Token![>])
712 || input.peek(Token![=])
713 {
714 break;
715 }
716 bounds.push_value({
717 let allow_precise_capture = false;
718 let allow_const = true;
719 TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
720 });
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(docsrs, doc(cfg(feature = "parsing")))]
748 impl Parse for TypeParamBound {
749 fn parse(input: ParseStream) -> Result<Self> {
750 let allow_precise_capture = true;
751 let allow_const = true;
752 Self::parse_single(input, allow_precise_capture, allow_const)
753 }
754 }
755
756 impl TypeParamBound {
757 pub(crate) fn parse_single(
758 input: ParseStream,
759 #[cfg_attr(not(feature = "full"), allow(unused_variables))] allow_precise_capture: bool,
760 allow_const: bool,
761 ) -> Result<Self> {
762 if input.peek(Lifetime) {
763 return input.parse().map(TypeParamBound::Lifetime);
764 }
765
766 #[cfg(feature = "full")]
767 {
768 if input.peek(Token![use]) {
769 let precise_capture: PreciseCapture = input.parse()?;
770 return if allow_precise_capture {
771 Ok(TypeParamBound::PreciseCapture(precise_capture))
772 } else {
773 let msg = "`use<...>` precise capturing syntax is not allowed here";
774 Err(error::new2(
775 precise_capture.use_token.span,
776 precise_capture.gt_token.span,
777 msg,
778 ))
779 };
780 }
781 }
782
783 let begin = input.fork();
784
785 let content;
786 let (paren_token, content) = if input.peek(token::Paren) {
787 (Some(parenthesized!(content in input)), &content)
788 } else {
789 (None, input)
790 };
791
792 if let Some(mut bound) = TraitBound::do_parse(content, allow_const)? {
793 bound.paren_token = paren_token;
794 Ok(TypeParamBound::Trait(bound))
795 } else {
796 Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input)))
797 }
798 }
799
800 pub(crate) fn parse_multiple(
801 input: ParseStream,
802 allow_plus: bool,
803 allow_precise_capture: bool,
804 allow_const: bool,
805 ) -> Result<Punctuated<Self, Token![+]>> {
806 let mut bounds = Punctuated::new();
807 loop {
808 let bound = Self::parse_single(input, allow_precise_capture, allow_const)?;
809 bounds.push_value(bound);
810 if !(allow_plus && input.peek(Token![+])) {
811 break;
812 }
813 bounds.push_punct(input.parse()?);
814 if !(input.peek(Ident::peek_any)
815 || input.peek(Token![::])
816 || input.peek(Token![?])
817 || input.peek(Lifetime)
818 || input.peek(token::Paren)
819 || (allow_const && (input.peek(token::Bracket) || input.peek(Token![const]))))
820 {
821 break;
822 }
823 }
824 Ok(bounds)
825 }
826 }
827
828 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
829 impl Parse for TraitBound {
830 fn parse(input: ParseStream) -> Result<Self> {
831 let allow_const = false;
832 Self::do_parse(input, allow_const).map(Option::unwrap)
833 }
834 }
835
836 impl TraitBound {
837 fn do_parse(input: ParseStream, allow_const: bool) -> Result<Option<Self>> {
838 let mut lifetimes: Option<BoundLifetimes> = input.parse()?;
839
840 let is_conditionally_const = cfg!(feature = "full") && input.peek(token::Bracket);
841 let is_unconditionally_const = cfg!(feature = "full") && input.peek(Token![const]);
842 if is_conditionally_const {
843 let conditionally_const;
844 let bracket_token = bracketed!(conditionally_const in input);
845 conditionally_const.parse::<Token![const]>()?;
846 if !allow_const {
847 let msg = "`[const]` is not allowed here";
848 return Err(Error::new(bracket_token.span.join(), msg));
849 }
850 } else if is_unconditionally_const {
851 let const_token: Token![const] = input.parse()?;
852 if !allow_const {
853 let msg = "`const` is not allowed here";
854 return Err(Error::new(const_token.span, msg));
855 }
856 }
857
858 let modifier: TraitBoundModifier = input.parse()?;
859 if lifetimes.is_none() && matches!(modifier, TraitBoundModifier::Maybe(_)) {
860 lifetimes = input.parse()?;
861 }
862
863 let mut path: Path = input.parse()?;
864 if path.segments.last().unwrap().arguments.is_empty()
865 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
866 {
867 input.parse::<Option<Token![::]>>()?;
868 let args: ParenthesizedGenericArguments = input.parse()?;
869 let parenthesized = PathArguments::Parenthesized(args);
870 path.segments.last_mut().unwrap().arguments = parenthesized;
871 }
872
873 if lifetimes.is_some() {
874 match modifier {
875 TraitBoundModifier::None => {}
876 TraitBoundModifier::Maybe(maybe) => {
877 let msg = "`for<...>` binder not allowed with `?` trait polarity modifier";
878 return Err(Error::new(maybe.span, msg));
879 }
880 }
881 }
882
883 if is_conditionally_const || is_unconditionally_const {
884 Ok(None)
885 } else {
886 Ok(Some(TraitBound {
887 paren_token: None,
888 modifier,
889 lifetimes,
890 path,
891 }))
892 }
893 }
894 }
895
896 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
897 impl Parse for TraitBoundModifier {
898 fn parse(input: ParseStream) -> Result<Self> {
899 if input.peek(Token![?]) {
900 input.parse().map(TraitBoundModifier::Maybe)
901 } else {
902 Ok(TraitBoundModifier::None)
903 }
904 }
905 }
906
907 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
908 impl Parse for ConstParam {
909 fn parse(input: ParseStream) -> Result<Self> {
910 let mut default = None;
911 Ok(ConstParam {
912 attrs: input.call(Attribute::parse_outer)?,
913 const_token: input.parse()?,
914 ident: input.parse()?,
915 colon_token: input.parse()?,
916 ty: input.parse()?,
917 eq_token: {
918 if input.peek(Token![=]) {
919 let eq_token = input.parse()?;
920 default = Some(path::parsing::const_argument(input)?);
921 Some(eq_token)
922 } else {
923 None
924 }
925 },
926 default,
927 })
928 }
929 }
930
931 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
932 impl Parse for WhereClause {
933 fn parse(input: ParseStream) -> Result<Self> {
934 let where_token: Token![where] = input.parse()?;
935
936 if choose_generics_over_qpath(input) {
937 return Err(input
938 .error("generic parameters on `where` clauses are reserved for future use"));
939 }
940
941 Ok(WhereClause {
942 where_token,
943 predicates: {
944 let mut predicates = Punctuated::new();
945 loop {
946 if input.is_empty()
947 || input.peek(token::Brace)
948 || input.peek(Token![,])
949 || input.peek(Token![;])
950 || input.peek(Token![:]) && !input.peek(Token![::])
951 || input.peek(Token![=])
952 {
953 break;
954 }
955 let value = input.parse()?;
956 predicates.push_value(value);
957 if !input.peek(Token![,]) {
958 break;
959 }
960 let punct = input.parse()?;
961 predicates.push_punct(punct);
962 }
963 predicates
964 },
965 })
966 }
967 }
968
969 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
970 impl Parse for Option<WhereClause> {
971 fn parse(input: ParseStream) -> Result<Self> {
972 if input.peek(Token![where]) {
973 input.parse().map(Some)
974 } else {
975 Ok(None)
976 }
977 }
978 }
979
980 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
981 impl Parse for WherePredicate {
982 fn parse(input: ParseStream) -> Result<Self> {
983 if input.peek(Lifetime) && input.peek2(Token![:]) {
984 Ok(WherePredicate::Lifetime(PredicateLifetime {
985 lifetime: input.parse()?,
986 colon_token: input.parse()?,
987 bounds: {
988 let mut bounds = Punctuated::new();
989 loop {
990 if input.is_empty()
991 || input.peek(token::Brace)
992 || input.peek(Token![,])
993 || input.peek(Token![;])
994 || input.peek(Token![:])
995 || input.peek(Token![=])
996 {
997 break;
998 }
999 let value = input.parse()?;
1000 bounds.push_value(value);
1001 if !input.peek(Token![+]) {
1002 break;
1003 }
1004 let punct = input.parse()?;
1005 bounds.push_punct(punct);
1006 }
1007 bounds
1008 },
1009 }))
1010 } else {
1011 Ok(WherePredicate::Type(PredicateType {
1012 lifetimes: input.parse()?,
1013 bounded_ty: input.parse()?,
1014 colon_token: input.parse()?,
1015 bounds: {
1016 let mut bounds = Punctuated::new();
1017 loop {
1018 if input.is_empty()
1019 || input.peek(token::Brace)
1020 || input.peek(Token![,])
1021 || input.peek(Token![;])
1022 || input.peek(Token![:]) && !input.peek(Token![::])
1023 || input.peek(Token![=])
1024 {
1025 break;
1026 }
1027 bounds.push_value({
1028 let allow_precise_capture = false;
1029 let allow_const = true;
1030 TypeParamBound::parse_single(
1031 input,
1032 allow_precise_capture,
1033 allow_const,
1034 )?
1035 });
1036 if !input.peek(Token![+]) {
1037 break;
1038 }
1039 let punct = input.parse()?;
1040 bounds.push_punct(punct);
1041 }
1042 bounds
1043 },
1044 }))
1045 }
1046 }
1047 }
1048
1049 #[cfg(feature = "full")]
1050 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1051 impl Parse for PreciseCapture {
1052 fn parse(input: ParseStream) -> Result<Self> {
1053 let use_token: Token![use] = input.parse()?;
1054 let lt_token: Token![<] = input.parse()?;
1055 let mut params = Punctuated::new();
1056 loop {
1057 let lookahead = input.lookahead1();
1058 params.push_value(
1059 if lookahead.peek(Lifetime) || lookahead.peek(Ident) || input.peek(Token![Self])
1060 {
1061 input.parse::<CapturedParam>()?
1062 } else if lookahead.peek(Token![>]) {
1063 break;
1064 } else {
1065 return Err(lookahead.error());
1066 },
1067 );
1068 let lookahead = input.lookahead1();
1069 params.push_punct(if lookahead.peek(Token![,]) {
1070 input.parse::<Token![,]>()?
1071 } else if lookahead.peek(Token![>]) {
1072 break;
1073 } else {
1074 return Err(lookahead.error());
1075 });
1076 }
1077 let gt_token: Token![>] = input.parse()?;
1078 Ok(PreciseCapture {
1079 use_token,
1080 lt_token,
1081 params,
1082 gt_token,
1083 })
1084 }
1085 }
1086
1087 #[cfg(feature = "full")]
1088 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1089 impl Parse for CapturedParam {
1090 fn parse(input: ParseStream) -> Result<Self> {
1091 let lookahead = input.lookahead1();
1092 if lookahead.peek(Lifetime) {
1093 input.parse().map(CapturedParam::Lifetime)
1094 } else if lookahead.peek(Ident) || input.peek(Token![Self]) {
1095 input.call(Ident::parse_any).map(CapturedParam::Ident)
1096 } else {
1097 Err(lookahead.error())
1098 }
1099 }
1100 }
1101
1102 pub(crate) fn choose_generics_over_qpath(input: ParseStream) -> bool {
1103 input.peek(Token![<])
1126 && (input.peek2(Token![>])
1127 || input.peek2(Token![#])
1128 || (input.peek2(Lifetime) || input.peek2(Ident))
1129 && (input.peek3(Token![>])
1130 || input.peek3(Token![,])
1131 || input.peek3(Token![:]) && !input.peek3(Token![::])
1132 || input.peek3(Token![=]))
1133 || input.peek2(Token![const]))
1134 }
1135
1136 #[cfg(feature = "full")]
1137 pub(crate) fn choose_generics_over_qpath_after_keyword(input: ParseStream) -> bool {
1138 let input = input.fork();
1139 input.call(Ident::parse_any).unwrap(); choose_generics_over_qpath(&input)
1141 }
1142}
1143
1144#[cfg(feature = "printing")]
1145pub(crate) mod printing {
1146 use crate::attr::FilterAttrs;
1147 #[cfg(feature = "full")]
1148 use crate::expr;
1149 use crate::expr::Expr;
1150 #[cfg(feature = "full")]
1151 use crate::fixup::FixupContext;
1152 use crate::generics::{
1153 BoundLifetimes, ConstParam, GenericParam, Generics, ImplGenerics, LifetimeParam,
1154 PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, Turbofish, TypeGenerics,
1155 TypeParam, WhereClause,
1156 };
1157 #[cfg(feature = "full")]
1158 use crate::generics::{CapturedParam, PreciseCapture};
1159 use crate::print::TokensOrDefault;
1160 use crate::token;
1161 use proc_macro2::TokenStream;
1162 use quote::{ToTokens, TokenStreamExt as _};
1163
1164 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1165 impl ToTokens for Generics {
1166 fn to_tokens(&self, tokens: &mut TokenStream) {
1167 if self.params.is_empty() {
1168 return;
1169 }
1170
1171 TokensOrDefault(&self.lt_token).to_tokens(tokens);
1172
1173 let mut trailing_or_empty = true;
1176 for param in self.params.pairs() {
1177 if let GenericParam::Lifetime(_) = **param.value() {
1178 param.to_tokens(tokens);
1179 trailing_or_empty = param.punct().is_some();
1180 }
1181 }
1182 for param in self.params.pairs() {
1183 match param.value() {
1184 GenericParam::Type(_) | GenericParam::Const(_) => {
1185 if !trailing_or_empty {
1186 <Token![,]>::default().to_tokens(tokens);
1187 trailing_or_empty = true;
1188 }
1189 param.to_tokens(tokens);
1190 }
1191 GenericParam::Lifetime(_) => {}
1192 }
1193 }
1194
1195 TokensOrDefault(&self.gt_token).to_tokens(tokens);
1196 }
1197 }
1198
1199 impl<'a> ToTokens for ImplGenerics<'a> {
1200 fn to_tokens(&self, tokens: &mut TokenStream) {
1201 if self.0.params.is_empty() {
1202 return;
1203 }
1204
1205 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1206
1207 let mut trailing_or_empty = true;
1210 for param in self.0.params.pairs() {
1211 if let GenericParam::Lifetime(_) = **param.value() {
1212 param.to_tokens(tokens);
1213 trailing_or_empty = param.punct().is_some();
1214 }
1215 }
1216 for param in self.0.params.pairs() {
1217 if let GenericParam::Lifetime(_) = **param.value() {
1218 continue;
1219 }
1220 if !trailing_or_empty {
1221 <Token![,]>::default().to_tokens(tokens);
1222 trailing_or_empty = true;
1223 }
1224 match param.value() {
1225 GenericParam::Lifetime(_) => unreachable!(),
1226 GenericParam::Type(param) => {
1227 tokens.append_all(param.attrs.outer());
1229 param.ident.to_tokens(tokens);
1230 if !param.bounds.is_empty() {
1231 TokensOrDefault(¶m.colon_token).to_tokens(tokens);
1232 param.bounds.to_tokens(tokens);
1233 }
1234 }
1235 GenericParam::Const(param) => {
1236 tokens.append_all(param.attrs.outer());
1238 param.const_token.to_tokens(tokens);
1239 param.ident.to_tokens(tokens);
1240 param.colon_token.to_tokens(tokens);
1241 param.ty.to_tokens(tokens);
1242 }
1243 }
1244 param.punct().to_tokens(tokens);
1245 }
1246
1247 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1248 }
1249 }
1250
1251 impl<'a> ToTokens for TypeGenerics<'a> {
1252 fn to_tokens(&self, tokens: &mut TokenStream) {
1253 if self.0.params.is_empty() {
1254 return;
1255 }
1256
1257 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1258
1259 let mut trailing_or_empty = true;
1262 for param in self.0.params.pairs() {
1263 if let GenericParam::Lifetime(def) = *param.value() {
1264 def.lifetime.to_tokens(tokens);
1266 param.punct().to_tokens(tokens);
1267 trailing_or_empty = param.punct().is_some();
1268 }
1269 }
1270 for param in self.0.params.pairs() {
1271 if let GenericParam::Lifetime(_) = **param.value() {
1272 continue;
1273 }
1274 if !trailing_or_empty {
1275 <Token![,]>::default().to_tokens(tokens);
1276 trailing_or_empty = true;
1277 }
1278 match param.value() {
1279 GenericParam::Lifetime(_) => unreachable!(),
1280 GenericParam::Type(param) => {
1281 param.ident.to_tokens(tokens);
1283 }
1284 GenericParam::Const(param) => {
1285 param.ident.to_tokens(tokens);
1287 }
1288 }
1289 param.punct().to_tokens(tokens);
1290 }
1291
1292 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1293 }
1294 }
1295
1296 impl<'a> ToTokens for Turbofish<'a> {
1297 fn to_tokens(&self, tokens: &mut TokenStream) {
1298 if !self.0.params.is_empty() {
1299 <Token![::]>::default().to_tokens(tokens);
1300 TypeGenerics(self.0).to_tokens(tokens);
1301 }
1302 }
1303 }
1304
1305 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1306 impl ToTokens for BoundLifetimes {
1307 fn to_tokens(&self, tokens: &mut TokenStream) {
1308 self.for_token.to_tokens(tokens);
1309 self.lt_token.to_tokens(tokens);
1310 self.lifetimes.to_tokens(tokens);
1311 self.gt_token.to_tokens(tokens);
1312 }
1313 }
1314
1315 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1316 impl ToTokens for LifetimeParam {
1317 fn to_tokens(&self, tokens: &mut TokenStream) {
1318 tokens.append_all(self.attrs.outer());
1319 self.lifetime.to_tokens(tokens);
1320 if !self.bounds.is_empty() {
1321 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1322 self.bounds.to_tokens(tokens);
1323 }
1324 }
1325 }
1326
1327 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1328 impl ToTokens for TypeParam {
1329 fn to_tokens(&self, tokens: &mut TokenStream) {
1330 tokens.append_all(self.attrs.outer());
1331 self.ident.to_tokens(tokens);
1332 if !self.bounds.is_empty() {
1333 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1334 self.bounds.to_tokens(tokens);
1335 }
1336 if let Some(default) = &self.default {
1337 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1338 default.to_tokens(tokens);
1339 }
1340 }
1341 }
1342
1343 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1344 impl ToTokens for TraitBound {
1345 fn to_tokens(&self, tokens: &mut TokenStream) {
1346 let to_tokens = |tokens: &mut TokenStream| {
1347 self.modifier.to_tokens(tokens);
1348 self.lifetimes.to_tokens(tokens);
1349 self.path.to_tokens(tokens);
1350 };
1351 match &self.paren_token {
1352 Some(paren) => paren.surround(tokens, to_tokens),
1353 None => to_tokens(tokens),
1354 }
1355 }
1356 }
1357
1358 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1359 impl ToTokens for TraitBoundModifier {
1360 fn to_tokens(&self, tokens: &mut TokenStream) {
1361 match self {
1362 TraitBoundModifier::None => {}
1363 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1364 }
1365 }
1366 }
1367
1368 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1369 impl ToTokens for ConstParam {
1370 fn to_tokens(&self, tokens: &mut TokenStream) {
1371 tokens.append_all(self.attrs.outer());
1372 self.const_token.to_tokens(tokens);
1373 self.ident.to_tokens(tokens);
1374 self.colon_token.to_tokens(tokens);
1375 self.ty.to_tokens(tokens);
1376 if let Some(default) = &self.default {
1377 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1378 print_const_argument(default, tokens);
1379 }
1380 }
1381 }
1382
1383 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1384 impl ToTokens for WhereClause {
1385 fn to_tokens(&self, tokens: &mut TokenStream) {
1386 if !self.predicates.is_empty() {
1387 self.where_token.to_tokens(tokens);
1388 self.predicates.to_tokens(tokens);
1389 }
1390 }
1391 }
1392
1393 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1394 impl ToTokens for PredicateLifetime {
1395 fn to_tokens(&self, tokens: &mut TokenStream) {
1396 self.lifetime.to_tokens(tokens);
1397 self.colon_token.to_tokens(tokens);
1398 self.bounds.to_tokens(tokens);
1399 }
1400 }
1401
1402 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1403 impl ToTokens for PredicateType {
1404 fn to_tokens(&self, tokens: &mut TokenStream) {
1405 self.lifetimes.to_tokens(tokens);
1406 self.bounded_ty.to_tokens(tokens);
1407 self.colon_token.to_tokens(tokens);
1408 self.bounds.to_tokens(tokens);
1409 }
1410 }
1411
1412 #[cfg(feature = "full")]
1413 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1414 impl ToTokens for PreciseCapture {
1415 fn to_tokens(&self, tokens: &mut TokenStream) {
1416 self.use_token.to_tokens(tokens);
1417 self.lt_token.to_tokens(tokens);
1418
1419 let mut trailing_or_empty = true;
1422 for param in self.params.pairs() {
1423 if let CapturedParam::Lifetime(_) = **param.value() {
1424 param.to_tokens(tokens);
1425 trailing_or_empty = param.punct().is_some();
1426 }
1427 }
1428 for param in self.params.pairs() {
1429 if let CapturedParam::Ident(_) = **param.value() {
1430 if !trailing_or_empty {
1431 <Token![,]>::default().to_tokens(tokens);
1432 trailing_or_empty = true;
1433 }
1434 param.to_tokens(tokens);
1435 }
1436 }
1437
1438 self.gt_token.to_tokens(tokens);
1439 }
1440 }
1441
1442 #[cfg(feature = "full")]
1443 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1444 impl ToTokens for CapturedParam {
1445 fn to_tokens(&self, tokens: &mut TokenStream) {
1446 match self {
1447 CapturedParam::Lifetime(lifetime) => lifetime.to_tokens(tokens),
1448 CapturedParam::Ident(ident) => ident.to_tokens(tokens),
1449 }
1450 }
1451 }
1452
1453 pub(crate) fn print_const_argument(expr: &Expr, tokens: &mut TokenStream) {
1454 match expr {
1455 Expr::Lit(expr) => expr.to_tokens(tokens),
1456
1457 Expr::Path(expr)
1458 if expr.attrs.is_empty()
1459 && expr.qself.is_none()
1460 && expr.path.get_ident().is_some() =>
1461 {
1462 expr.to_tokens(tokens);
1463 }
1464
1465 #[cfg(feature = "full")]
1466 Expr::Block(expr) => expr.to_tokens(tokens),
1467
1468 #[cfg(not(feature = "full"))]
1469 Expr::Verbatim(expr) => expr.to_tokens(tokens),
1470
1471 _ => token::Brace::default().surround(tokens, |tokens| {
1474 #[cfg(feature = "full")]
1475 expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
1476
1477 #[cfg(not(feature = "full"))]
1478 expr.to_tokens(tokens);
1479 }),
1480 }
1481 }
1482}