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<'a> {
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 #[cfg(feature = "full")]
518 use crate::error;
519 use crate::error::{Error, Result};
520 use crate::ext::IdentExt as _;
521 use crate::generics::{
522 BoundLifetimes, ConstParam, GenericParam, Generics, LifetimeParam, PredicateLifetime,
523 PredicateType, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, WhereClause,
524 WherePredicate,
525 };
526 #[cfg(feature = "full")]
527 use crate::generics::{CapturedParam, PreciseCapture};
528 use crate::ident::Ident;
529 use crate::lifetime::Lifetime;
530 use crate::parse::{Parse, ParseStream};
531 use crate::path::{self, ParenthesizedGenericArguments, Path, PathArguments};
532 use crate::punctuated::Punctuated;
533 use crate::token;
534 use crate::ty::Type;
535 use crate::verbatim;
536
537 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
538 impl Parse for Generics {
539 fn parse(input: ParseStream) -> Result<Self> {
540 if !input.peek(Token![<]) {
541 return Ok(Generics::default());
542 }
543
544 let lt_token: Token![<] = input.parse()?;
545
546 let mut params = Punctuated::new();
547 loop {
548 if input.peek(Token![>]) {
549 break;
550 }
551
552 let attrs = input.call(Attribute::parse_outer)?;
553 let lookahead = input.lookahead1();
554 if lookahead.peek(Lifetime) {
555 params.push_value(GenericParam::Lifetime(LifetimeParam {
556 attrs,
557 ..input.parse()?
558 }));
559 } else if lookahead.peek(Ident) {
560 params.push_value(GenericParam::Type(TypeParam {
561 attrs,
562 ..input.parse()?
563 }));
564 } else if lookahead.peek(Token![const]) {
565 params.push_value(GenericParam::Const(ConstParam {
566 attrs,
567 ..input.parse()?
568 }));
569 } else if input.peek(Token![_]) {
570 params.push_value(GenericParam::Type(TypeParam {
571 attrs,
572 ident: input.call(Ident::parse_any)?,
573 colon_token: None,
574 bounds: Punctuated::new(),
575 eq_token: None,
576 default: None,
577 }));
578 } else {
579 return Err(lookahead.error());
580 }
581
582 if input.peek(Token![>]) {
583 break;
584 }
585 let punct = input.parse()?;
586 params.push_punct(punct);
587 }
588
589 let gt_token: Token![>] = input.parse()?;
590
591 Ok(Generics {
592 lt_token: Some(lt_token),
593 params,
594 gt_token: Some(gt_token),
595 where_clause: None,
596 })
597 }
598 }
599
600 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
601 impl Parse for GenericParam {
602 fn parse(input: ParseStream) -> Result<Self> {
603 let attrs = input.call(Attribute::parse_outer)?;
604
605 let lookahead = input.lookahead1();
606 if lookahead.peek(Ident) {
607 Ok(GenericParam::Type(TypeParam {
608 attrs,
609 ..input.parse()?
610 }))
611 } else if lookahead.peek(Lifetime) {
612 Ok(GenericParam::Lifetime(LifetimeParam {
613 attrs,
614 ..input.parse()?
615 }))
616 } else if lookahead.peek(Token![const]) {
617 Ok(GenericParam::Const(ConstParam {
618 attrs,
619 ..input.parse()?
620 }))
621 } else {
622 Err(lookahead.error())
623 }
624 }
625 }
626
627 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
628 impl Parse for LifetimeParam {
629 fn parse(input: ParseStream) -> Result<Self> {
630 let has_colon;
631 Ok(LifetimeParam {
632 attrs: input.call(Attribute::parse_outer)?,
633 lifetime: input.parse()?,
634 colon_token: {
635 if input.peek(Token![:]) {
636 has_colon = true;
637 Some(input.parse()?)
638 } else {
639 has_colon = false;
640 None
641 }
642 },
643 bounds: {
644 let mut bounds = Punctuated::new();
645 if has_colon {
646 loop {
647 if input.peek(Token![,]) || input.peek(Token![>]) {
648 break;
649 }
650 let value = input.parse()?;
651 bounds.push_value(value);
652 if !input.peek(Token![+]) {
653 break;
654 }
655 let punct = input.parse()?;
656 bounds.push_punct(punct);
657 }
658 }
659 bounds
660 },
661 })
662 }
663 }
664
665 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
666 impl Parse for BoundLifetimes {
667 fn parse(input: ParseStream) -> Result<Self> {
668 Ok(BoundLifetimes {
669 for_token: input.parse()?,
670 lt_token: input.parse()?,
671 lifetimes: {
672 let mut lifetimes = Punctuated::new();
673 while !input.peek(Token![>]) {
674 lifetimes.push_value(input.parse()?);
675 if input.peek(Token![>]) {
676 break;
677 }
678 lifetimes.push_punct(input.parse()?);
679 }
680 lifetimes
681 },
682 gt_token: input.parse()?,
683 })
684 }
685 }
686
687 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
688 impl Parse for Option<BoundLifetimes> {
689 fn parse(input: ParseStream) -> Result<Self> {
690 if input.peek(Token![for]) {
691 input.parse().map(Some)
692 } else {
693 Ok(None)
694 }
695 }
696 }
697
698 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
699 impl Parse for TypeParam {
700 fn parse(input: ParseStream) -> Result<Self> {
701 let attrs = input.call(Attribute::parse_outer)?;
702 let ident: Ident = input.parse()?;
703 let colon_token: Option<Token![:]> = input.parse()?;
704
705 let mut bounds = Punctuated::new();
706 if colon_token.is_some() {
707 loop {
708 if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) {
709 break;
710 }
711 bounds.push_value({
712 let allow_precise_capture = false;
713 let allow_const = true;
714 TypeParamBound::parse_single(input, allow_precise_capture, allow_const)?
715 });
716 if !input.peek(Token![+]) {
717 break;
718 }
719 let punct: Token![+] = input.parse()?;
720 bounds.push_punct(punct);
721 }
722 }
723
724 let eq_token: Option<Token![=]> = input.parse()?;
725 let default = if eq_token.is_some() {
726 Some(input.parse::<Type>()?)
727 } else {
728 None
729 };
730
731 Ok(TypeParam {
732 attrs,
733 ident,
734 colon_token,
735 bounds,
736 eq_token,
737 default,
738 })
739 }
740 }
741
742 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
743 impl Parse for TypeParamBound {
744 fn parse(input: ParseStream) -> Result<Self> {
745 let allow_precise_capture = true;
746 let allow_const = true;
747 Self::parse_single(input, allow_precise_capture, allow_const)
748 }
749 }
750
751 impl TypeParamBound {
752 pub(crate) fn parse_single(
753 input: ParseStream,
754 #[cfg_attr(not(feature = "full"), allow(unused_variables))] allow_precise_capture: bool,
755 allow_const: bool,
756 ) -> Result<Self> {
757 if input.peek(Lifetime) {
758 return input.parse().map(TypeParamBound::Lifetime);
759 }
760
761 #[cfg(feature = "full")]
762 {
763 if input.peek(Token![use]) {
764 let precise_capture: PreciseCapture = input.parse()?;
765 return if allow_precise_capture {
766 Ok(TypeParamBound::PreciseCapture(precise_capture))
767 } else {
768 let msg = "`use<...>` precise capturing syntax is not allowed here";
769 Err(error::new2(
770 precise_capture.use_token.span,
771 precise_capture.gt_token.span,
772 msg,
773 ))
774 };
775 }
776 }
777
778 let begin = input.fork();
779
780 let content;
781 let (paren_token, content) = if input.peek(token::Paren) {
782 (Some(parenthesized!(content in input)), &content)
783 } else {
784 (None, input)
785 };
786
787 if let Some(mut bound) = TraitBound::do_parse(content, allow_const)? {
788 bound.paren_token = paren_token;
789 Ok(TypeParamBound::Trait(bound))
790 } else {
791 Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input)))
792 }
793 }
794
795 pub(crate) fn parse_multiple(
796 input: ParseStream,
797 allow_plus: bool,
798 allow_precise_capture: bool,
799 allow_const: bool,
800 ) -> Result<Punctuated<Self, Token![+]>> {
801 let mut bounds = Punctuated::new();
802 loop {
803 let bound = Self::parse_single(input, allow_precise_capture, allow_const)?;
804 bounds.push_value(bound);
805 if !(allow_plus && input.peek(Token![+])) {
806 break;
807 }
808 bounds.push_punct(input.parse()?);
809 if !(input.peek(Ident::peek_any)
810 || input.peek(Token![::])
811 || input.peek(Token![?])
812 || input.peek(Lifetime)
813 || input.peek(token::Paren)
814 || (allow_const && (input.peek(token::Bracket) || input.peek(Token![const]))))
815 {
816 break;
817 }
818 }
819 Ok(bounds)
820 }
821 }
822
823 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
824 impl Parse for TraitBound {
825 fn parse(input: ParseStream) -> Result<Self> {
826 let allow_const = false;
827 Self::do_parse(input, allow_const).map(Option::unwrap)
828 }
829 }
830
831 impl TraitBound {
832 fn do_parse(input: ParseStream, allow_const: bool) -> Result<Option<Self>> {
833 let mut lifetimes: Option<BoundLifetimes> = input.parse()?;
834
835 let is_conditionally_const = cfg!(feature = "full") && input.peek(token::Bracket);
836 let is_unconditionally_const = cfg!(feature = "full") && input.peek(Token![const]);
837 if is_conditionally_const {
838 let conditionally_const;
839 let bracket_token = bracketed!(conditionally_const in input);
840 conditionally_const.parse::<Token![const]>()?;
841 if !allow_const {
842 let msg = "`[const]` is not allowed here";
843 return Err(Error::new(bracket_token.span.join(), msg));
844 }
845 } else if is_unconditionally_const {
846 let const_token: Token![const] = input.parse()?;
847 if !allow_const {
848 let msg = "`const` is not allowed here";
849 return Err(Error::new(const_token.span, msg));
850 }
851 }
852
853 let modifier: TraitBoundModifier = input.parse()?;
854 if lifetimes.is_none() && matches!(modifier, TraitBoundModifier::Maybe(_)) {
855 lifetimes = input.parse()?;
856 }
857
858 let mut path: Path = input.parse()?;
859 if path.segments.last().unwrap().arguments.is_empty()
860 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren))
861 {
862 input.parse::<Option<Token![::]>>()?;
863 let args: ParenthesizedGenericArguments = input.parse()?;
864 let parenthesized = PathArguments::Parenthesized(args);
865 path.segments.last_mut().unwrap().arguments = parenthesized;
866 }
867
868 if lifetimes.is_some() {
869 match modifier {
870 TraitBoundModifier::None => {}
871 TraitBoundModifier::Maybe(maybe) => {
872 let msg = "`for<...>` binder not allowed with `?` trait polarity modifier";
873 return Err(Error::new(maybe.span, msg));
874 }
875 }
876 }
877
878 if is_conditionally_const || is_unconditionally_const {
879 Ok(None)
880 } else {
881 Ok(Some(TraitBound {
882 paren_token: None,
883 modifier,
884 lifetimes,
885 path,
886 }))
887 }
888 }
889 }
890
891 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
892 impl Parse for TraitBoundModifier {
893 fn parse(input: ParseStream) -> Result<Self> {
894 if input.peek(Token![?]) {
895 input.parse().map(TraitBoundModifier::Maybe)
896 } else {
897 Ok(TraitBoundModifier::None)
898 }
899 }
900 }
901
902 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
903 impl Parse for ConstParam {
904 fn parse(input: ParseStream) -> Result<Self> {
905 let mut default = None;
906 Ok(ConstParam {
907 attrs: input.call(Attribute::parse_outer)?,
908 const_token: input.parse()?,
909 ident: input.parse()?,
910 colon_token: input.parse()?,
911 ty: input.parse()?,
912 eq_token: {
913 if input.peek(Token![=]) {
914 let eq_token = input.parse()?;
915 default = Some(path::parsing::const_argument(input)?);
916 Some(eq_token)
917 } else {
918 None
919 }
920 },
921 default,
922 })
923 }
924 }
925
926 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
927 impl Parse for WhereClause {
928 fn parse(input: ParseStream) -> Result<Self> {
929 let where_token: Token![where] = input.parse()?;
930
931 if choose_generics_over_qpath(input) {
932 return Err(input
933 .error("generic parameters on `where` clauses are reserved for future use"));
934 }
935
936 Ok(WhereClause {
937 where_token,
938 predicates: {
939 let mut predicates = Punctuated::new();
940 loop {
941 if input.is_empty()
942 || input.peek(token::Brace)
943 || input.peek(Token![,])
944 || input.peek(Token![;])
945 || input.peek(Token![:]) && !input.peek(Token![::])
946 || input.peek(Token![=])
947 {
948 break;
949 }
950 let value = input.parse()?;
951 predicates.push_value(value);
952 if !input.peek(Token![,]) {
953 break;
954 }
955 let punct = input.parse()?;
956 predicates.push_punct(punct);
957 }
958 predicates
959 },
960 })
961 }
962 }
963
964 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
965 impl Parse for Option<WhereClause> {
966 fn parse(input: ParseStream) -> Result<Self> {
967 if input.peek(Token![where]) {
968 input.parse().map(Some)
969 } else {
970 Ok(None)
971 }
972 }
973 }
974
975 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
976 impl Parse for WherePredicate {
977 fn parse(input: ParseStream) -> Result<Self> {
978 if input.peek(Lifetime) && input.peek2(Token![:]) {
979 Ok(WherePredicate::Lifetime(PredicateLifetime {
980 lifetime: 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![:])
990 || input.peek(Token![=])
991 {
992 break;
993 }
994 let value = input.parse()?;
995 bounds.push_value(value);
996 if !input.peek(Token![+]) {
997 break;
998 }
999 let punct = input.parse()?;
1000 bounds.push_punct(punct);
1001 }
1002 bounds
1003 },
1004 }))
1005 } else {
1006 Ok(WherePredicate::Type(PredicateType {
1007 lifetimes: input.parse()?,
1008 bounded_ty: input.parse()?,
1009 colon_token: input.parse()?,
1010 bounds: {
1011 let mut bounds = Punctuated::new();
1012 loop {
1013 if input.is_empty()
1014 || input.peek(token::Brace)
1015 || input.peek(Token![,])
1016 || input.peek(Token![;])
1017 || input.peek(Token![:]) && !input.peek(Token![::])
1018 || input.peek(Token![=])
1019 {
1020 break;
1021 }
1022 bounds.push_value({
1023 let allow_precise_capture = false;
1024 let allow_const = true;
1025 TypeParamBound::parse_single(
1026 input,
1027 allow_precise_capture,
1028 allow_const,
1029 )?
1030 });
1031 if !input.peek(Token![+]) {
1032 break;
1033 }
1034 let punct = input.parse()?;
1035 bounds.push_punct(punct);
1036 }
1037 bounds
1038 },
1039 }))
1040 }
1041 }
1042 }
1043
1044 #[cfg(feature = "full")]
1045 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1046 impl Parse for PreciseCapture {
1047 fn parse(input: ParseStream) -> Result<Self> {
1048 let use_token: Token![use] = input.parse()?;
1049 let lt_token: Token![<] = input.parse()?;
1050 let mut params = Punctuated::new();
1051 loop {
1052 let lookahead = input.lookahead1();
1053 params.push_value(
1054 if lookahead.peek(Lifetime) || lookahead.peek(Ident) || input.peek(Token![Self])
1055 {
1056 input.parse::<CapturedParam>()?
1057 } else if lookahead.peek(Token![>]) {
1058 break;
1059 } else {
1060 return Err(lookahead.error());
1061 },
1062 );
1063 let lookahead = input.lookahead1();
1064 params.push_punct(if lookahead.peek(Token![,]) {
1065 input.parse::<Token![,]>()?
1066 } else if lookahead.peek(Token![>]) {
1067 break;
1068 } else {
1069 return Err(lookahead.error());
1070 });
1071 }
1072 let gt_token: Token![>] = input.parse()?;
1073 Ok(PreciseCapture {
1074 use_token,
1075 lt_token,
1076 params,
1077 gt_token,
1078 })
1079 }
1080 }
1081
1082 #[cfg(feature = "full")]
1083 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
1084 impl Parse for CapturedParam {
1085 fn parse(input: ParseStream) -> Result<Self> {
1086 let lookahead = input.lookahead1();
1087 if lookahead.peek(Lifetime) {
1088 input.parse().map(CapturedParam::Lifetime)
1089 } else if lookahead.peek(Ident) || input.peek(Token![Self]) {
1090 input.call(Ident::parse_any).map(CapturedParam::Ident)
1091 } else {
1092 Err(lookahead.error())
1093 }
1094 }
1095 }
1096
1097 pub(crate) fn choose_generics_over_qpath(input: ParseStream) -> bool {
1098 input.peek(Token![<])
1121 && (input.peek2(Token![>])
1122 || input.peek2(Token![#])
1123 || (input.peek2(Lifetime) || input.peek2(Ident))
1124 && (input.peek3(Token![>])
1125 || input.peek3(Token![,])
1126 || input.peek3(Token![:]) && !input.peek3(Token![::])
1127 || input.peek3(Token![=]))
1128 || input.peek2(Token![const]))
1129 }
1130
1131 #[cfg(feature = "full")]
1132 pub(crate) fn choose_generics_over_qpath_after_keyword(input: ParseStream) -> bool {
1133 let input = input.fork();
1134 input.call(Ident::parse_any).unwrap(); choose_generics_over_qpath(&input)
1136 }
1137}
1138
1139#[cfg(feature = "printing")]
1140pub(crate) mod printing {
1141 use crate::attr::FilterAttrs;
1142 #[cfg(feature = "full")]
1143 use crate::expr;
1144 use crate::expr::Expr;
1145 #[cfg(feature = "full")]
1146 use crate::fixup::FixupContext;
1147 use crate::generics::{
1148 BoundLifetimes, ConstParam, GenericParam, Generics, ImplGenerics, LifetimeParam,
1149 PredicateLifetime, PredicateType, TraitBound, TraitBoundModifier, Turbofish, TypeGenerics,
1150 TypeParam, WhereClause,
1151 };
1152 #[cfg(feature = "full")]
1153 use crate::generics::{CapturedParam, PreciseCapture};
1154 use crate::print::TokensOrDefault;
1155 use crate::token;
1156 use proc_macro2::TokenStream;
1157 use quote::{ToTokens, TokenStreamExt};
1158
1159 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1160 impl ToTokens for Generics {
1161 fn to_tokens(&self, tokens: &mut TokenStream) {
1162 if self.params.is_empty() {
1163 return;
1164 }
1165
1166 TokensOrDefault(&self.lt_token).to_tokens(tokens);
1167
1168 let mut trailing_or_empty = true;
1171 for param in self.params.pairs() {
1172 if let GenericParam::Lifetime(_) = **param.value() {
1173 param.to_tokens(tokens);
1174 trailing_or_empty = param.punct().is_some();
1175 }
1176 }
1177 for param in self.params.pairs() {
1178 match param.value() {
1179 GenericParam::Type(_) | GenericParam::Const(_) => {
1180 if !trailing_or_empty {
1181 <Token![,]>::default().to_tokens(tokens);
1182 trailing_or_empty = true;
1183 }
1184 param.to_tokens(tokens);
1185 }
1186 GenericParam::Lifetime(_) => {}
1187 }
1188 }
1189
1190 TokensOrDefault(&self.gt_token).to_tokens(tokens);
1191 }
1192 }
1193
1194 impl<'a> ToTokens for ImplGenerics<'a> {
1195 fn to_tokens(&self, tokens: &mut TokenStream) {
1196 if self.0.params.is_empty() {
1197 return;
1198 }
1199
1200 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1201
1202 let mut trailing_or_empty = true;
1205 for param in self.0.params.pairs() {
1206 if let GenericParam::Lifetime(_) = **param.value() {
1207 param.to_tokens(tokens);
1208 trailing_or_empty = param.punct().is_some();
1209 }
1210 }
1211 for param in self.0.params.pairs() {
1212 if let GenericParam::Lifetime(_) = **param.value() {
1213 continue;
1214 }
1215 if !trailing_or_empty {
1216 <Token![,]>::default().to_tokens(tokens);
1217 trailing_or_empty = true;
1218 }
1219 match param.value() {
1220 GenericParam::Lifetime(_) => unreachable!(),
1221 GenericParam::Type(param) => {
1222 tokens.append_all(param.attrs.outer());
1224 param.ident.to_tokens(tokens);
1225 if !param.bounds.is_empty() {
1226 TokensOrDefault(¶m.colon_token).to_tokens(tokens);
1227 param.bounds.to_tokens(tokens);
1228 }
1229 }
1230 GenericParam::Const(param) => {
1231 tokens.append_all(param.attrs.outer());
1233 param.const_token.to_tokens(tokens);
1234 param.ident.to_tokens(tokens);
1235 param.colon_token.to_tokens(tokens);
1236 param.ty.to_tokens(tokens);
1237 }
1238 }
1239 param.punct().to_tokens(tokens);
1240 }
1241
1242 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1243 }
1244 }
1245
1246 impl<'a> ToTokens for TypeGenerics<'a> {
1247 fn to_tokens(&self, tokens: &mut TokenStream) {
1248 if self.0.params.is_empty() {
1249 return;
1250 }
1251
1252 TokensOrDefault(&self.0.lt_token).to_tokens(tokens);
1253
1254 let mut trailing_or_empty = true;
1257 for param in self.0.params.pairs() {
1258 if let GenericParam::Lifetime(def) = *param.value() {
1259 def.lifetime.to_tokens(tokens);
1261 param.punct().to_tokens(tokens);
1262 trailing_or_empty = param.punct().is_some();
1263 }
1264 }
1265 for param in self.0.params.pairs() {
1266 if let GenericParam::Lifetime(_) = **param.value() {
1267 continue;
1268 }
1269 if !trailing_or_empty {
1270 <Token![,]>::default().to_tokens(tokens);
1271 trailing_or_empty = true;
1272 }
1273 match param.value() {
1274 GenericParam::Lifetime(_) => unreachable!(),
1275 GenericParam::Type(param) => {
1276 param.ident.to_tokens(tokens);
1278 }
1279 GenericParam::Const(param) => {
1280 param.ident.to_tokens(tokens);
1282 }
1283 }
1284 param.punct().to_tokens(tokens);
1285 }
1286
1287 TokensOrDefault(&self.0.gt_token).to_tokens(tokens);
1288 }
1289 }
1290
1291 impl<'a> ToTokens for Turbofish<'a> {
1292 fn to_tokens(&self, tokens: &mut TokenStream) {
1293 if !self.0.params.is_empty() {
1294 <Token![::]>::default().to_tokens(tokens);
1295 TypeGenerics(self.0).to_tokens(tokens);
1296 }
1297 }
1298 }
1299
1300 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1301 impl ToTokens for BoundLifetimes {
1302 fn to_tokens(&self, tokens: &mut TokenStream) {
1303 self.for_token.to_tokens(tokens);
1304 self.lt_token.to_tokens(tokens);
1305 self.lifetimes.to_tokens(tokens);
1306 self.gt_token.to_tokens(tokens);
1307 }
1308 }
1309
1310 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1311 impl ToTokens for LifetimeParam {
1312 fn to_tokens(&self, tokens: &mut TokenStream) {
1313 tokens.append_all(self.attrs.outer());
1314 self.lifetime.to_tokens(tokens);
1315 if !self.bounds.is_empty() {
1316 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1317 self.bounds.to_tokens(tokens);
1318 }
1319 }
1320 }
1321
1322 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1323 impl ToTokens for TypeParam {
1324 fn to_tokens(&self, tokens: &mut TokenStream) {
1325 tokens.append_all(self.attrs.outer());
1326 self.ident.to_tokens(tokens);
1327 if !self.bounds.is_empty() {
1328 TokensOrDefault(&self.colon_token).to_tokens(tokens);
1329 self.bounds.to_tokens(tokens);
1330 }
1331 if let Some(default) = &self.default {
1332 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1333 default.to_tokens(tokens);
1334 }
1335 }
1336 }
1337
1338 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1339 impl ToTokens for TraitBound {
1340 fn to_tokens(&self, tokens: &mut TokenStream) {
1341 let to_tokens = |tokens: &mut TokenStream| {
1342 self.modifier.to_tokens(tokens);
1343 self.lifetimes.to_tokens(tokens);
1344 self.path.to_tokens(tokens);
1345 };
1346 match &self.paren_token {
1347 Some(paren) => paren.surround(tokens, to_tokens),
1348 None => to_tokens(tokens),
1349 }
1350 }
1351 }
1352
1353 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1354 impl ToTokens for TraitBoundModifier {
1355 fn to_tokens(&self, tokens: &mut TokenStream) {
1356 match self {
1357 TraitBoundModifier::None => {}
1358 TraitBoundModifier::Maybe(t) => t.to_tokens(tokens),
1359 }
1360 }
1361 }
1362
1363 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1364 impl ToTokens for ConstParam {
1365 fn to_tokens(&self, tokens: &mut TokenStream) {
1366 tokens.append_all(self.attrs.outer());
1367 self.const_token.to_tokens(tokens);
1368 self.ident.to_tokens(tokens);
1369 self.colon_token.to_tokens(tokens);
1370 self.ty.to_tokens(tokens);
1371 if let Some(default) = &self.default {
1372 TokensOrDefault(&self.eq_token).to_tokens(tokens);
1373 print_const_argument(default, tokens);
1374 }
1375 }
1376 }
1377
1378 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1379 impl ToTokens for WhereClause {
1380 fn to_tokens(&self, tokens: &mut TokenStream) {
1381 if !self.predicates.is_empty() {
1382 self.where_token.to_tokens(tokens);
1383 self.predicates.to_tokens(tokens);
1384 }
1385 }
1386 }
1387
1388 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1389 impl ToTokens for PredicateLifetime {
1390 fn to_tokens(&self, tokens: &mut TokenStream) {
1391 self.lifetime.to_tokens(tokens);
1392 self.colon_token.to_tokens(tokens);
1393 self.bounds.to_tokens(tokens);
1394 }
1395 }
1396
1397 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1398 impl ToTokens for PredicateType {
1399 fn to_tokens(&self, tokens: &mut TokenStream) {
1400 self.lifetimes.to_tokens(tokens);
1401 self.bounded_ty.to_tokens(tokens);
1402 self.colon_token.to_tokens(tokens);
1403 self.bounds.to_tokens(tokens);
1404 }
1405 }
1406
1407 #[cfg(feature = "full")]
1408 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1409 impl ToTokens for PreciseCapture {
1410 fn to_tokens(&self, tokens: &mut TokenStream) {
1411 self.use_token.to_tokens(tokens);
1412 self.lt_token.to_tokens(tokens);
1413
1414 let mut trailing_or_empty = true;
1417 for param in self.params.pairs() {
1418 if let CapturedParam::Lifetime(_) = **param.value() {
1419 param.to_tokens(tokens);
1420 trailing_or_empty = param.punct().is_some();
1421 }
1422 }
1423 for param in self.params.pairs() {
1424 if let CapturedParam::Ident(_) = **param.value() {
1425 if !trailing_or_empty {
1426 <Token![,]>::default().to_tokens(tokens);
1427 trailing_or_empty = true;
1428 }
1429 param.to_tokens(tokens);
1430 }
1431 }
1432
1433 self.gt_token.to_tokens(tokens);
1434 }
1435 }
1436
1437 #[cfg(feature = "full")]
1438 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1439 impl ToTokens for CapturedParam {
1440 fn to_tokens(&self, tokens: &mut TokenStream) {
1441 match self {
1442 CapturedParam::Lifetime(lifetime) => lifetime.to_tokens(tokens),
1443 CapturedParam::Ident(ident) => ident.to_tokens(tokens),
1444 }
1445 }
1446 }
1447
1448 pub(crate) fn print_const_argument(expr: &Expr, tokens: &mut TokenStream) {
1449 match expr {
1450 Expr::Lit(expr) => expr.to_tokens(tokens),
1451
1452 Expr::Path(expr)
1453 if expr.attrs.is_empty()
1454 && expr.qself.is_none()
1455 && expr.path.get_ident().is_some() =>
1456 {
1457 expr.to_tokens(tokens);
1458 }
1459
1460 #[cfg(feature = "full")]
1461 Expr::Block(expr) => expr.to_tokens(tokens),
1462
1463 #[cfg(not(feature = "full"))]
1464 Expr::Verbatim(expr) => expr.to_tokens(tokens),
1465
1466 _ => token::Brace::default().surround(tokens, |tokens| {
1469 #[cfg(feature = "full")]
1470 expr::printing::print_expr(expr, tokens, FixupContext::new_stmt());
1471
1472 #[cfg(not(feature = "full"))]
1473 expr.to_tokens(tokens);
1474 }),
1475 }
1476 }
1477}