2 use crate::punctuated
::{Iter, IterMut, Punctuated}
;
3 #[cfg(all(feature = "printing", feature = "extra-traits"))]
4 use std
::fmt
::{self, Debug}
;
5 #[cfg(all(feature = "printing", feature = "extra-traits"))]
6 use std
::hash
::{Hash, Hasher}
;
9 /// Lifetimes and type parameters attached to a declaration of a function,
12 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
14 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
16 pub lt_token
: Option
<Token
![<]>,
17 pub params
: Punctuated
<GenericParam
, Token
![,]>,
18 pub gt_token
: Option
<Token
![>]>,
19 pub where_clause
: Option
<WhereClause
>,
23 ast_enum_of_structs
! {
24 /// A generic type parameter, lifetime, or const generic: `T: Into<String>`,
25 /// `'a: 'b`, `const LEN: usize`.
27 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
30 /// # Syntax tree enum
32 /// This type is a [syntax tree enum].
34 /// [syntax tree enum]: Expr#syntax-tree-enums
35 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
36 pub enum GenericParam
{
37 /// A generic type parameter: `T: Into<String>`.
40 /// A lifetime definition: `'a: 'b + 'c + 'd`.
41 Lifetime(LifetimeDef
),
43 /// A const generic parameter: `const LENGTH: usize`.
49 /// A generic type parameter: `T: Into<String>`.
51 /// *This type is available only if Syn is built with the `"derive"` or
52 /// `"full"` feature.*
53 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
54 pub struct TypeParam
{
55 pub attrs
: Vec
<Attribute
>,
57 pub colon_token
: Option
<Token
![:]>,
58 pub bounds
: Punctuated
<TypeParamBound
, Token
![+]>,
59 pub eq_token
: Option
<Token
![=]>,
60 pub default: Option
<Type
>,
65 /// A lifetime definition: `'a: 'b + 'c + 'd`.
67 /// *This type is available only if Syn is built with the `"derive"` or
68 /// `"full"` feature.*
69 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
70 pub struct LifetimeDef
{
71 pub attrs
: Vec
<Attribute
>,
72 pub lifetime
: Lifetime
,
73 pub colon_token
: Option
<Token
![:]>,
74 pub bounds
: Punctuated
<Lifetime
, Token
![+]>,
79 /// A const generic parameter: `const LENGTH: usize`.
81 /// *This type is available only if Syn is built with the `"derive"` or
82 /// `"full"` feature.*
83 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
84 pub struct ConstParam
{
85 pub attrs
: Vec
<Attribute
>,
86 pub const_token
: Token
![const],
88 pub colon_token
: Token
![:],
90 pub eq_token
: Option
<Token
![=]>,
91 pub default: Option
<Expr
>,
95 impl Default
for Generics
{
96 fn default() -> Self {
99 params
: Punctuated
::new(),
109 /// style="padding-right:0;">Iterator<Item = &</code><a
110 /// href="struct.TypeParam.html"><code
111 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
112 /// style="padding-left:0;">></code>
113 /// over the type parameters in `self.params`.
114 pub fn type_params(&self) -> TypeParams
{
115 TypeParams(self.params
.iter())
120 /// style="padding-right:0;">Iterator<Item = &mut </code><a
121 /// href="struct.TypeParam.html"><code
122 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
123 /// style="padding-left:0;">></code>
124 /// over the type parameters in `self.params`.
125 pub fn type_params_mut(&mut self) -> TypeParamsMut
{
126 TypeParamsMut(self.params
.iter_mut())
131 /// style="padding-right:0;">Iterator<Item = &</code><a
132 /// href="struct.LifetimeDef.html"><code
133 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
134 /// style="padding-left:0;">></code>
135 /// over the lifetime parameters in `self.params`.
136 pub fn lifetimes(&self) -> Lifetimes
{
137 Lifetimes(self.params
.iter())
142 /// style="padding-right:0;">Iterator<Item = &mut </code><a
143 /// href="struct.LifetimeDef.html"><code
144 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
145 /// style="padding-left:0;">></code>
146 /// over the lifetime parameters in `self.params`.
147 pub fn lifetimes_mut(&mut self) -> LifetimesMut
{
148 LifetimesMut(self.params
.iter_mut())
153 /// style="padding-right:0;">Iterator<Item = &</code><a
154 /// href="struct.ConstParam.html"><code
155 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
156 /// style="padding-left:0;">></code>
157 /// over the constant parameters in `self.params`.
158 pub fn const_params(&self) -> ConstParams
{
159 ConstParams(self.params
.iter())
164 /// style="padding-right:0;">Iterator<Item = &mut </code><a
165 /// href="struct.ConstParam.html"><code
166 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
167 /// style="padding-left:0;">></code>
168 /// over the constant parameters in `self.params`.
169 pub fn const_params_mut(&mut self) -> ConstParamsMut
{
170 ConstParamsMut(self.params
.iter_mut())
173 /// Initializes an empty `where`-clause if there is not one present already.
174 pub fn make_where_clause(&mut self) -> &mut WhereClause
{
175 self.where_clause
.get_or_insert_with(|| WhereClause
{
176 where_token
: <Token
![where]>::default(),
177 predicates
: Punctuated
::new(),
182 pub struct TypeParams
<'a
>(Iter
<'a
, GenericParam
>);
184 impl<'a
> Iterator
for TypeParams
<'a
> {
185 type Item
= &'a TypeParam
;
187 fn next(&mut self) -> Option
<Self::Item
> {
188 let next
= match self.0.next() {
192 if let GenericParam
::Type(type_param
) = next
{
200 pub struct TypeParamsMut
<'a
>(IterMut
<'a
, GenericParam
>);
202 impl<'a
> Iterator
for TypeParamsMut
<'a
> {
203 type Item
= &'a
mut TypeParam
;
205 fn next(&mut self) -> Option
<Self::Item
> {
206 let next
= match self.0.next() {
210 if let GenericParam
::Type(type_param
) = next
{
218 pub struct Lifetimes
<'a
>(Iter
<'a
, GenericParam
>);
220 impl<'a
> Iterator
for Lifetimes
<'a
> {
221 type Item
= &'a LifetimeDef
;
223 fn next(&mut self) -> Option
<Self::Item
> {
224 let next
= match self.0.next() {
228 if let GenericParam
::Lifetime(lifetime
) = next
{
236 pub struct LifetimesMut
<'a
>(IterMut
<'a
, GenericParam
>);
238 impl<'a
> Iterator
for LifetimesMut
<'a
> {
239 type Item
= &'a
mut LifetimeDef
;
241 fn next(&mut self) -> Option
<Self::Item
> {
242 let next
= match self.0.next() {
246 if let GenericParam
::Lifetime(lifetime
) = next
{
254 pub struct ConstParams
<'a
>(Iter
<'a
, GenericParam
>);
256 impl<'a
> Iterator
for ConstParams
<'a
> {
257 type Item
= &'a ConstParam
;
259 fn next(&mut self) -> Option
<Self::Item
> {
260 let next
= match self.0.next() {
264 if let GenericParam
::Const(const_param
) = next
{
272 pub struct ConstParamsMut
<'a
>(IterMut
<'a
, GenericParam
>);
274 impl<'a
> Iterator
for ConstParamsMut
<'a
> {
275 type Item
= &'a
mut ConstParam
;
277 fn next(&mut self) -> Option
<Self::Item
> {
278 let next
= match self.0.next() {
282 if let GenericParam
::Const(const_param
) = next
{
290 /// Returned by `Generics::split_for_impl`.
292 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
293 /// feature and the `"printing"` feature.*
294 #[cfg(feature = "printing")]
297 doc(cfg(all(any(feature
= "full", feature
= "derive"), feature
= "printing")))
299 pub struct ImplGenerics
<'a
>(&'a Generics
);
301 /// Returned by `Generics::split_for_impl`.
303 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
304 /// feature and the `"printing"` feature.*
305 #[cfg(feature = "printing")]
308 doc(cfg(all(any(feature
= "full", feature
= "derive"), feature
= "printing")))
310 pub struct TypeGenerics
<'a
>(&'a Generics
);
312 /// Returned by `TypeGenerics::as_turbofish`.
314 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
315 /// feature and the `"printing"` feature.*
316 #[cfg(feature = "printing")]
319 doc(cfg(all(any(feature
= "full", feature
= "derive"), feature
= "printing")))
321 pub struct Turbofish
<'a
>(&'a Generics
);
323 #[cfg(feature = "printing")]
325 /// Split a type's generics into the pieces required for impl'ing a trait
329 /// # use proc_macro2::{Span, Ident};
330 /// # use quote::quote;
332 /// # let generics: syn::Generics = Default::default();
333 /// # let name = Ident::new("MyType", Span::call_site());
335 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
337 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
344 /// *This method is available only if Syn is built with the `"derive"` or
345 /// `"full"` feature and the `"printing"` feature.*
348 doc(cfg(all(any(feature
= "full", feature
= "derive"), feature
= "printing")))
350 pub fn split_for_impl(&self) -> (ImplGenerics
, TypeGenerics
, Option
<&WhereClause
>) {
354 self.where_clause
.as_ref(),
359 #[cfg(feature = "printing")]
360 macro_rules
! generics_wrapper_impls
{
362 #[cfg(feature = "clone-impls")]
363 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
364 impl<'a
> Clone
for $ty
<'a
> {
365 fn clone(&self) -> Self {
370 #[cfg(feature = "extra-traits")]
371 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
372 impl<'a
> Debug
for $ty
<'a
> {
373 fn fmt(&self, formatter
: &mut fmt
::Formatter
) -> fmt
::Result
{
375 .debug_tuple(stringify
!($ty
))
381 #[cfg(feature = "extra-traits")]
382 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
383 impl<'a
> Eq
for $ty
<'a
> {}
385 #[cfg(feature = "extra-traits")]
386 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
387 impl<'a
> PartialEq
for $ty
<'a
> {
388 fn eq(&self, other
: &Self) -> bool
{
393 #[cfg(feature = "extra-traits")]
394 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
395 impl<'a
> Hash
for $ty
<'a
> {
396 fn hash
<H
: Hasher
>(&self, state
: &mut H
) {
403 #[cfg(feature = "printing")]
404 generics_wrapper_impls
!(ImplGenerics
);
405 #[cfg(feature = "printing")]
406 generics_wrapper_impls
!(TypeGenerics
);
407 #[cfg(feature = "printing")]
408 generics_wrapper_impls
!(Turbofish
);
410 #[cfg(feature = "printing")]
411 impl<'a
> TypeGenerics
<'a
> {
412 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
414 /// *This method is available only if Syn is built with the `"derive"` or
415 /// `"full"` feature and the `"printing"` feature.*
416 pub fn as_turbofish(&self) -> Turbofish
{
422 /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
424 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
426 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
427 pub struct BoundLifetimes
{
428 pub for_token
: Token
![for],
429 pub lt_token
: Token
![<],
430 pub lifetimes
: Punctuated
<LifetimeDef
, Token
![,]>,
431 pub gt_token
: Token
![>],
435 impl Default
for BoundLifetimes
{
436 fn default() -> Self {
438 for_token
: Default
::default(),
439 lt_token
: Default
::default(),
440 lifetimes
: Punctuated
::new(),
441 gt_token
: Default
::default(),
447 pub fn new(lifetime
: Lifetime
) -> Self {
452 bounds
: Punctuated
::new(),
457 impl From
<Ident
> for TypeParam
{
458 fn from(ident
: Ident
) -> Self {
463 bounds
: Punctuated
::new(),
470 ast_enum_of_structs
! {
471 /// A trait or lifetime used as a bound on a type parameter.
473 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
475 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
476 pub enum TypeParamBound
{
483 /// A trait used as a bound on a type parameter.
485 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
487 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
488 pub struct TraitBound
{
489 pub paren_token
: Option
<token
::Paren
>,
490 pub modifier
: TraitBoundModifier
,
491 /// The `for<'a>` in `for<'a> Foo<&'a T>`
492 pub lifetimes
: Option
<BoundLifetimes
>,
493 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
499 /// A modifier on a trait bound, currently only used for the `?` in
502 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
504 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
505 pub enum TraitBoundModifier
{
512 /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
515 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
517 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
518 pub struct WhereClause
{
519 pub where_token
: Token
![where],
520 pub predicates
: Punctuated
<WherePredicate
, Token
![,]>,
524 ast_enum_of_structs
! {
525 /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
527 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
530 /// # Syntax tree enum
532 /// This type is a [syntax tree enum].
534 /// [syntax tree enum]: Expr#syntax-tree-enums
535 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
536 pub enum WherePredicate
{
537 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
540 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
541 Lifetime(PredicateLifetime
),
543 /// An equality predicate in a `where` clause (unsupported).
549 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
551 /// *This type is available only if Syn is built with the `"derive"` or
552 /// `"full"` feature.*
553 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
554 pub struct PredicateType
{
555 /// Any lifetimes from a `for` binding
556 pub lifetimes
: Option
<BoundLifetimes
>,
557 /// The type being bounded
558 pub bounded_ty
: Type
,
559 pub colon_token
: Token
![:],
560 /// Trait and lifetime bounds (`Clone+Send+'static`)
561 pub bounds
: Punctuated
<TypeParamBound
, Token
![+]>,
566 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
568 /// *This type is available only if Syn is built with the `"derive"` or
569 /// `"full"` feature.*
570 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
571 pub struct PredicateLifetime
{
572 pub lifetime
: Lifetime
,
573 pub colon_token
: Token
![:],
574 pub bounds
: Punctuated
<Lifetime
, Token
![+]>,
579 /// An equality predicate in a `where` clause (unsupported).
581 /// *This type is available only if Syn is built with the `"derive"` or
582 /// `"full"` feature.*
583 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
584 pub struct PredicateEq
{
586 pub eq_token
: Token
![=],
591 #[cfg(feature = "parsing")]
594 use crate::ext
::IdentExt
;
595 use crate::parse
::{Parse, ParseStream, Result}
;
597 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
598 impl Parse
for Generics
{
599 fn parse(input
: ParseStream
) -> Result
<Self> {
600 if !input
.peek(Token
![<]) {
601 return Ok(Generics
::default());
604 let lt_token
: Token
![<] = input
.parse()?
;
606 let mut params
= Punctuated
::new();
608 if input
.peek(Token
![>]) {
612 let attrs
= input
.call(Attribute
::parse_outer
)?
;
613 let lookahead
= input
.lookahead1();
614 if lookahead
.peek(Lifetime
) {
615 params
.push_value(GenericParam
::Lifetime(LifetimeDef
{
619 } else if lookahead
.peek(Ident
) {
620 params
.push_value(GenericParam
::Type(TypeParam
{
624 } else if lookahead
.peek(Token
![const]) {
625 params
.push_value(GenericParam
::Const(ConstParam
{
629 } else if input
.peek(Token
![_
]) {
630 params
.push_value(GenericParam
::Type(TypeParam
{
632 ident
: input
.call(Ident
::parse_any
)?
,
634 bounds
: Punctuated
::new(),
639 return Err(lookahead
.error());
642 if input
.peek(Token
![>]) {
645 let punct
= input
.parse()?
;
646 params
.push_punct(punct
);
649 let gt_token
: Token
![>] = input
.parse()?
;
652 lt_token
: Some(lt_token
),
654 gt_token
: Some(gt_token
),
660 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
661 impl Parse
for GenericParam
{
662 fn parse(input
: ParseStream
) -> Result
<Self> {
663 let attrs
= input
.call(Attribute
::parse_outer
)?
;
665 let lookahead
= input
.lookahead1();
666 if lookahead
.peek(Ident
) {
667 Ok(GenericParam
::Type(TypeParam
{
671 } else if lookahead
.peek(Lifetime
) {
672 Ok(GenericParam
::Lifetime(LifetimeDef
{
676 } else if lookahead
.peek(Token
![const]) {
677 Ok(GenericParam
::Const(ConstParam
{
682 Err(lookahead
.error())
687 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
688 impl Parse
for LifetimeDef
{
689 fn parse(input
: ParseStream
) -> Result
<Self> {
692 attrs
: input
.call(Attribute
::parse_outer
)?
,
693 lifetime
: input
.parse()?
,
695 if input
.peek(Token
![:]) {
704 let mut bounds
= Punctuated
::new();
707 if input
.peek(Token
![,]) || input
.peek(Token
![>]) {
710 let value
= input
.parse()?
;
711 bounds
.push_value(value
);
712 if !input
.peek(Token
![+]) {
715 let punct
= input
.parse()?
;
716 bounds
.push_punct(punct
);
725 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
726 impl Parse
for BoundLifetimes
{
727 fn parse(input
: ParseStream
) -> Result
<Self> {
729 for_token
: input
.parse()?
,
730 lt_token
: input
.parse()?
,
732 let mut lifetimes
= Punctuated
::new();
733 while !input
.peek(Token
![>]) {
734 lifetimes
.push_value(input
.parse()?
);
735 if input
.peek(Token
![>]) {
738 lifetimes
.push_punct(input
.parse()?
);
742 gt_token
: input
.parse()?
,
747 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
748 impl Parse
for Option
<BoundLifetimes
> {
749 fn parse(input
: ParseStream
) -> Result
<Self> {
750 if input
.peek(Token
![for]) {
751 input
.parse().map(Some
)
758 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
759 impl Parse
for TypeParam
{
760 fn parse(input
: ParseStream
) -> Result
<Self> {
761 let attrs
= input
.call(Attribute
::parse_outer
)?
;
762 let ident
: Ident
= input
.parse()?
;
763 let colon_token
: Option
<Token
![:]> = input
.parse()?
;
765 let begin_bound
= input
.fork();
766 let mut is_maybe_const
= false;
767 let mut bounds
= Punctuated
::new();
768 if colon_token
.is_some() {
770 if input
.peek(Token
![,]) || input
.peek(Token
![>]) || input
.peek(Token
![=]) {
773 if input
.peek(Token
![~]) && input
.peek2(Token
![const]) {
774 input
.parse
::<Token
![~]>()?
;
775 input
.parse
::<Token
![const]>()?
;
776 is_maybe_const
= true;
778 let value
: TypeParamBound
= input
.parse()?
;
779 bounds
.push_value(value
);
780 if !input
.peek(Token
![+]) {
783 let punct
: Token
![+] = input
.parse()?
;
784 bounds
.push_punct(punct
);
788 let mut eq_token
: Option
<Token
![=]> = input
.parse()?
;
789 let mut default = if eq_token
.is_some() {
790 Some(input
.parse
::<Type
>()?
)
798 default = Some(Type
::Verbatim(verbatim
::between(begin_bound
, input
)));
812 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
813 impl Parse
for TypeParamBound
{
814 fn parse(input
: ParseStream
) -> Result
<Self> {
815 if input
.peek(Lifetime
) {
816 return input
.parse().map(TypeParamBound
::Lifetime
);
819 if input
.peek(token
::Paren
) {
821 let paren_token
= parenthesized
!(content
in input
);
822 let mut bound
: TraitBound
= content
.parse()?
;
823 bound
.paren_token
= Some(paren_token
);
824 return Ok(TypeParamBound
::Trait(bound
));
827 input
.parse().map(TypeParamBound
::Trait
)
831 impl TypeParamBound
{
832 pub(crate) fn parse_multiple(
835 ) -> Result
<Punctuated
<Self, Token
![+]>> {
836 let mut bounds
= Punctuated
::new();
838 bounds
.push_value(input
.parse()?
);
839 if !(allow_plus
&& input
.peek(Token
![+])) {
842 bounds
.push_punct(input
.parse()?
);
843 if !(input
.peek(Ident
::peek_any
)
844 || input
.peek(Token
![::])
845 || input
.peek(Token
![?
])
846 || input
.peek(Lifetime
)
847 || input
.peek(token
::Paren
))
856 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
857 impl Parse
for TraitBound
{
858 fn parse(input
: ParseStream
) -> Result
<Self> {
859 #[cfg(feature = "full")]
860 let tilde_const
= if input
.peek(Token
![~]) && input
.peek2(Token
![const]) {
861 let tilde_token
= input
.parse
::<Token
![~]>()?
;
862 let const_token
= input
.parse
::<Token
![const]>()?
;
863 Some((tilde_token
, const_token
))
868 let modifier
: TraitBoundModifier
= input
.parse()?
;
869 let lifetimes
: Option
<BoundLifetimes
> = input
.parse()?
;
871 let mut path
: Path
= input
.parse()?
;
872 if path
.segments
.last().unwrap().arguments
.is_empty()
873 && (input
.peek(token
::Paren
) || input
.peek(Token
![::]) && input
.peek3(token
::Paren
))
875 input
.parse
::<Option
<Token
![::]>>()?
;
876 let args
: ParenthesizedGenericArguments
= input
.parse()?
;
877 let parenthesized
= PathArguments
::Parenthesized(args
);
878 path
.segments
.last_mut().unwrap().arguments
= parenthesized
;
881 #[cfg(feature = "full")]
883 if let Some((tilde_token
, const_token
)) = tilde_const
{
884 path
.segments
.insert(
887 ident
: Ident
::new("const", const_token
.span
),
888 arguments
: PathArguments
::None
,
891 let (_const
, punct
) = path
.segments
.pairs_mut().next().unwrap().into_tuple();
892 *punct
.unwrap() = Token
![::](tilde_token
.span
);
905 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
906 impl Parse
for TraitBoundModifier
{
907 fn parse(input
: ParseStream
) -> Result
<Self> {
908 if input
.peek(Token
![?
]) {
909 input
.parse().map(TraitBoundModifier
::Maybe
)
911 Ok(TraitBoundModifier
::None
)
916 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
917 impl Parse
for ConstParam
{
918 fn parse(input
: ParseStream
) -> Result
<Self> {
919 let mut default = None
;
921 attrs
: input
.call(Attribute
::parse_outer
)?
,
922 const_token
: input
.parse()?
,
923 ident
: input
.parse()?
,
924 colon_token
: input
.parse()?
,
927 if input
.peek(Token
![=]) {
928 let eq_token
= input
.parse()?
;
929 default = Some(path
::parsing
::const_argument(input
)?
);
940 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
941 impl Parse
for WhereClause
{
942 fn parse(input
: ParseStream
) -> Result
<Self> {
944 where_token
: input
.parse()?
,
946 let mut predicates
= Punctuated
::new();
949 || input
.peek(token
::Brace
)
950 || input
.peek(Token
![,])
951 || input
.peek(Token
![;])
952 || input
.peek(Token
![:]) && !input
.peek(Token
![::])
953 || input
.peek(Token
![=])
957 let value
= input
.parse()?
;
958 predicates
.push_value(value
);
959 if !input
.peek(Token
![,]) {
962 let punct
= input
.parse()?
;
963 predicates
.push_punct(punct
);
971 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
972 impl Parse
for Option
<WhereClause
> {
973 fn parse(input
: ParseStream
) -> Result
<Self> {
974 if input
.peek(Token
![where]) {
975 input
.parse().map(Some
)
982 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
983 impl Parse
for WherePredicate
{
984 fn parse(input
: ParseStream
) -> Result
<Self> {
985 if input
.peek(Lifetime
) && input
.peek2(Token
![:]) {
986 Ok(WherePredicate
::Lifetime(PredicateLifetime
{
987 lifetime
: input
.parse()?
,
988 colon_token
: input
.parse()?
,
990 let mut bounds
= Punctuated
::new();
993 || input
.peek(token
::Brace
)
994 || input
.peek(Token
![,])
995 || input
.peek(Token
![;])
996 || input
.peek(Token
![:])
997 || input
.peek(Token
![=])
1001 let value
= input
.parse()?
;
1002 bounds
.push_value(value
);
1003 if !input
.peek(Token
![+]) {
1006 let punct
= input
.parse()?
;
1007 bounds
.push_punct(punct
);
1013 Ok(WherePredicate
::Type(PredicateType
{
1014 lifetimes
: input
.parse()?
,
1015 bounded_ty
: input
.parse()?
,
1016 colon_token
: input
.parse()?
,
1018 let mut bounds
= Punctuated
::new();
1021 || input
.peek(token
::Brace
)
1022 || input
.peek(Token
![,])
1023 || input
.peek(Token
![;])
1024 || input
.peek(Token
![:]) && !input
.peek(Token
![::])
1025 || input
.peek(Token
![=])
1029 let value
= input
.parse()?
;
1030 bounds
.push_value(value
);
1031 if !input
.peek(Token
![+]) {
1034 let punct
= input
.parse()?
;
1035 bounds
.push_punct(punct
);
1045 #[cfg(feature = "printing")]
1048 use crate::attr
::FilterAttrs
;
1049 use crate::print
::TokensOrDefault
;
1050 #[cfg(feature = "full")]
1051 use crate::punctuated
::Pair
;
1052 use proc_macro2
::TokenStream
;
1053 #[cfg(feature = "full")]
1054 use proc_macro2
::TokenTree
;
1055 use quote
::{ToTokens, TokenStreamExt}
;
1057 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1058 impl ToTokens
for Generics
{
1059 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1060 if self.params
.is_empty() {
1064 TokensOrDefault(&self.lt_token
).to_tokens(tokens
);
1066 // Print lifetimes before types and consts, regardless of their
1067 // order in self.params.
1069 // TODO: ordering rules for const parameters vs type parameters have
1070 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1071 let mut trailing_or_empty
= true;
1072 for param
in self.params
.pairs() {
1073 if let GenericParam
::Lifetime(_
) = **param
.value() {
1074 param
.to_tokens(tokens
);
1075 trailing_or_empty
= param
.punct().is_some();
1078 for param
in self.params
.pairs() {
1079 match **param
.value() {
1080 GenericParam
::Type(_
) | GenericParam
::Const(_
) => {
1081 if !trailing_or_empty
{
1082 <Token
![,]>::default().to_tokens(tokens
);
1083 trailing_or_empty
= true;
1085 param
.to_tokens(tokens
);
1087 GenericParam
::Lifetime(_
) => {}
1091 TokensOrDefault(&self.gt_token
).to_tokens(tokens
);
1095 impl<'a
> ToTokens
for ImplGenerics
<'a
> {
1096 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1097 if self.0.params
.is_empty() {
1101 TokensOrDefault(&self.0.lt_token
).to_tokens(tokens
);
1103 // Print lifetimes before types and consts, regardless of their
1104 // order in self.params.
1106 // TODO: ordering rules for const parameters vs type parameters have
1107 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1108 let mut trailing_or_empty
= true;
1109 for param
in self.0.params
.pairs() {
1110 if let GenericParam
::Lifetime(_
) = **param
.value() {
1111 param
.to_tokens(tokens
);
1112 trailing_or_empty
= param
.punct().is_some();
1115 for param
in self.0.params
.pairs() {
1116 if let GenericParam
::Lifetime(_
) = **param
.value() {
1119 if !trailing_or_empty
{
1120 <Token
![,]>::default().to_tokens(tokens
);
1121 trailing_or_empty
= true;
1123 match *param
.value() {
1124 GenericParam
::Lifetime(_
) => unreachable
!(),
1125 GenericParam
::Type(param
) => {
1126 // Leave off the type parameter defaults
1127 tokens
.append_all(param
.attrs
.outer());
1128 param
.ident
.to_tokens(tokens
);
1129 if !param
.bounds
.is_empty() {
1130 TokensOrDefault(¶m
.colon_token
).to_tokens(tokens
);
1131 param
.bounds
.to_tokens(tokens
);
1134 GenericParam
::Const(param
) => {
1135 // Leave off the const parameter defaults
1136 tokens
.append_all(param
.attrs
.outer());
1137 param
.const_token
.to_tokens(tokens
);
1138 param
.ident
.to_tokens(tokens
);
1139 param
.colon_token
.to_tokens(tokens
);
1140 param
.ty
.to_tokens(tokens
);
1143 param
.punct().to_tokens(tokens
);
1146 TokensOrDefault(&self.0.gt_token
).to_tokens(tokens
);
1150 impl<'a
> ToTokens
for TypeGenerics
<'a
> {
1151 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1152 if self.0.params
.is_empty() {
1156 TokensOrDefault(&self.0.lt_token
).to_tokens(tokens
);
1158 // Print lifetimes before types and consts, regardless of their
1159 // order in self.params.
1161 // TODO: ordering rules for const parameters vs type parameters have
1162 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1163 let mut trailing_or_empty
= true;
1164 for param
in self.0.params
.pairs() {
1165 if let GenericParam
::Lifetime(def
) = *param
.value() {
1166 // Leave off the lifetime bounds and attributes
1167 def
.lifetime
.to_tokens(tokens
);
1168 param
.punct().to_tokens(tokens
);
1169 trailing_or_empty
= param
.punct().is_some();
1172 for param
in self.0.params
.pairs() {
1173 if let GenericParam
::Lifetime(_
) = **param
.value() {
1176 if !trailing_or_empty
{
1177 <Token
![,]>::default().to_tokens(tokens
);
1178 trailing_or_empty
= true;
1180 match *param
.value() {
1181 GenericParam
::Lifetime(_
) => unreachable
!(),
1182 GenericParam
::Type(param
) => {
1183 // Leave off the type parameter defaults
1184 param
.ident
.to_tokens(tokens
);
1186 GenericParam
::Const(param
) => {
1187 // Leave off the const parameter defaults
1188 param
.ident
.to_tokens(tokens
);
1191 param
.punct().to_tokens(tokens
);
1194 TokensOrDefault(&self.0.gt_token
).to_tokens(tokens
);
1198 impl<'a
> ToTokens
for Turbofish
<'a
> {
1199 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1200 if !self.0.params
.is_empty() {
1201 <Token
![::]>::default().to_tokens(tokens
);
1202 TypeGenerics(self.0).to_tokens(tokens
);
1207 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1208 impl ToTokens
for BoundLifetimes
{
1209 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1210 self.for_token
.to_tokens(tokens
);
1211 self.lt_token
.to_tokens(tokens
);
1212 self.lifetimes
.to_tokens(tokens
);
1213 self.gt_token
.to_tokens(tokens
);
1217 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1218 impl ToTokens
for LifetimeDef
{
1219 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1220 tokens
.append_all(self.attrs
.outer());
1221 self.lifetime
.to_tokens(tokens
);
1222 if !self.bounds
.is_empty() {
1223 TokensOrDefault(&self.colon_token
).to_tokens(tokens
);
1224 self.bounds
.to_tokens(tokens
);
1229 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1230 impl ToTokens
for TypeParam
{
1231 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1232 tokens
.append_all(self.attrs
.outer());
1233 self.ident
.to_tokens(tokens
);
1234 if !self.bounds
.is_empty() {
1235 TokensOrDefault(&self.colon_token
).to_tokens(tokens
);
1236 self.bounds
.to_tokens(tokens
);
1238 if let Some(default) = &self.default {
1239 #[cfg(feature = "full")]
1241 if self.eq_token
.is_none() {
1242 if let Type
::Verbatim(default) = default {
1243 let mut iter
= default.clone().into_iter().peekable();
1244 while let Some(token
) = iter
.next() {
1245 if let TokenTree
::Punct(q
) = token
{
1246 if q
.as_char() == '
~'
{
1247 if let Some(TokenTree
::Ident(c
)) = iter
.peek() {
1249 if self.bounds
.is_empty() {
1250 TokensOrDefault(&self.colon_token
)
1253 return default.to_tokens(tokens
);
1262 TokensOrDefault(&self.eq_token
).to_tokens(tokens
);
1263 default.to_tokens(tokens
);
1268 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1269 impl ToTokens
for TraitBound
{
1270 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1271 let to_tokens
= |tokens
: &mut TokenStream
| {
1272 #[cfg(feature = "full")]
1273 let skip
= match self.path
.segments
.pairs().next() {
1274 Some(Pair
::Punctuated(t
, p
)) if t
.ident
== "const" => {
1275 Token
![~](p
.spans
[0]).to_tokens(tokens
);
1276 t
.to_tokens(tokens
);
1281 self.modifier
.to_tokens(tokens
);
1282 self.lifetimes
.to_tokens(tokens
);
1283 #[cfg(feature = "full")]
1285 self.path
.leading_colon
.to_tokens(tokens
);
1286 tokens
.append_all(self.path
.segments
.pairs().skip(skip
));
1288 #[cfg(not(feature = "full"))]
1290 self.path
.to_tokens(tokens
);
1293 match &self.paren_token
{
1294 Some(paren
) => paren
.surround(tokens
, to_tokens
),
1295 None
=> to_tokens(tokens
),
1300 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1301 impl ToTokens
for TraitBoundModifier
{
1302 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1304 TraitBoundModifier
::None
=> {}
1305 TraitBoundModifier
::Maybe(t
) => t
.to_tokens(tokens
),
1310 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1311 impl ToTokens
for ConstParam
{
1312 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1313 tokens
.append_all(self.attrs
.outer());
1314 self.const_token
.to_tokens(tokens
);
1315 self.ident
.to_tokens(tokens
);
1316 self.colon_token
.to_tokens(tokens
);
1317 self.ty
.to_tokens(tokens
);
1318 if let Some(default) = &self.default {
1319 TokensOrDefault(&self.eq_token
).to_tokens(tokens
);
1320 default.to_tokens(tokens
);
1325 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1326 impl ToTokens
for WhereClause
{
1327 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1328 if !self.predicates
.is_empty() {
1329 self.where_token
.to_tokens(tokens
);
1330 self.predicates
.to_tokens(tokens
);
1335 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1336 impl ToTokens
for PredicateType
{
1337 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1338 self.lifetimes
.to_tokens(tokens
);
1339 self.bounded_ty
.to_tokens(tokens
);
1340 self.colon_token
.to_tokens(tokens
);
1341 self.bounds
.to_tokens(tokens
);
1345 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1346 impl ToTokens
for PredicateLifetime
{
1347 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1348 self.lifetime
.to_tokens(tokens
);
1349 self.colon_token
.to_tokens(tokens
);
1350 self.bounds
.to_tokens(tokens
);
1354 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1355 impl ToTokens
for PredicateEq
{
1356 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1357 self.lhs_ty
.to_tokens(tokens
);
1358 self.eq_token
.to_tokens(tokens
);
1359 self.rhs_ty
.to_tokens(tokens
);