2 use crate::punctuated
::{Iter, IterMut, Punctuated}
;
5 /// Lifetimes and type parameters attached to a declaration of a function,
8 /// *This type is available if Syn is built with the `"derive"` or `"full"`
12 pub lt_token
: Option
<Token
![<]>,
13 pub params
: Punctuated
<GenericParam
, Token
![,]>,
14 pub gt_token
: Option
<Token
![>]>,
15 pub where_clause
: Option
<WhereClause
>,
19 ast_enum_of_structs
! {
20 /// A generic type parameter, lifetime, or const generic: `T: Into<String>`,
21 /// `'a: 'b`, `const LEN: usize`.
23 /// *This type is available if Syn is built with the `"derive"` or `"full"`
26 /// # Syntax tree enum
28 /// This type is a [syntax tree enum].
30 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
32 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
33 // blocked on https://github.com/rust-lang/rust/issues/62833
34 pub enum GenericParam
{
35 /// A generic type parameter: `T: Into<String>`.
38 /// A lifetime definition: `'a: 'b + 'c + 'd`.
39 Lifetime(LifetimeDef
),
41 /// A const generic parameter: `const LENGTH: usize`.
47 /// A generic type parameter: `T: Into<String>`.
49 /// *This type is available if Syn is built with the `"derive"` or
50 /// `"full"` feature.*
51 pub struct TypeParam
{
52 pub attrs
: Vec
<Attribute
>,
54 pub colon_token
: Option
<Token
![:]>,
55 pub bounds
: Punctuated
<TypeParamBound
, Token
![+]>,
56 pub eq_token
: Option
<Token
![=]>,
57 pub default: Option
<Type
>,
62 /// A lifetime definition: `'a: 'b + 'c + 'd`.
64 /// *This type is available if Syn is built with the `"derive"` or
65 /// `"full"` feature.*
66 pub struct LifetimeDef
{
67 pub attrs
: Vec
<Attribute
>,
68 pub lifetime
: Lifetime
,
69 pub colon_token
: Option
<Token
![:]>,
70 pub bounds
: Punctuated
<Lifetime
, Token
![+]>,
75 /// A const generic parameter: `const LENGTH: usize`.
77 /// *This type is available if Syn is built with the `"derive"` or
78 /// `"full"` feature.*
79 pub struct ConstParam
{
80 pub attrs
: Vec
<Attribute
>,
81 pub const_token
: Token
![const],
83 pub colon_token
: Token
![:],
85 pub eq_token
: Option
<Token
![=]>,
86 pub default: Option
<Expr
>,
93 /// style="padding-right:0;">Iterator<Item = &</code><a
94 /// href="struct.TypeParam.html"><code
95 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
96 /// style="padding-left:0;">></code>
97 /// over the type parameters in `self.params`.
98 pub fn type_params(&self) -> TypeParams
{
99 TypeParams(self.params
.iter())
104 /// style="padding-right:0;">Iterator<Item = &mut </code><a
105 /// href="struct.TypeParam.html"><code
106 /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code
107 /// style="padding-left:0;">></code>
108 /// over the type parameters in `self.params`.
109 pub fn type_params_mut(&mut self) -> TypeParamsMut
{
110 TypeParamsMut(self.params
.iter_mut())
115 /// style="padding-right:0;">Iterator<Item = &</code><a
116 /// href="struct.LifetimeDef.html"><code
117 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
118 /// style="padding-left:0;">></code>
119 /// over the lifetime parameters in `self.params`.
120 pub fn lifetimes(&self) -> Lifetimes
{
121 Lifetimes(self.params
.iter())
126 /// style="padding-right:0;">Iterator<Item = &mut </code><a
127 /// href="struct.LifetimeDef.html"><code
128 /// style="padding-left:0;padding-right:0;">LifetimeDef</code></a><code
129 /// style="padding-left:0;">></code>
130 /// over the lifetime parameters in `self.params`.
131 pub fn lifetimes_mut(&mut self) -> LifetimesMut
{
132 LifetimesMut(self.params
.iter_mut())
137 /// style="padding-right:0;">Iterator<Item = &</code><a
138 /// href="struct.ConstParam.html"><code
139 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
140 /// style="padding-left:0;">></code>
141 /// over the constant parameters in `self.params`.
142 pub fn const_params(&self) -> ConstParams
{
143 ConstParams(self.params
.iter())
148 /// style="padding-right:0;">Iterator<Item = &mut </code><a
149 /// href="struct.ConstParam.html"><code
150 /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code
151 /// style="padding-left:0;">></code>
152 /// over the constant parameters in `self.params`.
153 pub fn const_params_mut(&mut self) -> ConstParamsMut
{
154 ConstParamsMut(self.params
.iter_mut())
157 /// Initializes an empty `where`-clause if there is not one present already.
158 pub fn make_where_clause(&mut self) -> &mut WhereClause
{
159 // This is Option::get_or_insert_with in Rust 1.20.
160 if self.where_clause
.is_none() {
161 self.where_clause
= Some(WhereClause
{
162 where_token
: <Token
![where]>::default(),
163 predicates
: Punctuated
::new(),
166 match &mut self.where_clause
{
167 Some(where_clause
) => where_clause
,
168 None
=> unreachable
!(),
173 pub struct TypeParams
<'a
>(Iter
<'a
, GenericParam
>);
175 impl<'a
> Iterator
for TypeParams
<'a
> {
176 type Item
= &'a TypeParam
;
178 fn next(&mut self) -> Option
<Self::Item
> {
179 let next
= match self.0.next() {
183 if let GenericParam
::Type(type_param
) = next
{
191 pub struct TypeParamsMut
<'a
>(IterMut
<'a
, GenericParam
>);
193 impl<'a
> Iterator
for TypeParamsMut
<'a
> {
194 type Item
= &'a
mut TypeParam
;
196 fn next(&mut self) -> Option
<Self::Item
> {
197 let next
= match self.0.next() {
201 if let GenericParam
::Type(type_param
) = next
{
209 pub struct Lifetimes
<'a
>(Iter
<'a
, GenericParam
>);
211 impl<'a
> Iterator
for Lifetimes
<'a
> {
212 type Item
= &'a LifetimeDef
;
214 fn next(&mut self) -> Option
<Self::Item
> {
215 let next
= match self.0.next() {
219 if let GenericParam
::Lifetime(lifetime
) = next
{
227 pub struct LifetimesMut
<'a
>(IterMut
<'a
, GenericParam
>);
229 impl<'a
> Iterator
for LifetimesMut
<'a
> {
230 type Item
= &'a
mut LifetimeDef
;
232 fn next(&mut self) -> Option
<Self::Item
> {
233 let next
= match self.0.next() {
237 if let GenericParam
::Lifetime(lifetime
) = next
{
245 pub struct ConstParams
<'a
>(Iter
<'a
, GenericParam
>);
247 impl<'a
> Iterator
for ConstParams
<'a
> {
248 type Item
= &'a ConstParam
;
250 fn next(&mut self) -> Option
<Self::Item
> {
251 let next
= match self.0.next() {
255 if let GenericParam
::Const(const_param
) = next
{
263 pub struct ConstParamsMut
<'a
>(IterMut
<'a
, GenericParam
>);
265 impl<'a
> Iterator
for ConstParamsMut
<'a
> {
266 type Item
= &'a
mut ConstParam
;
268 fn next(&mut self) -> Option
<Self::Item
> {
269 let next
= match self.0.next() {
273 if let GenericParam
::Const(const_param
) = next
{
281 /// Returned by `Generics::split_for_impl`.
283 /// *This type is available if Syn is built with the `"derive"` or `"full"`
284 /// feature and the `"printing"` feature.*
285 #[cfg(feature = "printing")]
286 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
287 #[cfg_attr(feature = "clone-impls", derive(Clone))]
288 pub struct ImplGenerics
<'a
>(&'a Generics
);
290 /// Returned by `Generics::split_for_impl`.
292 /// *This type is available if Syn is built with the `"derive"` or `"full"`
293 /// feature and the `"printing"` feature.*
294 #[cfg(feature = "printing")]
295 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
296 #[cfg_attr(feature = "clone-impls", derive(Clone))]
297 pub struct TypeGenerics
<'a
>(&'a Generics
);
299 /// Returned by `TypeGenerics::as_turbofish`.
301 /// *This type is available if Syn is built with the `"derive"` or `"full"`
302 /// feature and the `"printing"` feature.*
303 #[cfg(feature = "printing")]
304 #[cfg_attr(feature = "extra-traits", derive(Debug, Eq, PartialEq, Hash))]
305 #[cfg_attr(feature = "clone-impls", derive(Clone))]
306 pub struct Turbofish
<'a
>(&'a Generics
);
308 #[cfg(feature = "printing")]
310 /// Split a type's generics into the pieces required for impl'ing a trait
314 /// # use proc_macro2::{Span, Ident};
315 /// # use quote::quote;
318 /// # let generics: syn::Generics = Default::default();
319 /// # let name = Ident::new("MyType", Span::call_site());
321 /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
323 /// impl #impl_generics MyTrait for #name #ty_generics #where_clause {
331 /// *This method is available if Syn is built with the `"derive"` or
332 /// `"full"` feature and the `"printing"` feature.*
333 pub fn split_for_impl(&self) -> (ImplGenerics
, TypeGenerics
, Option
<&WhereClause
>) {
337 self.where_clause
.as_ref(),
342 #[cfg(feature = "printing")]
343 impl<'a
> TypeGenerics
<'a
> {
344 /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`.
346 /// *This method is available if Syn is built with the `"derive"` or
347 /// `"full"` feature and the `"printing"` feature.*
348 pub fn as_turbofish(&self) -> Turbofish
{
354 /// A set of bound lifetimes: `for<'a, 'b, 'c>`.
356 /// *This type is available if Syn is built with the `"derive"` or `"full"`
359 pub struct BoundLifetimes
{
360 pub for_token
: Token
![for],
361 pub lt_token
: Token
![<],
362 pub lifetimes
: Punctuated
<LifetimeDef
, Token
![,]>,
363 pub gt_token
: Token
![>],
368 pub fn new(lifetime
: Lifetime
) -> Self {
373 bounds
: Punctuated
::new(),
378 impl From
<Ident
> for TypeParam
{
379 fn from(ident
: Ident
) -> Self {
384 bounds
: Punctuated
::new(),
391 ast_enum_of_structs
! {
392 /// A trait or lifetime used as a bound on a type parameter.
394 /// *This type is available if Syn is built with the `"derive"` or `"full"`
396 pub enum TypeParamBound
{
403 /// A trait used as a bound on a type parameter.
405 /// *This type is available if Syn is built with the `"derive"` or `"full"`
407 pub struct TraitBound
{
408 pub paren_token
: Option
<token
::Paren
>,
409 pub modifier
: TraitBoundModifier
,
410 /// The `for<'a>` in `for<'a> Foo<&'a T>`
411 pub lifetimes
: Option
<BoundLifetimes
>,
412 /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>`
418 /// A modifier on a trait bound, currently only used for the `?` in
421 /// *This type is available if Syn is built with the `"derive"` or `"full"`
423 #[cfg_attr(feature = "clone-impls", derive(Copy))]
424 pub enum TraitBoundModifier
{
431 /// A `where` clause in a definition: `where T: Deserialize<'de>, D:
434 /// *This type is available if Syn is built with the `"derive"` or `"full"`
436 pub struct WhereClause
{
437 pub where_token
: Token
![where],
438 pub predicates
: Punctuated
<WherePredicate
, Token
![,]>,
442 ast_enum_of_structs
! {
443 /// A single predicate in a `where` clause: `T: Deserialize<'de>`.
445 /// *This type is available if Syn is built with the `"derive"` or `"full"`
448 /// # Syntax tree enum
450 /// This type is a [syntax tree enum].
452 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
454 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently
455 // blocked on https://github.com/rust-lang/rust/issues/62833
456 pub enum WherePredicate
{
457 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
460 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
461 Lifetime(PredicateLifetime
),
463 /// An equality predicate in a `where` clause (unsupported).
469 /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`.
471 /// *This type is available if Syn is built with the `"derive"` or
472 /// `"full"` feature.*
473 pub struct PredicateType
{
474 /// Any lifetimes from a `for` binding
475 pub lifetimes
: Option
<BoundLifetimes
>,
476 /// The type being bounded
477 pub bounded_ty
: Type
,
478 pub colon_token
: Token
![:],
479 /// Trait and lifetime bounds (`Clone+Send+'static`)
480 pub bounds
: Punctuated
<TypeParamBound
, Token
![+]>,
485 /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`.
487 /// *This type is available if Syn is built with the `"derive"` or
488 /// `"full"` feature.*
489 pub struct PredicateLifetime
{
490 pub lifetime
: Lifetime
,
491 pub colon_token
: Token
![:],
492 pub bounds
: Punctuated
<Lifetime
, Token
![+]>,
497 /// An equality predicate in a `where` clause (unsupported).
499 /// *This type is available if Syn is built with the `"derive"` or
500 /// `"full"` feature.*
501 pub struct PredicateEq
{
503 pub eq_token
: Token
![=],
508 #[cfg(feature = "parsing")]
512 use crate::parse
::{Parse, ParseStream, Result}
;
514 impl Parse
for Generics
{
515 fn parse(input
: ParseStream
) -> Result
<Self> {
516 if !input
.peek(Token
![<]) {
517 return Ok(Generics
::default());
520 let lt_token
: Token
![<] = input
.parse()?
;
522 let mut params
= Punctuated
::new();
523 let mut allow_lifetime_param
= true;
524 let mut allow_type_param
= true;
526 if input
.peek(Token
![>]) {
530 let attrs
= input
.call(Attribute
::parse_outer
)?
;
531 let lookahead
= input
.lookahead1();
532 if allow_lifetime_param
&& lookahead
.peek(Lifetime
) {
533 params
.push_value(GenericParam
::Lifetime(LifetimeDef
{
537 } else if allow_type_param
&& lookahead
.peek(Ident
) {
538 allow_lifetime_param
= false;
539 params
.push_value(GenericParam
::Type(TypeParam
{
543 } else if lookahead
.peek(Token
![const]) {
544 allow_lifetime_param
= false;
545 allow_type_param
= false;
546 params
.push_value(GenericParam
::Const(ConstParam
{
551 return Err(lookahead
.error());
554 if input
.peek(Token
![>]) {
557 let punct
= input
.parse()?
;
558 params
.push_punct(punct
);
561 let gt_token
: Token
![>] = input
.parse()?
;
564 lt_token
: Some(lt_token
),
566 gt_token
: Some(gt_token
),
572 impl Parse
for GenericParam
{
573 fn parse(input
: ParseStream
) -> Result
<Self> {
574 let attrs
= input
.call(Attribute
::parse_outer
)?
;
576 let lookahead
= input
.lookahead1();
577 if lookahead
.peek(Ident
) {
578 Ok(GenericParam
::Type(TypeParam
{
582 } else if lookahead
.peek(Lifetime
) {
583 Ok(GenericParam
::Lifetime(LifetimeDef
{
587 } else if lookahead
.peek(Token
![const]) {
588 Ok(GenericParam
::Const(ConstParam
{
593 Err(lookahead
.error())
598 impl Parse
for LifetimeDef
{
599 fn parse(input
: ParseStream
) -> Result
<Self> {
602 attrs
: input
.call(Attribute
::parse_outer
)?
,
603 lifetime
: input
.parse()?
,
605 if input
.peek(Token
![:]) {
614 let mut bounds
= Punctuated
::new();
617 if input
.peek(Token
![,]) || input
.peek(Token
![>]) {
620 let value
= input
.parse()?
;
621 bounds
.push_value(value
);
622 if !input
.peek(Token
![+]) {
625 let punct
= input
.parse()?
;
626 bounds
.push_punct(punct
);
635 impl Parse
for BoundLifetimes
{
636 fn parse(input
: ParseStream
) -> Result
<Self> {
638 for_token
: input
.parse()?
,
639 lt_token
: input
.parse()?
,
641 let mut lifetimes
= Punctuated
::new();
642 while !input
.peek(Token
![>]) {
643 lifetimes
.push_value(input
.parse()?
);
644 if input
.peek(Token
![>]) {
647 lifetimes
.push_punct(input
.parse()?
);
651 gt_token
: input
.parse()?
,
656 impl Parse
for Option
<BoundLifetimes
> {
657 fn parse(input
: ParseStream
) -> Result
<Self> {
658 if input
.peek(Token
![for]) {
659 input
.parse().map(Some
)
666 impl Parse
for TypeParam
{
667 fn parse(input
: ParseStream
) -> Result
<Self> {
671 attrs
: input
.call(Attribute
::parse_outer
)?
,
672 ident
: input
.parse()?
,
674 if input
.peek(Token
![:]) {
683 let mut bounds
= Punctuated
::new();
686 if input
.peek(Token
![,])
687 || input
.peek(Token
![>])
688 || input
.peek(Token
![=])
692 let value
= input
.parse()?
;
693 bounds
.push_value(value
);
694 if !input
.peek(Token
![+]) {
697 let punct
= input
.parse()?
;
698 bounds
.push_punct(punct
);
704 if input
.peek(Token
![=]) {
723 impl Parse
for TypeParamBound
{
724 fn parse(input
: ParseStream
) -> Result
<Self> {
725 if input
.peek(Lifetime
) {
726 return input
.parse().map(TypeParamBound
::Lifetime
);
729 if input
.peek(token
::Paren
) {
731 let paren_token
= parenthesized
!(content
in input
);
732 let mut bound
: TraitBound
= content
.parse()?
;
733 bound
.paren_token
= Some(paren_token
);
734 return Ok(TypeParamBound
::Trait(bound
));
737 input
.parse().map(TypeParamBound
::Trait
)
741 impl Parse
for TraitBound
{
742 fn parse(input
: ParseStream
) -> Result
<Self> {
743 let modifier
: TraitBoundModifier
= input
.parse()?
;
744 let lifetimes
: Option
<BoundLifetimes
> = input
.parse()?
;
746 let mut path
: Path
= input
.parse()?
;
747 if path
.segments
.last().unwrap().arguments
.is_empty() && input
.peek(token
::Paren
) {
748 let parenthesized
= PathArguments
::Parenthesized(input
.parse()?
);
749 path
.segments
.last_mut().unwrap().arguments
= parenthesized
;
761 impl Parse
for TraitBoundModifier
{
762 fn parse(input
: ParseStream
) -> Result
<Self> {
763 if input
.peek(Token
![?
]) {
764 input
.parse().map(TraitBoundModifier
::Maybe
)
766 Ok(TraitBoundModifier
::None
)
771 impl Parse
for ConstParam
{
772 fn parse(input
: ParseStream
) -> Result
<Self> {
773 let mut default = None
;
775 attrs
: input
.call(Attribute
::parse_outer
)?
,
776 const_token
: input
.parse()?
,
777 ident
: input
.parse()?
,
778 colon_token
: input
.parse()?
,
781 if input
.peek(Token
![=]) {
782 let eq_token
= input
.parse()?
;
783 default = Some(input
.parse
::<Expr
>()?
);
794 impl Parse
for WhereClause
{
795 fn parse(input
: ParseStream
) -> Result
<Self> {
797 where_token
: input
.parse()?
,
799 let mut predicates
= Punctuated
::new();
802 || input
.peek(token
::Brace
)
803 || input
.peek(Token
![,])
804 || input
.peek(Token
![;])
805 || input
.peek(Token
![:]) && !input
.peek(Token
![::])
806 || input
.peek(Token
![=])
810 let value
= input
.parse()?
;
811 predicates
.push_value(value
);
812 if !input
.peek(Token
![,]) {
815 let punct
= input
.parse()?
;
816 predicates
.push_punct(punct
);
824 impl Parse
for Option
<WhereClause
> {
825 fn parse(input
: ParseStream
) -> Result
<Self> {
826 if input
.peek(Token
![where]) {
827 input
.parse().map(Some
)
834 impl Parse
for WherePredicate
{
835 fn parse(input
: ParseStream
) -> Result
<Self> {
836 if input
.peek(Lifetime
) && input
.peek2(Token
![:]) {
837 Ok(WherePredicate
::Lifetime(PredicateLifetime
{
838 lifetime
: input
.parse()?
,
839 colon_token
: input
.parse()?
,
841 let mut bounds
= Punctuated
::new();
844 || input
.peek(token
::Brace
)
845 || input
.peek(Token
![,])
846 || input
.peek(Token
![;])
847 || input
.peek(Token
![:])
848 || input
.peek(Token
![=])
852 let value
= input
.parse()?
;
853 bounds
.push_value(value
);
854 if !input
.peek(Token
![+]) {
857 let punct
= input
.parse()?
;
858 bounds
.push_punct(punct
);
864 Ok(WherePredicate
::Type(PredicateType
{
865 lifetimes
: input
.parse()?
,
866 bounded_ty
: input
.parse()?
,
867 colon_token
: input
.parse()?
,
869 let mut bounds
= Punctuated
::new();
872 || input
.peek(token
::Brace
)
873 || input
.peek(Token
![,])
874 || input
.peek(Token
![;])
875 || input
.peek(Token
![:]) && !input
.peek(Token
![::])
876 || input
.peek(Token
![=])
880 let value
= input
.parse()?
;
881 bounds
.push_value(value
);
882 if !input
.peek(Token
![+]) {
885 let punct
= input
.parse()?
;
886 bounds
.push_punct(punct
);
896 #[cfg(feature = "printing")]
900 use proc_macro2
::TokenStream
;
901 use quote
::{ToTokens, TokenStreamExt}
;
903 use crate::attr
::FilterAttrs
;
904 use crate::print
::TokensOrDefault
;
906 impl ToTokens
for Generics
{
907 fn to_tokens(&self, tokens
: &mut TokenStream
) {
908 if self.params
.is_empty() {
912 TokensOrDefault(&self.lt_token
).to_tokens(tokens
);
914 // Print lifetimes before types and consts, regardless of their
915 // order in self.params.
917 // TODO: ordering rules for const parameters vs type parameters have
918 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
919 let mut trailing_or_empty
= true;
920 for param
in self.params
.pairs() {
921 if let GenericParam
::Lifetime(_
) = **param
.value() {
922 param
.to_tokens(tokens
);
923 trailing_or_empty
= param
.punct().is_some();
926 for param
in self.params
.pairs() {
927 match **param
.value() {
928 GenericParam
::Type(_
) | GenericParam
::Const(_
) => {
929 if !trailing_or_empty
{
930 <Token
![,]>::default().to_tokens(tokens
);
931 trailing_or_empty
= true;
933 param
.to_tokens(tokens
);
935 GenericParam
::Lifetime(_
) => {}
939 TokensOrDefault(&self.gt_token
).to_tokens(tokens
);
943 impl<'a
> ToTokens
for ImplGenerics
<'a
> {
944 fn to_tokens(&self, tokens
: &mut TokenStream
) {
945 if self.0.params
.is_empty() {
949 TokensOrDefault(&self.0.lt_token
).to_tokens(tokens
);
951 // Print lifetimes before types and consts, regardless of their
952 // order in self.params.
954 // TODO: ordering rules for const parameters vs type parameters have
955 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
956 let mut trailing_or_empty
= true;
957 for param
in self.0.params
.pairs() {
958 if let GenericParam
::Lifetime(_
) = **param
.value() {
959 param
.to_tokens(tokens
);
960 trailing_or_empty
= param
.punct().is_some();
963 for param
in self.0.params
.pairs() {
964 if let GenericParam
::Lifetime(_
) = **param
.value() {
967 if !trailing_or_empty
{
968 <Token
![,]>::default().to_tokens(tokens
);
969 trailing_or_empty
= true;
971 match *param
.value() {
972 GenericParam
::Lifetime(_
) => unreachable
!(),
973 GenericParam
::Type(param
) => {
974 // Leave off the type parameter defaults
975 tokens
.append_all(param
.attrs
.outer());
976 param
.ident
.to_tokens(tokens
);
977 if !param
.bounds
.is_empty() {
978 TokensOrDefault(¶m
.colon_token
).to_tokens(tokens
);
979 param
.bounds
.to_tokens(tokens
);
982 GenericParam
::Const(param
) => {
983 // Leave off the const parameter defaults
984 tokens
.append_all(param
.attrs
.outer());
985 param
.const_token
.to_tokens(tokens
);
986 param
.ident
.to_tokens(tokens
);
987 param
.colon_token
.to_tokens(tokens
);
988 param
.ty
.to_tokens(tokens
);
991 param
.punct().to_tokens(tokens
);
994 TokensOrDefault(&self.0.gt_token
).to_tokens(tokens
);
998 impl<'a
> ToTokens
for TypeGenerics
<'a
> {
999 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1000 if self.0.params
.is_empty() {
1004 TokensOrDefault(&self.0.lt_token
).to_tokens(tokens
);
1006 // Print lifetimes before types and consts, regardless of their
1007 // order in self.params.
1009 // TODO: ordering rules for const parameters vs type parameters have
1010 // not been settled yet. https://github.com/rust-lang/rust/issues/44580
1011 let mut trailing_or_empty
= true;
1012 for param
in self.0.params
.pairs() {
1013 if let GenericParam
::Lifetime(def
) = *param
.value() {
1014 // Leave off the lifetime bounds and attributes
1015 def
.lifetime
.to_tokens(tokens
);
1016 param
.punct().to_tokens(tokens
);
1017 trailing_or_empty
= param
.punct().is_some();
1020 for param
in self.0.params
.pairs() {
1021 if let GenericParam
::Lifetime(_
) = **param
.value() {
1024 if !trailing_or_empty
{
1025 <Token
![,]>::default().to_tokens(tokens
);
1026 trailing_or_empty
= true;
1028 match *param
.value() {
1029 GenericParam
::Lifetime(_
) => unreachable
!(),
1030 GenericParam
::Type(param
) => {
1031 // Leave off the type parameter defaults
1032 param
.ident
.to_tokens(tokens
);
1034 GenericParam
::Const(param
) => {
1035 // Leave off the const parameter defaults
1036 param
.ident
.to_tokens(tokens
);
1039 param
.punct().to_tokens(tokens
);
1042 TokensOrDefault(&self.0.gt_token
).to_tokens(tokens
);
1046 impl<'a
> ToTokens
for Turbofish
<'a
> {
1047 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1048 if !self.0.params
.is_empty() {
1049 <Token
![::]>::default().to_tokens(tokens
);
1050 TypeGenerics(self.0).to_tokens(tokens
);
1055 impl ToTokens
for BoundLifetimes
{
1056 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1057 self.for_token
.to_tokens(tokens
);
1058 self.lt_token
.to_tokens(tokens
);
1059 self.lifetimes
.to_tokens(tokens
);
1060 self.gt_token
.to_tokens(tokens
);
1064 impl ToTokens
for LifetimeDef
{
1065 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1066 tokens
.append_all(self.attrs
.outer());
1067 self.lifetime
.to_tokens(tokens
);
1068 if !self.bounds
.is_empty() {
1069 TokensOrDefault(&self.colon_token
).to_tokens(tokens
);
1070 self.bounds
.to_tokens(tokens
);
1075 impl ToTokens
for TypeParam
{
1076 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1077 tokens
.append_all(self.attrs
.outer());
1078 self.ident
.to_tokens(tokens
);
1079 if !self.bounds
.is_empty() {
1080 TokensOrDefault(&self.colon_token
).to_tokens(tokens
);
1081 self.bounds
.to_tokens(tokens
);
1083 if self.default.is_some() {
1084 TokensOrDefault(&self.eq_token
).to_tokens(tokens
);
1085 self.default.to_tokens(tokens
);
1090 impl ToTokens
for TraitBound
{
1091 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1092 let to_tokens
= |tokens
: &mut TokenStream
| {
1093 self.modifier
.to_tokens(tokens
);
1094 self.lifetimes
.to_tokens(tokens
);
1095 self.path
.to_tokens(tokens
);
1097 match &self.paren_token
{
1098 Some(paren
) => paren
.surround(tokens
, to_tokens
),
1099 None
=> to_tokens(tokens
),
1104 impl ToTokens
for TraitBoundModifier
{
1105 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1107 TraitBoundModifier
::None
=> {}
1108 TraitBoundModifier
::Maybe(t
) => t
.to_tokens(tokens
),
1113 impl ToTokens
for ConstParam
{
1114 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1115 tokens
.append_all(self.attrs
.outer());
1116 self.const_token
.to_tokens(tokens
);
1117 self.ident
.to_tokens(tokens
);
1118 self.colon_token
.to_tokens(tokens
);
1119 self.ty
.to_tokens(tokens
);
1120 if self.default.is_some() {
1121 TokensOrDefault(&self.eq_token
).to_tokens(tokens
);
1122 self.default.to_tokens(tokens
);
1127 impl ToTokens
for WhereClause
{
1128 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1129 if !self.predicates
.is_empty() {
1130 self.where_token
.to_tokens(tokens
);
1131 self.predicates
.to_tokens(tokens
);
1136 impl ToTokens
for PredicateType
{
1137 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1138 self.lifetimes
.to_tokens(tokens
);
1139 self.bounded_ty
.to_tokens(tokens
);
1140 self.colon_token
.to_tokens(tokens
);
1141 self.bounds
.to_tokens(tokens
);
1145 impl ToTokens
for PredicateLifetime
{
1146 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1147 self.lifetime
.to_tokens(tokens
);
1148 self.colon_token
.to_tokens(tokens
);
1149 self.bounds
.to_tokens(tokens
);
1153 impl ToTokens
for PredicateEq
{
1154 fn to_tokens(&self, tokens
: &mut TokenStream
) {
1155 self.lhs_ty
.to_tokens(tokens
);
1156 self.eq_token
.to_tokens(tokens
);
1157 self.rhs_ty
.to_tokens(tokens
);