// SPDX-License-Identifier: Apache-2.0 OR MIT use crate::attr::Attribute;use crate::expr::Expr;use crate::ident::Ident;use crate::lifetime::Lifetime;use crate::path::Path;use crate::punctuated::{Iter, IterMut, Punctuated};use crate::token;use crate::ty::Type;use proc_macro2::TokenStream;#[cfg(all(feature = "printing", feature = "extra-traits"))]use std::fmt::{self, Debug};#[cfg(all(feature = "printing", feature = "extra-traits"))]use std::hash::{Hash, Hasher}; ast_struct! { /// Lifetimes and type parameters attached to a declaration of a function, /// enum, trait, etc. /// /// This struct represents two distinct optional syntactic elements, /// [generic parameters] and [where clause]. In some locations of the /// grammar, there may be other tokens in between these two things. /// /// [generic parameters]: https://doc.rust-lang.org/stable/reference/items/generics.html#generic-parameters /// [where clause]: https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Generics { pub lt_token: Option<Token![<]>, pub params: Punctuated<GenericParam, Token![,]>, pub gt_token: Option<Token![>]>, pub where_clause: Option<WhereClause>, }} ast_enum_of_structs! { /// A generic type parameter, lifetime, or const generic: `T: Into<String>`, /// `'a: 'b`, `const LEN: usize`. /// /// # Syntax tree enum /// /// This type is a [syntax tree enum]. /// /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum GenericParam { /// A lifetime parameter: `'a: 'b + 'c + 'd`. Lifetime(LifetimeParam), /// A generic type parameter: `T: Into<String>`. Type(TypeParam), /// A const generic parameter: `const LENGTH: usize`. Const(ConstParam), }} ast_struct! { /// A lifetime definition: `'a: 'b + 'c + 'd`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct LifetimeParam { pub attrs: Vec<Attribute>, pub lifetime: Lifetime, pub colon_token: Option<Token![:]>, pub bounds: Punctuated<Lifetime, Token![+]>, }} ast_struct! { /// A generic type parameter: `T: Into<String>`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct TypeParam { pub attrs: Vec<Attribute>, pub ident: Ident, pub colon_token: Option<Token![:]>, pub bounds: Punctuated<TypeParamBound, Token![+]>, pub eq_token: Option<Token![=]>, pub default: Option<Type>, }} ast_struct! { /// A const generic parameter: `const LENGTH: usize`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ConstParam { pub attrs: Vec<Attribute>, pub const_token: Token![const], pub ident: Ident, pub colon_token: Token![:], pub ty: Type, pub eq_token: Option<Token![=]>, pub default: Option<Expr>, }} impl Default for Generics { fn default() -> Self { Generics { lt_token: None, params: Punctuated::new(), gt_token: None, where_clause: None, } }} impl Generics { return_impl_trait! { /// Iterator over the lifetime parameters in `self.params`. pub fn lifetimes(&self) -> impl Iterator<Item = &LifetimeParam> [Lifetimes] { Lifetimes(self.params.iter()) } } return_impl_trait! { /// Iterator over the lifetime parameters in `self.params`. pub fn lifetimes_mut(&mut self) -> impl Iterator<Item = &mut LifetimeParam> [LifetimesMut] { LifetimesMut(self.params.iter_mut()) } } return_impl_trait! { /// Iterator over the type parameters in `self.params`. pub fn type_params(&self) -> impl Iterator<Item = &TypeParam> [TypeParams] { TypeParams(self.params.iter()) } } return_impl_trait! { /// Iterator over the type parameters in `self.params`. pub fn type_params_mut(&mut self) -> impl Iterator<Item = &mut TypeParam> [TypeParamsMut] { TypeParamsMut(self.params.iter_mut()) } } return_impl_trait! { /// Iterator over the constant parameters in `self.params`. pub fn const_params(&self) -> impl Iterator<Item = &ConstParam> [ConstParams] { ConstParams(self.params.iter()) } } return_impl_trait! { /// Iterator over the constant parameters in `self.params`. pub fn const_params_mut(&mut self) -> impl Iterator<Item = &mut ConstParam> [ConstParamsMut] { ConstParamsMut(self.params.iter_mut()) } } /// Initializes an empty `where`-clause if there is not one present already. pub fn make_where_clause(&mut self) -> &mut WhereClause { self.where_clause.get_or_insert_with(|| WhereClause { where_token: <Token![where]>::default(), predicates: Punctuated::new(), }) } /// Split a type's generics into the pieces required for impl'ing a trait /// for that type. /// /// ``` /// # use proc_macro2::{Span, Ident}; /// # use quote::quote; /// # /// # let generics: syn::Generics = Default::default(); /// # let name = Ident::new("MyType", Span::call_site()); /// # /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); /// quote! { /// impl #impl_generics MyTrait for #name #ty_generics #where_clause { /// // ... /// } /// } /// # ; /// ``` #[cfg(feature = "printing")] #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) { ( ImplGenerics(self), TypeGenerics(self), self.where_clause.as_ref(), ) }} pub struct Lifetimes<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for Lifetimes<'a> { type Item = &'a LifetimeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Lifetime(lifetime) = self.0.next()? { Some(lifetime) } else { self.next() } }} pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for LifetimesMut<'a> { type Item = &'a mut LifetimeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Lifetime(lifetime) = self.0.next()? { Some(lifetime) } else { self.next() } }} pub struct TypeParams<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for TypeParams<'a> { type Item = &'a TypeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Type(type_param) = self.0.next()? { Some(type_param) } else { self.next() } }} pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for TypeParamsMut<'a> { type Item = &'a mut TypeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Type(type_param) = self.0.next()? { Some(type_param) } else { self.next() } }} pub struct ConstParams<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for ConstParams<'a> { type Item = &'a ConstParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Const(const_param) = self.0.next()? { Some(const_param) } else { self.next() } }} pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for ConstParamsMut<'a> { type Item = &'a mut ConstParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Const(const_param) = self.0.next()? { Some(const_param) } else { self.next() } }} /// Returned by `Generics::split_for_impl`.#[cfg(feature = "printing")]#[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))))]pub struct ImplGenerics<'a>(&'a Generics); /// Returned by `Generics::split_for_impl`.#[cfg(feature = "printing")]#[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))))]pub struct TypeGenerics<'a>(&'a Generics); /// Returned by `TypeGenerics::as_turbofish`.#[cfg(feature = "printing")]#[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))))]pub struct Turbofish<'a>(&'a Generics); #[cfg(feature = "printing")]macro_rules! generics_wrapper_impls { ($ty:ident) => { #[cfg(feature = "clone-impls")] #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] impl<'a> Clone for $ty<'a> { fn clone(&self) -> Self { $ty(self.0) } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Debug for $ty<'a> { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter .debug_tuple(stringify!($ty)) .field(self.0) .finish() } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Eq for $ty<'a> {} #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> PartialEq for $ty<'a> { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Hash for $ty<'a> { fn hash<H: Hasher>(&self, state: &mut H) { self.0.hash(state); } } };} #[cfg(feature = "printing")]generics_wrapper_impls!(ImplGenerics);#[cfg(feature = "printing")]generics_wrapper_impls!(TypeGenerics);#[cfg(feature = "printing")]generics_wrapper_impls!(Turbofish); #[cfg(feature = "printing")]impl<'a> TypeGenerics<'a> { /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`. pub fn as_turbofish(&self) -> Turbofish<'a> { Turbofish(self.0) }} ast_struct! { /// A set of bound lifetimes: `for<'a, 'b, 'c>`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct BoundLifetimes { pub for_token: Token![for], pub lt_token: Token![<], pub lifetimes: Punctuated<GenericParam, Token![,]>, pub gt_token: Token![>], }} impl Default for BoundLifetimes { fn default() -> Self { BoundLifetimes { for_token: Default::default(), lt_token: Default::default(), lifetimes: Punctuated::new(), gt_token: Default::default(), } }} impl LifetimeParam { pub fn new(lifetime: Lifetime) -> Self { LifetimeParam { attrs: Vec::new(), lifetime, colon_token: None, bounds: Punctuated::new(), } }} impl From<Ident> for TypeParam { fn from(ident: Ident) -> Self { TypeParam { attrs: vec![], ident, colon_token: None, bounds: Punctuated::new(), eq_token: None, default: None, } }} ast_enum_of_structs! { /// A trait or lifetime used as a bound on a type parameter. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] #[non_exhaustive] pub enum TypeParamBound { Trait(TraitBound), Lifetime(Lifetime), PreciseCapture(PreciseCapture), Verbatim(TokenStream), }} ast_struct! { /// A trait used as a bound on a type parameter. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct TraitBound { pub paren_token: Option<token::Paren>, pub modifier: TraitBoundModifier, /// The `for<'a>` in `for<'a> Foo<&'a T>` pub lifetimes: Option<BoundLifetimes>, /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>` pub path: Path, }} ast_enum! { /// A modifier on a trait bound, currently only used for the `?` in /// `?Sized`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum TraitBoundModifier { None, Maybe(Token![?]), }} ast_struct! { /// Precise capturing bound: the 'use<…>' in `impl Trait + /// use<'a, T>`. #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub struct PreciseCapture #full { pub use_token: Token![use], pub lt_token: Token![<], pub params: Punctuated<CapturedParam, Token![,]>, pub gt_token: Token![>], }} #[cfg(feature = "full")]ast_enum! { /// Single parameter in a precise capturing bound. #[cfg_attr(docsrs, doc(cfg(feature = "full")))] #[non_exhaustive] pub enum CapturedParam { /// A lifetime parameter in precise capturing bound: `fn f<'a>() -> impl /// Trait + use<'a>`. Lifetime(Lifetime), /// A type parameter or const generic parameter in precise capturing /// bound: `fn f<T>() -> impl Trait + use<T>` or `fn f<const K: T>() -> /// impl Trait + use<K>`. Ident(Ident), }} ast_struct! { /// A `where` clause in a definition: `where T: Deserialize<'de>, D: /// 'static`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct WhereClause { pub where_token: Token![where], pub predicates: Punctuated<WherePredicate, Token![,]>, }} ast_enum_of_structs! { /// A single predicate in a `where` clause: `T: Deserialize<'de>`. /// /// # Syntax tree enum /// /// This type is a [syntax tree enum]. /// /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] #[non_exhaustive] pub enum WherePredicate { /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. Lifetime(PredicateLifetime), /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`. Type(PredicateType), }} ast_struct! { /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct PredicateLifetime { pub lifetime: Lifetime, pub colon_token: Token![:], pub bounds: Punctuated<Lifetime, Token![+]>, }}Lines 1–500 of 1479. Load more
// SPDX-License-Identifier: Apache-2.0 OR MIT use crate::attr::Attribute; use crate::expr::Expr; use crate::ident::Ident; use crate::lifetime::Lifetime; use crate::path::Path; use crate::punctuated::{Iter, IterMut, Punctuated}; use crate::token; use crate::ty::Type; use proc_macro2::TokenStream; #[cfg(all(feature = "printing", feature = "extra-traits"))] use std::fmt::{self, Debug}; #[cfg(all(feature = "printing", feature = "extra-traits"))] use std::hash::{Hash, Hasher}; ast_struct! { /// Lifetimes and type parameters attached to a declaration of a function, /// enum, trait, etc. /// /// This struct represents two distinct optional syntactic elements, /// [generic parameters] and [where clause]. In some locations of the /// grammar, there may be other tokens in between these two things. /// /// [generic parameters]: https://doc.rust-lang.org/stable/reference/items/generics.html#generic-parameters /// [where clause]: https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct Generics { pub lt_token: Option<Token![<]>, pub params: Punctuated<GenericParam, Token![,]>, pub gt_token: Option<Token![>]>, pub where_clause: Option<WhereClause>, } } ast_enum_of_structs! { /// A generic type parameter, lifetime, or const generic: `T: Into<String>`, /// `'a: 'b`, `const LEN: usize`. /// /// # Syntax tree enum /// /// This type is a [syntax tree enum]. /// /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum GenericParam { /// A lifetime parameter: `'a: 'b + 'c + 'd`. Lifetime(LifetimeParam), /// A generic type parameter: `T: Into<String>`. Type(TypeParam), /// A const generic parameter: `const LENGTH: usize`. Const(ConstParam), } } ast_struct! { /// A lifetime definition: `'a: 'b + 'c + 'd`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct LifetimeParam { pub attrs: Vec<Attribute>, pub lifetime: Lifetime, pub colon_token: Option<Token![:]>, pub bounds: Punctuated<Lifetime, Token![+]>, } } ast_struct! { /// A generic type parameter: `T: Into<String>`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct TypeParam { pub attrs: Vec<Attribute>, pub ident: Ident, pub colon_token: Option<Token![:]>, pub bounds: Punctuated<TypeParamBound, Token![+]>, pub eq_token: Option<Token![=]>, pub default: Option<Type>, } } ast_struct! { /// A const generic parameter: `const LENGTH: usize`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct ConstParam { pub attrs: Vec<Attribute>, pub const_token: Token![const], pub ident: Ident, pub colon_token: Token![:], pub ty: Type, pub eq_token: Option<Token![=]>, pub default: Option<Expr>, } } impl Default for Generics { fn default() -> Self { Generics { lt_token: None, params: Punctuated::new(), gt_token: None, where_clause: None, } } } impl Generics { return_impl_trait! { /// Iterator over the lifetime parameters in `self.params`. pub fn lifetimes(&self) -> impl Iterator<Item = &LifetimeParam> [Lifetimes] { Lifetimes(self.params.iter()) } } return_impl_trait! { /// Iterator over the lifetime parameters in `self.params`. pub fn lifetimes_mut(&mut self) -> impl Iterator<Item = &mut LifetimeParam> [LifetimesMut] { LifetimesMut(self.params.iter_mut()) } } return_impl_trait! { /// Iterator over the type parameters in `self.params`. pub fn type_params(&self) -> impl Iterator<Item = &TypeParam> [TypeParams] { TypeParams(self.params.iter()) } } return_impl_trait! { /// Iterator over the type parameters in `self.params`. pub fn type_params_mut(&mut self) -> impl Iterator<Item = &mut TypeParam> [TypeParamsMut] { TypeParamsMut(self.params.iter_mut()) } } return_impl_trait! { /// Iterator over the constant parameters in `self.params`. pub fn const_params(&self) -> impl Iterator<Item = &ConstParam> [ConstParams] { ConstParams(self.params.iter()) } } return_impl_trait! { /// Iterator over the constant parameters in `self.params`. pub fn const_params_mut(&mut self) -> impl Iterator<Item = &mut ConstParam> [ConstParamsMut] { ConstParamsMut(self.params.iter_mut()) } } /// Initializes an empty `where`-clause if there is not one present already. pub fn make_where_clause(&mut self) -> &mut WhereClause { self.where_clause.get_or_insert_with(|| WhereClause { where_token: <Token![where]>::default(), predicates: Punctuated::new(), }) } /// Split a type's generics into the pieces required for impl'ing a trait /// for that type. /// /// ``` /// # use proc_macro2::{Span, Ident}; /// # use quote::quote; /// # /// # let generics: syn::Generics = Default::default(); /// # let name = Ident::new("MyType", Span::call_site()); /// # /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); /// quote! { /// impl #impl_generics MyTrait for #name #ty_generics #where_clause { /// // ... /// } /// } /// # ; /// ``` #[cfg(feature = "printing")] #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) { ( ImplGenerics(self), TypeGenerics(self), self.where_clause.as_ref(), ) } } pub struct Lifetimes<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for Lifetimes<'a> { type Item = &'a LifetimeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Lifetime(lifetime) = self.0.next()? { Some(lifetime) } else { self.next() } } } pub struct LifetimesMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for LifetimesMut<'a> { type Item = &'a mut LifetimeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Lifetime(lifetime) = self.0.next()? { Some(lifetime) } else { self.next() } } } pub struct TypeParams<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for TypeParams<'a> { type Item = &'a TypeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Type(type_param) = self.0.next()? { Some(type_param) } else { self.next() } } } pub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for TypeParamsMut<'a> { type Item = &'a mut TypeParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Type(type_param) = self.0.next()? { Some(type_param) } else { self.next() } } } pub struct ConstParams<'a>(Iter<'a, GenericParam>); impl<'a> Iterator for ConstParams<'a> { type Item = &'a ConstParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Const(const_param) = self.0.next()? { Some(const_param) } else { self.next() } } } pub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>); impl<'a> Iterator for ConstParamsMut<'a> { type Item = &'a mut ConstParam; fn next(&mut self) -> Option<Self::Item> { if let GenericParam::Const(const_param) = self.0.next()? { Some(const_param) } else { self.next() } } } /// Returned by `Generics::split_for_impl`. #[cfg(feature = "printing")] #[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) )] pub struct ImplGenerics<'a>(&'a Generics); /// Returned by `Generics::split_for_impl`. #[cfg(feature = "printing")] #[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) )] pub struct TypeGenerics<'a>(&'a Generics); /// Returned by `TypeGenerics::as_turbofish`. #[cfg(feature = "printing")] #[cfg_attr( docsrs, doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) )] pub struct Turbofish<'a>(&'a Generics); #[cfg(feature = "printing")] macro_rules! generics_wrapper_impls { ($ty:ident) => { #[cfg(feature = "clone-impls")] #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))] impl<'a> Clone for $ty<'a> { fn clone(&self) -> Self { $ty(self.0) } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Debug for $ty<'a> { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter .debug_tuple(stringify!($ty)) .field(self.0) .finish() } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Eq for $ty<'a> {} #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> PartialEq for $ty<'a> { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } #[cfg(feature = "extra-traits")] #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))] impl<'a> Hash for $ty<'a> { fn hash<H: Hasher>(&self, state: &mut H) { self.0.hash(state); } } }; } #[cfg(feature = "printing")] generics_wrapper_impls!(ImplGenerics); #[cfg(feature = "printing")] generics_wrapper_impls!(TypeGenerics); #[cfg(feature = "printing")] generics_wrapper_impls!(Turbofish); #[cfg(feature = "printing")] impl<'a> TypeGenerics<'a> { /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`. pub fn as_turbofish(&self) -> Turbofish<'a> { Turbofish(self.0) } } ast_struct! { /// A set of bound lifetimes: `for<'a, 'b, 'c>`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct BoundLifetimes { pub for_token: Token![for], pub lt_token: Token![<], pub lifetimes: Punctuated<GenericParam, Token![,]>, pub gt_token: Token![>], } } impl Default for BoundLifetimes { fn default() -> Self { BoundLifetimes { for_token: Default::default(), lt_token: Default::default(), lifetimes: Punctuated::new(), gt_token: Default::default(), } } } impl LifetimeParam { pub fn new(lifetime: Lifetime) -> Self { LifetimeParam { attrs: Vec::new(), lifetime, colon_token: None, bounds: Punctuated::new(), } } } impl From<Ident> for TypeParam { fn from(ident: Ident) -> Self { TypeParam { attrs: vec![], ident, colon_token: None, bounds: Punctuated::new(), eq_token: None, default: None, } } } ast_enum_of_structs! { /// A trait or lifetime used as a bound on a type parameter. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] #[non_exhaustive] pub enum TypeParamBound { Trait(TraitBound), Lifetime(Lifetime), PreciseCapture(PreciseCapture), Verbatim(TokenStream), } } ast_struct! { /// A trait used as a bound on a type parameter. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct TraitBound { pub paren_token: Option<token::Paren>, pub modifier: TraitBoundModifier, /// The `for<'a>` in `for<'a> Foo<&'a T>` pub lifetimes: Option<BoundLifetimes>, /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>` pub path: Path, } } ast_enum! { /// A modifier on a trait bound, currently only used for the `?` in /// `?Sized`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub enum TraitBoundModifier { None, Maybe(Token![?]), } } ast_struct! { /// Precise capturing bound: the 'use<…>' in `impl Trait + /// use<'a, T>`. #[cfg_attr(docsrs, doc(cfg(feature = "full")))] pub struct PreciseCapture #full { pub use_token: Token![use], pub lt_token: Token![<], pub params: Punctuated<CapturedParam, Token![,]>, pub gt_token: Token![>], } } #[cfg(feature = "full")] ast_enum! { /// Single parameter in a precise capturing bound. #[cfg_attr(docsrs, doc(cfg(feature = "full")))] #[non_exhaustive] pub enum CapturedParam { /// A lifetime parameter in precise capturing bound: `fn f<'a>() -> impl /// Trait + use<'a>`. Lifetime(Lifetime), /// A type parameter or const generic parameter in precise capturing /// bound: `fn f<T>() -> impl Trait + use<T>` or `fn f<const K: T>() -> /// impl Trait + use<K>`. Ident(Ident), } } ast_struct! { /// A `where` clause in a definition: `where T: Deserialize<'de>, D: /// 'static`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct WhereClause { pub where_token: Token![where], pub predicates: Punctuated<WherePredicate, Token![,]>, } } ast_enum_of_structs! { /// A single predicate in a `where` clause: `T: Deserialize<'de>`. /// /// # Syntax tree enum /// /// This type is a [syntax tree enum]. /// /// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] #[non_exhaustive] pub enum WherePredicate { /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. Lifetime(PredicateLifetime), /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`. Type(PredicateType), } } ast_struct! { /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] pub struct PredicateLifetime { pub lifetime: Lifetime, pub colon_token: Token![:], pub bounds: Punctuated<Lifetime, Token![+]>, } }