1fad3a1d3Sopenharmony_ciuse super::*; 2fad3a1d3Sopenharmony_ciuse crate::punctuated::{Iter, IterMut, Punctuated}; 3fad3a1d3Sopenharmony_ciuse proc_macro2::TokenStream; 4fad3a1d3Sopenharmony_ci#[cfg(all(feature = "printing", feature = "extra-traits"))] 5fad3a1d3Sopenharmony_ciuse std::fmt::{self, Debug}; 6fad3a1d3Sopenharmony_ci#[cfg(all(feature = "printing", feature = "extra-traits"))] 7fad3a1d3Sopenharmony_ciuse std::hash::{Hash, Hasher}; 8fad3a1d3Sopenharmony_ci 9fad3a1d3Sopenharmony_ciast_struct! { 10fad3a1d3Sopenharmony_ci /// Lifetimes and type parameters attached to a declaration of a function, 11fad3a1d3Sopenharmony_ci /// enum, trait, etc. 12fad3a1d3Sopenharmony_ci /// 13fad3a1d3Sopenharmony_ci /// This struct represents two distinct optional syntactic elements, 14fad3a1d3Sopenharmony_ci /// [generic parameters] and [where clause]. In some locations of the 15fad3a1d3Sopenharmony_ci /// grammar, there may be other tokens in between these two things. 16fad3a1d3Sopenharmony_ci /// 17fad3a1d3Sopenharmony_ci /// [generic parameters]: https://doc.rust-lang.org/stable/reference/items/generics.html#generic-parameters 18fad3a1d3Sopenharmony_ci /// [where clause]: https://doc.rust-lang.org/stable/reference/items/generics.html#where-clauses 19fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 20fad3a1d3Sopenharmony_ci pub struct Generics { 21fad3a1d3Sopenharmony_ci pub lt_token: Option<Token![<]>, 22fad3a1d3Sopenharmony_ci pub params: Punctuated<GenericParam, Token![,]>, 23fad3a1d3Sopenharmony_ci pub gt_token: Option<Token![>]>, 24fad3a1d3Sopenharmony_ci pub where_clause: Option<WhereClause>, 25fad3a1d3Sopenharmony_ci } 26fad3a1d3Sopenharmony_ci} 27fad3a1d3Sopenharmony_ci 28fad3a1d3Sopenharmony_ciast_enum_of_structs! { 29fad3a1d3Sopenharmony_ci /// A generic type parameter, lifetime, or const generic: `T: Into<String>`, 30fad3a1d3Sopenharmony_ci /// `'a: 'b`, `const LEN: usize`. 31fad3a1d3Sopenharmony_ci /// 32fad3a1d3Sopenharmony_ci /// # Syntax tree enum 33fad3a1d3Sopenharmony_ci /// 34fad3a1d3Sopenharmony_ci /// This type is a [syntax tree enum]. 35fad3a1d3Sopenharmony_ci /// 36fad3a1d3Sopenharmony_ci /// [syntax tree enum]: Expr#syntax-tree-enums 37fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 38fad3a1d3Sopenharmony_ci pub enum GenericParam { 39fad3a1d3Sopenharmony_ci /// A lifetime parameter: `'a: 'b + 'c + 'd`. 40fad3a1d3Sopenharmony_ci Lifetime(LifetimeParam), 41fad3a1d3Sopenharmony_ci 42fad3a1d3Sopenharmony_ci /// A generic type parameter: `T: Into<String>`. 43fad3a1d3Sopenharmony_ci Type(TypeParam), 44fad3a1d3Sopenharmony_ci 45fad3a1d3Sopenharmony_ci /// A const generic parameter: `const LENGTH: usize`. 46fad3a1d3Sopenharmony_ci Const(ConstParam), 47fad3a1d3Sopenharmony_ci } 48fad3a1d3Sopenharmony_ci} 49fad3a1d3Sopenharmony_ci 50fad3a1d3Sopenharmony_ciast_struct! { 51fad3a1d3Sopenharmony_ci /// A lifetime definition: `'a: 'b + 'c + 'd`. 52fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 53fad3a1d3Sopenharmony_ci pub struct LifetimeParam { 54fad3a1d3Sopenharmony_ci pub attrs: Vec<Attribute>, 55fad3a1d3Sopenharmony_ci pub lifetime: Lifetime, 56fad3a1d3Sopenharmony_ci pub colon_token: Option<Token![:]>, 57fad3a1d3Sopenharmony_ci pub bounds: Punctuated<Lifetime, Token![+]>, 58fad3a1d3Sopenharmony_ci } 59fad3a1d3Sopenharmony_ci} 60fad3a1d3Sopenharmony_ci 61fad3a1d3Sopenharmony_ciast_struct! { 62fad3a1d3Sopenharmony_ci /// A generic type parameter: `T: Into<String>`. 63fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 64fad3a1d3Sopenharmony_ci pub struct TypeParam { 65fad3a1d3Sopenharmony_ci pub attrs: Vec<Attribute>, 66fad3a1d3Sopenharmony_ci pub ident: Ident, 67fad3a1d3Sopenharmony_ci pub colon_token: Option<Token![:]>, 68fad3a1d3Sopenharmony_ci pub bounds: Punctuated<TypeParamBound, Token![+]>, 69fad3a1d3Sopenharmony_ci pub eq_token: Option<Token![=]>, 70fad3a1d3Sopenharmony_ci pub default: Option<Type>, 71fad3a1d3Sopenharmony_ci } 72fad3a1d3Sopenharmony_ci} 73fad3a1d3Sopenharmony_ci 74fad3a1d3Sopenharmony_ciast_struct! { 75fad3a1d3Sopenharmony_ci /// A const generic parameter: `const LENGTH: usize`. 76fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 77fad3a1d3Sopenharmony_ci pub struct ConstParam { 78fad3a1d3Sopenharmony_ci pub attrs: Vec<Attribute>, 79fad3a1d3Sopenharmony_ci pub const_token: Token![const], 80fad3a1d3Sopenharmony_ci pub ident: Ident, 81fad3a1d3Sopenharmony_ci pub colon_token: Token![:], 82fad3a1d3Sopenharmony_ci pub ty: Type, 83fad3a1d3Sopenharmony_ci pub eq_token: Option<Token![=]>, 84fad3a1d3Sopenharmony_ci pub default: Option<Expr>, 85fad3a1d3Sopenharmony_ci } 86fad3a1d3Sopenharmony_ci} 87fad3a1d3Sopenharmony_ci 88fad3a1d3Sopenharmony_ciimpl Default for Generics { 89fad3a1d3Sopenharmony_ci fn default() -> Self { 90fad3a1d3Sopenharmony_ci Generics { 91fad3a1d3Sopenharmony_ci lt_token: None, 92fad3a1d3Sopenharmony_ci params: Punctuated::new(), 93fad3a1d3Sopenharmony_ci gt_token: None, 94fad3a1d3Sopenharmony_ci where_clause: None, 95fad3a1d3Sopenharmony_ci } 96fad3a1d3Sopenharmony_ci } 97fad3a1d3Sopenharmony_ci} 98fad3a1d3Sopenharmony_ci 99fad3a1d3Sopenharmony_ciimpl Generics { 100fad3a1d3Sopenharmony_ci /// Returns an 101fad3a1d3Sopenharmony_ci /// <code 102fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &</code><a 103fad3a1d3Sopenharmony_ci /// href="struct.LifetimeParam.html"><code 104fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code 105fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 106fad3a1d3Sopenharmony_ci /// over the lifetime parameters in `self.params`. 107fad3a1d3Sopenharmony_ci pub fn lifetimes(&self) -> Lifetimes { 108fad3a1d3Sopenharmony_ci Lifetimes(self.params.iter()) 109fad3a1d3Sopenharmony_ci } 110fad3a1d3Sopenharmony_ci 111fad3a1d3Sopenharmony_ci /// Returns an 112fad3a1d3Sopenharmony_ci /// <code 113fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &mut </code><a 114fad3a1d3Sopenharmony_ci /// href="struct.LifetimeParam.html"><code 115fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">LifetimeParam</code></a><code 116fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 117fad3a1d3Sopenharmony_ci /// over the lifetime parameters in `self.params`. 118fad3a1d3Sopenharmony_ci pub fn lifetimes_mut(&mut self) -> LifetimesMut { 119fad3a1d3Sopenharmony_ci LifetimesMut(self.params.iter_mut()) 120fad3a1d3Sopenharmony_ci } 121fad3a1d3Sopenharmony_ci 122fad3a1d3Sopenharmony_ci /// Returns an 123fad3a1d3Sopenharmony_ci /// <code 124fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &</code><a 125fad3a1d3Sopenharmony_ci /// href="struct.TypeParam.html"><code 126fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code 127fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 128fad3a1d3Sopenharmony_ci /// over the type parameters in `self.params`. 129fad3a1d3Sopenharmony_ci pub fn type_params(&self) -> TypeParams { 130fad3a1d3Sopenharmony_ci TypeParams(self.params.iter()) 131fad3a1d3Sopenharmony_ci } 132fad3a1d3Sopenharmony_ci 133fad3a1d3Sopenharmony_ci /// Returns an 134fad3a1d3Sopenharmony_ci /// <code 135fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &mut </code><a 136fad3a1d3Sopenharmony_ci /// href="struct.TypeParam.html"><code 137fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">TypeParam</code></a><code 138fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 139fad3a1d3Sopenharmony_ci /// over the type parameters in `self.params`. 140fad3a1d3Sopenharmony_ci pub fn type_params_mut(&mut self) -> TypeParamsMut { 141fad3a1d3Sopenharmony_ci TypeParamsMut(self.params.iter_mut()) 142fad3a1d3Sopenharmony_ci } 143fad3a1d3Sopenharmony_ci 144fad3a1d3Sopenharmony_ci /// Returns an 145fad3a1d3Sopenharmony_ci /// <code 146fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &</code><a 147fad3a1d3Sopenharmony_ci /// href="struct.ConstParam.html"><code 148fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code 149fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 150fad3a1d3Sopenharmony_ci /// over the constant parameters in `self.params`. 151fad3a1d3Sopenharmony_ci pub fn const_params(&self) -> ConstParams { 152fad3a1d3Sopenharmony_ci ConstParams(self.params.iter()) 153fad3a1d3Sopenharmony_ci } 154fad3a1d3Sopenharmony_ci 155fad3a1d3Sopenharmony_ci /// Returns an 156fad3a1d3Sopenharmony_ci /// <code 157fad3a1d3Sopenharmony_ci /// style="padding-right:0;">Iterator<Item = &mut </code><a 158fad3a1d3Sopenharmony_ci /// href="struct.ConstParam.html"><code 159fad3a1d3Sopenharmony_ci /// style="padding-left:0;padding-right:0;">ConstParam</code></a><code 160fad3a1d3Sopenharmony_ci /// style="padding-left:0;">></code> 161fad3a1d3Sopenharmony_ci /// over the constant parameters in `self.params`. 162fad3a1d3Sopenharmony_ci pub fn const_params_mut(&mut self) -> ConstParamsMut { 163fad3a1d3Sopenharmony_ci ConstParamsMut(self.params.iter_mut()) 164fad3a1d3Sopenharmony_ci } 165fad3a1d3Sopenharmony_ci 166fad3a1d3Sopenharmony_ci /// Initializes an empty `where`-clause if there is not one present already. 167fad3a1d3Sopenharmony_ci pub fn make_where_clause(&mut self) -> &mut WhereClause { 168fad3a1d3Sopenharmony_ci self.where_clause.get_or_insert_with(|| WhereClause { 169fad3a1d3Sopenharmony_ci where_token: <Token![where]>::default(), 170fad3a1d3Sopenharmony_ci predicates: Punctuated::new(), 171fad3a1d3Sopenharmony_ci }) 172fad3a1d3Sopenharmony_ci } 173fad3a1d3Sopenharmony_ci} 174fad3a1d3Sopenharmony_ci 175fad3a1d3Sopenharmony_cipub struct Lifetimes<'a>(Iter<'a, GenericParam>); 176fad3a1d3Sopenharmony_ci 177fad3a1d3Sopenharmony_ciimpl<'a> Iterator for Lifetimes<'a> { 178fad3a1d3Sopenharmony_ci type Item = &'a LifetimeParam; 179fad3a1d3Sopenharmony_ci 180fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 181fad3a1d3Sopenharmony_ci let next = match self.0.next() { 182fad3a1d3Sopenharmony_ci Some(item) => item, 183fad3a1d3Sopenharmony_ci None => return None, 184fad3a1d3Sopenharmony_ci }; 185fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(lifetime) = next { 186fad3a1d3Sopenharmony_ci Some(lifetime) 187fad3a1d3Sopenharmony_ci } else { 188fad3a1d3Sopenharmony_ci self.next() 189fad3a1d3Sopenharmony_ci } 190fad3a1d3Sopenharmony_ci } 191fad3a1d3Sopenharmony_ci} 192fad3a1d3Sopenharmony_ci 193fad3a1d3Sopenharmony_cipub struct LifetimesMut<'a>(IterMut<'a, GenericParam>); 194fad3a1d3Sopenharmony_ci 195fad3a1d3Sopenharmony_ciimpl<'a> Iterator for LifetimesMut<'a> { 196fad3a1d3Sopenharmony_ci type Item = &'a mut LifetimeParam; 197fad3a1d3Sopenharmony_ci 198fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 199fad3a1d3Sopenharmony_ci let next = match self.0.next() { 200fad3a1d3Sopenharmony_ci Some(item) => item, 201fad3a1d3Sopenharmony_ci None => return None, 202fad3a1d3Sopenharmony_ci }; 203fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(lifetime) = next { 204fad3a1d3Sopenharmony_ci Some(lifetime) 205fad3a1d3Sopenharmony_ci } else { 206fad3a1d3Sopenharmony_ci self.next() 207fad3a1d3Sopenharmony_ci } 208fad3a1d3Sopenharmony_ci } 209fad3a1d3Sopenharmony_ci} 210fad3a1d3Sopenharmony_ci 211fad3a1d3Sopenharmony_cipub struct TypeParams<'a>(Iter<'a, GenericParam>); 212fad3a1d3Sopenharmony_ci 213fad3a1d3Sopenharmony_ciimpl<'a> Iterator for TypeParams<'a> { 214fad3a1d3Sopenharmony_ci type Item = &'a TypeParam; 215fad3a1d3Sopenharmony_ci 216fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 217fad3a1d3Sopenharmony_ci let next = match self.0.next() { 218fad3a1d3Sopenharmony_ci Some(item) => item, 219fad3a1d3Sopenharmony_ci None => return None, 220fad3a1d3Sopenharmony_ci }; 221fad3a1d3Sopenharmony_ci if let GenericParam::Type(type_param) = next { 222fad3a1d3Sopenharmony_ci Some(type_param) 223fad3a1d3Sopenharmony_ci } else { 224fad3a1d3Sopenharmony_ci self.next() 225fad3a1d3Sopenharmony_ci } 226fad3a1d3Sopenharmony_ci } 227fad3a1d3Sopenharmony_ci} 228fad3a1d3Sopenharmony_ci 229fad3a1d3Sopenharmony_cipub struct TypeParamsMut<'a>(IterMut<'a, GenericParam>); 230fad3a1d3Sopenharmony_ci 231fad3a1d3Sopenharmony_ciimpl<'a> Iterator for TypeParamsMut<'a> { 232fad3a1d3Sopenharmony_ci type Item = &'a mut TypeParam; 233fad3a1d3Sopenharmony_ci 234fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 235fad3a1d3Sopenharmony_ci let next = match self.0.next() { 236fad3a1d3Sopenharmony_ci Some(item) => item, 237fad3a1d3Sopenharmony_ci None => return None, 238fad3a1d3Sopenharmony_ci }; 239fad3a1d3Sopenharmony_ci if let GenericParam::Type(type_param) = next { 240fad3a1d3Sopenharmony_ci Some(type_param) 241fad3a1d3Sopenharmony_ci } else { 242fad3a1d3Sopenharmony_ci self.next() 243fad3a1d3Sopenharmony_ci } 244fad3a1d3Sopenharmony_ci } 245fad3a1d3Sopenharmony_ci} 246fad3a1d3Sopenharmony_ci 247fad3a1d3Sopenharmony_cipub struct ConstParams<'a>(Iter<'a, GenericParam>); 248fad3a1d3Sopenharmony_ci 249fad3a1d3Sopenharmony_ciimpl<'a> Iterator for ConstParams<'a> { 250fad3a1d3Sopenharmony_ci type Item = &'a ConstParam; 251fad3a1d3Sopenharmony_ci 252fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 253fad3a1d3Sopenharmony_ci let next = match self.0.next() { 254fad3a1d3Sopenharmony_ci Some(item) => item, 255fad3a1d3Sopenharmony_ci None => return None, 256fad3a1d3Sopenharmony_ci }; 257fad3a1d3Sopenharmony_ci if let GenericParam::Const(const_param) = next { 258fad3a1d3Sopenharmony_ci Some(const_param) 259fad3a1d3Sopenharmony_ci } else { 260fad3a1d3Sopenharmony_ci self.next() 261fad3a1d3Sopenharmony_ci } 262fad3a1d3Sopenharmony_ci } 263fad3a1d3Sopenharmony_ci} 264fad3a1d3Sopenharmony_ci 265fad3a1d3Sopenharmony_cipub struct ConstParamsMut<'a>(IterMut<'a, GenericParam>); 266fad3a1d3Sopenharmony_ci 267fad3a1d3Sopenharmony_ciimpl<'a> Iterator for ConstParamsMut<'a> { 268fad3a1d3Sopenharmony_ci type Item = &'a mut ConstParam; 269fad3a1d3Sopenharmony_ci 270fad3a1d3Sopenharmony_ci fn next(&mut self) -> Option<Self::Item> { 271fad3a1d3Sopenharmony_ci let next = match self.0.next() { 272fad3a1d3Sopenharmony_ci Some(item) => item, 273fad3a1d3Sopenharmony_ci None => return None, 274fad3a1d3Sopenharmony_ci }; 275fad3a1d3Sopenharmony_ci if let GenericParam::Const(const_param) = next { 276fad3a1d3Sopenharmony_ci Some(const_param) 277fad3a1d3Sopenharmony_ci } else { 278fad3a1d3Sopenharmony_ci self.next() 279fad3a1d3Sopenharmony_ci } 280fad3a1d3Sopenharmony_ci } 281fad3a1d3Sopenharmony_ci} 282fad3a1d3Sopenharmony_ci 283fad3a1d3Sopenharmony_ci/// Returned by `Generics::split_for_impl`. 284fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 285fad3a1d3Sopenharmony_ci#[cfg_attr( 286fad3a1d3Sopenharmony_ci doc_cfg, 287fad3a1d3Sopenharmony_ci doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) 288fad3a1d3Sopenharmony_ci)] 289fad3a1d3Sopenharmony_cipub struct ImplGenerics<'a>(&'a Generics); 290fad3a1d3Sopenharmony_ci 291fad3a1d3Sopenharmony_ci/// Returned by `Generics::split_for_impl`. 292fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 293fad3a1d3Sopenharmony_ci#[cfg_attr( 294fad3a1d3Sopenharmony_ci doc_cfg, 295fad3a1d3Sopenharmony_ci doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) 296fad3a1d3Sopenharmony_ci)] 297fad3a1d3Sopenharmony_cipub struct TypeGenerics<'a>(&'a Generics); 298fad3a1d3Sopenharmony_ci 299fad3a1d3Sopenharmony_ci/// Returned by `TypeGenerics::as_turbofish`. 300fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 301fad3a1d3Sopenharmony_ci#[cfg_attr( 302fad3a1d3Sopenharmony_ci doc_cfg, 303fad3a1d3Sopenharmony_ci doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) 304fad3a1d3Sopenharmony_ci)] 305fad3a1d3Sopenharmony_cipub struct Turbofish<'a>(&'a Generics); 306fad3a1d3Sopenharmony_ci 307fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 308fad3a1d3Sopenharmony_ciimpl Generics { 309fad3a1d3Sopenharmony_ci /// Split a type's generics into the pieces required for impl'ing a trait 310fad3a1d3Sopenharmony_ci /// for that type. 311fad3a1d3Sopenharmony_ci /// 312fad3a1d3Sopenharmony_ci /// ``` 313fad3a1d3Sopenharmony_ci /// # use proc_macro2::{Span, Ident}; 314fad3a1d3Sopenharmony_ci /// # use quote::quote; 315fad3a1d3Sopenharmony_ci /// # 316fad3a1d3Sopenharmony_ci /// # let generics: syn::Generics = Default::default(); 317fad3a1d3Sopenharmony_ci /// # let name = Ident::new("MyType", Span::call_site()); 318fad3a1d3Sopenharmony_ci /// # 319fad3a1d3Sopenharmony_ci /// let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); 320fad3a1d3Sopenharmony_ci /// quote! { 321fad3a1d3Sopenharmony_ci /// impl #impl_generics MyTrait for #name #ty_generics #where_clause { 322fad3a1d3Sopenharmony_ci /// // ... 323fad3a1d3Sopenharmony_ci /// } 324fad3a1d3Sopenharmony_ci /// } 325fad3a1d3Sopenharmony_ci /// # ; 326fad3a1d3Sopenharmony_ci /// ``` 327fad3a1d3Sopenharmony_ci #[cfg_attr( 328fad3a1d3Sopenharmony_ci doc_cfg, 329fad3a1d3Sopenharmony_ci doc(cfg(all(any(feature = "full", feature = "derive"), feature = "printing"))) 330fad3a1d3Sopenharmony_ci )] 331fad3a1d3Sopenharmony_ci pub fn split_for_impl(&self) -> (ImplGenerics, TypeGenerics, Option<&WhereClause>) { 332fad3a1d3Sopenharmony_ci ( 333fad3a1d3Sopenharmony_ci ImplGenerics(self), 334fad3a1d3Sopenharmony_ci TypeGenerics(self), 335fad3a1d3Sopenharmony_ci self.where_clause.as_ref(), 336fad3a1d3Sopenharmony_ci ) 337fad3a1d3Sopenharmony_ci } 338fad3a1d3Sopenharmony_ci} 339fad3a1d3Sopenharmony_ci 340fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 341fad3a1d3Sopenharmony_cimacro_rules! generics_wrapper_impls { 342fad3a1d3Sopenharmony_ci ($ty:ident) => { 343fad3a1d3Sopenharmony_ci #[cfg(feature = "clone-impls")] 344fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))] 345fad3a1d3Sopenharmony_ci impl<'a> Clone for $ty<'a> { 346fad3a1d3Sopenharmony_ci fn clone(&self) -> Self { 347fad3a1d3Sopenharmony_ci $ty(self.0) 348fad3a1d3Sopenharmony_ci } 349fad3a1d3Sopenharmony_ci } 350fad3a1d3Sopenharmony_ci 351fad3a1d3Sopenharmony_ci #[cfg(feature = "extra-traits")] 352fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] 353fad3a1d3Sopenharmony_ci impl<'a> Debug for $ty<'a> { 354fad3a1d3Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 355fad3a1d3Sopenharmony_ci formatter 356fad3a1d3Sopenharmony_ci .debug_tuple(stringify!($ty)) 357fad3a1d3Sopenharmony_ci .field(self.0) 358fad3a1d3Sopenharmony_ci .finish() 359fad3a1d3Sopenharmony_ci } 360fad3a1d3Sopenharmony_ci } 361fad3a1d3Sopenharmony_ci 362fad3a1d3Sopenharmony_ci #[cfg(feature = "extra-traits")] 363fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] 364fad3a1d3Sopenharmony_ci impl<'a> Eq for $ty<'a> {} 365fad3a1d3Sopenharmony_ci 366fad3a1d3Sopenharmony_ci #[cfg(feature = "extra-traits")] 367fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] 368fad3a1d3Sopenharmony_ci impl<'a> PartialEq for $ty<'a> { 369fad3a1d3Sopenharmony_ci fn eq(&self, other: &Self) -> bool { 370fad3a1d3Sopenharmony_ci self.0 == other.0 371fad3a1d3Sopenharmony_ci } 372fad3a1d3Sopenharmony_ci } 373fad3a1d3Sopenharmony_ci 374fad3a1d3Sopenharmony_ci #[cfg(feature = "extra-traits")] 375fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))] 376fad3a1d3Sopenharmony_ci impl<'a> Hash for $ty<'a> { 377fad3a1d3Sopenharmony_ci fn hash<H: Hasher>(&self, state: &mut H) { 378fad3a1d3Sopenharmony_ci self.0.hash(state); 379fad3a1d3Sopenharmony_ci } 380fad3a1d3Sopenharmony_ci } 381fad3a1d3Sopenharmony_ci }; 382fad3a1d3Sopenharmony_ci} 383fad3a1d3Sopenharmony_ci 384fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 385fad3a1d3Sopenharmony_cigenerics_wrapper_impls!(ImplGenerics); 386fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 387fad3a1d3Sopenharmony_cigenerics_wrapper_impls!(TypeGenerics); 388fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 389fad3a1d3Sopenharmony_cigenerics_wrapper_impls!(Turbofish); 390fad3a1d3Sopenharmony_ci 391fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 392fad3a1d3Sopenharmony_ciimpl<'a> TypeGenerics<'a> { 393fad3a1d3Sopenharmony_ci /// Turn a type's generics like `<X, Y>` into a turbofish like `::<X, Y>`. 394fad3a1d3Sopenharmony_ci pub fn as_turbofish(&self) -> Turbofish { 395fad3a1d3Sopenharmony_ci Turbofish(self.0) 396fad3a1d3Sopenharmony_ci } 397fad3a1d3Sopenharmony_ci} 398fad3a1d3Sopenharmony_ci 399fad3a1d3Sopenharmony_ciast_struct! { 400fad3a1d3Sopenharmony_ci /// A set of bound lifetimes: `for<'a, 'b, 'c>`. 401fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 402fad3a1d3Sopenharmony_ci pub struct BoundLifetimes { 403fad3a1d3Sopenharmony_ci pub for_token: Token![for], 404fad3a1d3Sopenharmony_ci pub lt_token: Token![<], 405fad3a1d3Sopenharmony_ci pub lifetimes: Punctuated<GenericParam, Token![,]>, 406fad3a1d3Sopenharmony_ci pub gt_token: Token![>], 407fad3a1d3Sopenharmony_ci } 408fad3a1d3Sopenharmony_ci} 409fad3a1d3Sopenharmony_ci 410fad3a1d3Sopenharmony_ciimpl Default for BoundLifetimes { 411fad3a1d3Sopenharmony_ci fn default() -> Self { 412fad3a1d3Sopenharmony_ci BoundLifetimes { 413fad3a1d3Sopenharmony_ci for_token: Default::default(), 414fad3a1d3Sopenharmony_ci lt_token: Default::default(), 415fad3a1d3Sopenharmony_ci lifetimes: Punctuated::new(), 416fad3a1d3Sopenharmony_ci gt_token: Default::default(), 417fad3a1d3Sopenharmony_ci } 418fad3a1d3Sopenharmony_ci } 419fad3a1d3Sopenharmony_ci} 420fad3a1d3Sopenharmony_ci 421fad3a1d3Sopenharmony_ciimpl LifetimeParam { 422fad3a1d3Sopenharmony_ci pub fn new(lifetime: Lifetime) -> Self { 423fad3a1d3Sopenharmony_ci LifetimeParam { 424fad3a1d3Sopenharmony_ci attrs: Vec::new(), 425fad3a1d3Sopenharmony_ci lifetime, 426fad3a1d3Sopenharmony_ci colon_token: None, 427fad3a1d3Sopenharmony_ci bounds: Punctuated::new(), 428fad3a1d3Sopenharmony_ci } 429fad3a1d3Sopenharmony_ci } 430fad3a1d3Sopenharmony_ci} 431fad3a1d3Sopenharmony_ci 432fad3a1d3Sopenharmony_ciimpl From<Ident> for TypeParam { 433fad3a1d3Sopenharmony_ci fn from(ident: Ident) -> Self { 434fad3a1d3Sopenharmony_ci TypeParam { 435fad3a1d3Sopenharmony_ci attrs: vec![], 436fad3a1d3Sopenharmony_ci ident, 437fad3a1d3Sopenharmony_ci colon_token: None, 438fad3a1d3Sopenharmony_ci bounds: Punctuated::new(), 439fad3a1d3Sopenharmony_ci eq_token: None, 440fad3a1d3Sopenharmony_ci default: None, 441fad3a1d3Sopenharmony_ci } 442fad3a1d3Sopenharmony_ci } 443fad3a1d3Sopenharmony_ci} 444fad3a1d3Sopenharmony_ci 445fad3a1d3Sopenharmony_ciast_enum_of_structs! { 446fad3a1d3Sopenharmony_ci /// A trait or lifetime used as a bound on a type parameter. 447fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 448fad3a1d3Sopenharmony_ci #[non_exhaustive] 449fad3a1d3Sopenharmony_ci pub enum TypeParamBound { 450fad3a1d3Sopenharmony_ci Trait(TraitBound), 451fad3a1d3Sopenharmony_ci Lifetime(Lifetime), 452fad3a1d3Sopenharmony_ci Verbatim(TokenStream), 453fad3a1d3Sopenharmony_ci } 454fad3a1d3Sopenharmony_ci} 455fad3a1d3Sopenharmony_ci 456fad3a1d3Sopenharmony_ciast_struct! { 457fad3a1d3Sopenharmony_ci /// A trait used as a bound on a type parameter. 458fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 459fad3a1d3Sopenharmony_ci pub struct TraitBound { 460fad3a1d3Sopenharmony_ci pub paren_token: Option<token::Paren>, 461fad3a1d3Sopenharmony_ci pub modifier: TraitBoundModifier, 462fad3a1d3Sopenharmony_ci /// The `for<'a>` in `for<'a> Foo<&'a T>` 463fad3a1d3Sopenharmony_ci pub lifetimes: Option<BoundLifetimes>, 464fad3a1d3Sopenharmony_ci /// The `Foo<&'a T>` in `for<'a> Foo<&'a T>` 465fad3a1d3Sopenharmony_ci pub path: Path, 466fad3a1d3Sopenharmony_ci } 467fad3a1d3Sopenharmony_ci} 468fad3a1d3Sopenharmony_ci 469fad3a1d3Sopenharmony_ciast_enum! { 470fad3a1d3Sopenharmony_ci /// A modifier on a trait bound, currently only used for the `?` in 471fad3a1d3Sopenharmony_ci /// `?Sized`. 472fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 473fad3a1d3Sopenharmony_ci pub enum TraitBoundModifier { 474fad3a1d3Sopenharmony_ci None, 475fad3a1d3Sopenharmony_ci Maybe(Token![?]), 476fad3a1d3Sopenharmony_ci } 477fad3a1d3Sopenharmony_ci} 478fad3a1d3Sopenharmony_ci 479fad3a1d3Sopenharmony_ciast_struct! { 480fad3a1d3Sopenharmony_ci /// A `where` clause in a definition: `where T: Deserialize<'de>, D: 481fad3a1d3Sopenharmony_ci /// 'static`. 482fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 483fad3a1d3Sopenharmony_ci pub struct WhereClause { 484fad3a1d3Sopenharmony_ci pub where_token: Token![where], 485fad3a1d3Sopenharmony_ci pub predicates: Punctuated<WherePredicate, Token![,]>, 486fad3a1d3Sopenharmony_ci } 487fad3a1d3Sopenharmony_ci} 488fad3a1d3Sopenharmony_ci 489fad3a1d3Sopenharmony_ciast_enum_of_structs! { 490fad3a1d3Sopenharmony_ci /// A single predicate in a `where` clause: `T: Deserialize<'de>`. 491fad3a1d3Sopenharmony_ci /// 492fad3a1d3Sopenharmony_ci /// # Syntax tree enum 493fad3a1d3Sopenharmony_ci /// 494fad3a1d3Sopenharmony_ci /// This type is a [syntax tree enum]. 495fad3a1d3Sopenharmony_ci /// 496fad3a1d3Sopenharmony_ci /// [syntax tree enum]: Expr#syntax-tree-enums 497fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 498fad3a1d3Sopenharmony_ci #[non_exhaustive] 499fad3a1d3Sopenharmony_ci pub enum WherePredicate { 500fad3a1d3Sopenharmony_ci /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. 501fad3a1d3Sopenharmony_ci Lifetime(PredicateLifetime), 502fad3a1d3Sopenharmony_ci 503fad3a1d3Sopenharmony_ci /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`. 504fad3a1d3Sopenharmony_ci Type(PredicateType), 505fad3a1d3Sopenharmony_ci } 506fad3a1d3Sopenharmony_ci} 507fad3a1d3Sopenharmony_ci 508fad3a1d3Sopenharmony_ciast_struct! { 509fad3a1d3Sopenharmony_ci /// A lifetime predicate in a `where` clause: `'a: 'b + 'c`. 510fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 511fad3a1d3Sopenharmony_ci pub struct PredicateLifetime { 512fad3a1d3Sopenharmony_ci pub lifetime: Lifetime, 513fad3a1d3Sopenharmony_ci pub colon_token: Token![:], 514fad3a1d3Sopenharmony_ci pub bounds: Punctuated<Lifetime, Token![+]>, 515fad3a1d3Sopenharmony_ci } 516fad3a1d3Sopenharmony_ci} 517fad3a1d3Sopenharmony_ci 518fad3a1d3Sopenharmony_ciast_struct! { 519fad3a1d3Sopenharmony_ci /// A type predicate in a `where` clause: `for<'c> Foo<'c>: Trait<'c>`. 520fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] 521fad3a1d3Sopenharmony_ci pub struct PredicateType { 522fad3a1d3Sopenharmony_ci /// Any lifetimes from a `for` binding 523fad3a1d3Sopenharmony_ci pub lifetimes: Option<BoundLifetimes>, 524fad3a1d3Sopenharmony_ci /// The type being bounded 525fad3a1d3Sopenharmony_ci pub bounded_ty: Type, 526fad3a1d3Sopenharmony_ci pub colon_token: Token![:], 527fad3a1d3Sopenharmony_ci /// Trait and lifetime bounds (`Clone+Send+'static`) 528fad3a1d3Sopenharmony_ci pub bounds: Punctuated<TypeParamBound, Token![+]>, 529fad3a1d3Sopenharmony_ci } 530fad3a1d3Sopenharmony_ci} 531fad3a1d3Sopenharmony_ci 532fad3a1d3Sopenharmony_ci#[cfg(feature = "parsing")] 533fad3a1d3Sopenharmony_cipub(crate) mod parsing { 534fad3a1d3Sopenharmony_ci use super::*; 535fad3a1d3Sopenharmony_ci use crate::ext::IdentExt as _; 536fad3a1d3Sopenharmony_ci use crate::parse::{Parse, ParseStream, Result}; 537fad3a1d3Sopenharmony_ci 538fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 539fad3a1d3Sopenharmony_ci impl Parse for Generics { 540fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 541fad3a1d3Sopenharmony_ci if !input.peek(Token![<]) { 542fad3a1d3Sopenharmony_ci return Ok(Generics::default()); 543fad3a1d3Sopenharmony_ci } 544fad3a1d3Sopenharmony_ci 545fad3a1d3Sopenharmony_ci let lt_token: Token![<] = input.parse()?; 546fad3a1d3Sopenharmony_ci 547fad3a1d3Sopenharmony_ci let mut params = Punctuated::new(); 548fad3a1d3Sopenharmony_ci loop { 549fad3a1d3Sopenharmony_ci if input.peek(Token![>]) { 550fad3a1d3Sopenharmony_ci break; 551fad3a1d3Sopenharmony_ci } 552fad3a1d3Sopenharmony_ci 553fad3a1d3Sopenharmony_ci let attrs = input.call(Attribute::parse_outer)?; 554fad3a1d3Sopenharmony_ci let lookahead = input.lookahead1(); 555fad3a1d3Sopenharmony_ci if lookahead.peek(Lifetime) { 556fad3a1d3Sopenharmony_ci params.push_value(GenericParam::Lifetime(LifetimeParam { 557fad3a1d3Sopenharmony_ci attrs, 558fad3a1d3Sopenharmony_ci ..input.parse()? 559fad3a1d3Sopenharmony_ci })); 560fad3a1d3Sopenharmony_ci } else if lookahead.peek(Ident) { 561fad3a1d3Sopenharmony_ci params.push_value(GenericParam::Type(TypeParam { 562fad3a1d3Sopenharmony_ci attrs, 563fad3a1d3Sopenharmony_ci ..input.parse()? 564fad3a1d3Sopenharmony_ci })); 565fad3a1d3Sopenharmony_ci } else if lookahead.peek(Token![const]) { 566fad3a1d3Sopenharmony_ci params.push_value(GenericParam::Const(ConstParam { 567fad3a1d3Sopenharmony_ci attrs, 568fad3a1d3Sopenharmony_ci ..input.parse()? 569fad3a1d3Sopenharmony_ci })); 570fad3a1d3Sopenharmony_ci } else if input.peek(Token![_]) { 571fad3a1d3Sopenharmony_ci params.push_value(GenericParam::Type(TypeParam { 572fad3a1d3Sopenharmony_ci attrs, 573fad3a1d3Sopenharmony_ci ident: input.call(Ident::parse_any)?, 574fad3a1d3Sopenharmony_ci colon_token: None, 575fad3a1d3Sopenharmony_ci bounds: Punctuated::new(), 576fad3a1d3Sopenharmony_ci eq_token: None, 577fad3a1d3Sopenharmony_ci default: None, 578fad3a1d3Sopenharmony_ci })); 579fad3a1d3Sopenharmony_ci } else { 580fad3a1d3Sopenharmony_ci return Err(lookahead.error()); 581fad3a1d3Sopenharmony_ci } 582fad3a1d3Sopenharmony_ci 583fad3a1d3Sopenharmony_ci if input.peek(Token![>]) { 584fad3a1d3Sopenharmony_ci break; 585fad3a1d3Sopenharmony_ci } 586fad3a1d3Sopenharmony_ci let punct = input.parse()?; 587fad3a1d3Sopenharmony_ci params.push_punct(punct); 588fad3a1d3Sopenharmony_ci } 589fad3a1d3Sopenharmony_ci 590fad3a1d3Sopenharmony_ci let gt_token: Token![>] = input.parse()?; 591fad3a1d3Sopenharmony_ci 592fad3a1d3Sopenharmony_ci Ok(Generics { 593fad3a1d3Sopenharmony_ci lt_token: Some(lt_token), 594fad3a1d3Sopenharmony_ci params, 595fad3a1d3Sopenharmony_ci gt_token: Some(gt_token), 596fad3a1d3Sopenharmony_ci where_clause: None, 597fad3a1d3Sopenharmony_ci }) 598fad3a1d3Sopenharmony_ci } 599fad3a1d3Sopenharmony_ci } 600fad3a1d3Sopenharmony_ci 601fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 602fad3a1d3Sopenharmony_ci impl Parse for GenericParam { 603fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 604fad3a1d3Sopenharmony_ci let attrs = input.call(Attribute::parse_outer)?; 605fad3a1d3Sopenharmony_ci 606fad3a1d3Sopenharmony_ci let lookahead = input.lookahead1(); 607fad3a1d3Sopenharmony_ci if lookahead.peek(Ident) { 608fad3a1d3Sopenharmony_ci Ok(GenericParam::Type(TypeParam { 609fad3a1d3Sopenharmony_ci attrs, 610fad3a1d3Sopenharmony_ci ..input.parse()? 611fad3a1d3Sopenharmony_ci })) 612fad3a1d3Sopenharmony_ci } else if lookahead.peek(Lifetime) { 613fad3a1d3Sopenharmony_ci Ok(GenericParam::Lifetime(LifetimeParam { 614fad3a1d3Sopenharmony_ci attrs, 615fad3a1d3Sopenharmony_ci ..input.parse()? 616fad3a1d3Sopenharmony_ci })) 617fad3a1d3Sopenharmony_ci } else if lookahead.peek(Token![const]) { 618fad3a1d3Sopenharmony_ci Ok(GenericParam::Const(ConstParam { 619fad3a1d3Sopenharmony_ci attrs, 620fad3a1d3Sopenharmony_ci ..input.parse()? 621fad3a1d3Sopenharmony_ci })) 622fad3a1d3Sopenharmony_ci } else { 623fad3a1d3Sopenharmony_ci Err(lookahead.error()) 624fad3a1d3Sopenharmony_ci } 625fad3a1d3Sopenharmony_ci } 626fad3a1d3Sopenharmony_ci } 627fad3a1d3Sopenharmony_ci 628fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 629fad3a1d3Sopenharmony_ci impl Parse for LifetimeParam { 630fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 631fad3a1d3Sopenharmony_ci let has_colon; 632fad3a1d3Sopenharmony_ci Ok(LifetimeParam { 633fad3a1d3Sopenharmony_ci attrs: input.call(Attribute::parse_outer)?, 634fad3a1d3Sopenharmony_ci lifetime: input.parse()?, 635fad3a1d3Sopenharmony_ci colon_token: { 636fad3a1d3Sopenharmony_ci if input.peek(Token![:]) { 637fad3a1d3Sopenharmony_ci has_colon = true; 638fad3a1d3Sopenharmony_ci Some(input.parse()?) 639fad3a1d3Sopenharmony_ci } else { 640fad3a1d3Sopenharmony_ci has_colon = false; 641fad3a1d3Sopenharmony_ci None 642fad3a1d3Sopenharmony_ci } 643fad3a1d3Sopenharmony_ci }, 644fad3a1d3Sopenharmony_ci bounds: { 645fad3a1d3Sopenharmony_ci let mut bounds = Punctuated::new(); 646fad3a1d3Sopenharmony_ci if has_colon { 647fad3a1d3Sopenharmony_ci loop { 648fad3a1d3Sopenharmony_ci if input.peek(Token![,]) || input.peek(Token![>]) { 649fad3a1d3Sopenharmony_ci break; 650fad3a1d3Sopenharmony_ci } 651fad3a1d3Sopenharmony_ci let value = input.parse()?; 652fad3a1d3Sopenharmony_ci bounds.push_value(value); 653fad3a1d3Sopenharmony_ci if !input.peek(Token![+]) { 654fad3a1d3Sopenharmony_ci break; 655fad3a1d3Sopenharmony_ci } 656fad3a1d3Sopenharmony_ci let punct = input.parse()?; 657fad3a1d3Sopenharmony_ci bounds.push_punct(punct); 658fad3a1d3Sopenharmony_ci } 659fad3a1d3Sopenharmony_ci } 660fad3a1d3Sopenharmony_ci bounds 661fad3a1d3Sopenharmony_ci }, 662fad3a1d3Sopenharmony_ci }) 663fad3a1d3Sopenharmony_ci } 664fad3a1d3Sopenharmony_ci } 665fad3a1d3Sopenharmony_ci 666fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 667fad3a1d3Sopenharmony_ci impl Parse for BoundLifetimes { 668fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 669fad3a1d3Sopenharmony_ci Ok(BoundLifetimes { 670fad3a1d3Sopenharmony_ci for_token: input.parse()?, 671fad3a1d3Sopenharmony_ci lt_token: input.parse()?, 672fad3a1d3Sopenharmony_ci lifetimes: { 673fad3a1d3Sopenharmony_ci let mut lifetimes = Punctuated::new(); 674fad3a1d3Sopenharmony_ci while !input.peek(Token![>]) { 675fad3a1d3Sopenharmony_ci let attrs = input.call(Attribute::parse_outer)?; 676fad3a1d3Sopenharmony_ci let lifetime: Lifetime = input.parse()?; 677fad3a1d3Sopenharmony_ci lifetimes.push_value(GenericParam::Lifetime(LifetimeParam { 678fad3a1d3Sopenharmony_ci attrs, 679fad3a1d3Sopenharmony_ci lifetime, 680fad3a1d3Sopenharmony_ci colon_token: None, 681fad3a1d3Sopenharmony_ci bounds: Punctuated::new(), 682fad3a1d3Sopenharmony_ci })); 683fad3a1d3Sopenharmony_ci if input.peek(Token![>]) { 684fad3a1d3Sopenharmony_ci break; 685fad3a1d3Sopenharmony_ci } 686fad3a1d3Sopenharmony_ci lifetimes.push_punct(input.parse()?); 687fad3a1d3Sopenharmony_ci } 688fad3a1d3Sopenharmony_ci lifetimes 689fad3a1d3Sopenharmony_ci }, 690fad3a1d3Sopenharmony_ci gt_token: input.parse()?, 691fad3a1d3Sopenharmony_ci }) 692fad3a1d3Sopenharmony_ci } 693fad3a1d3Sopenharmony_ci } 694fad3a1d3Sopenharmony_ci 695fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 696fad3a1d3Sopenharmony_ci impl Parse for Option<BoundLifetimes> { 697fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 698fad3a1d3Sopenharmony_ci if input.peek(Token![for]) { 699fad3a1d3Sopenharmony_ci input.parse().map(Some) 700fad3a1d3Sopenharmony_ci } else { 701fad3a1d3Sopenharmony_ci Ok(None) 702fad3a1d3Sopenharmony_ci } 703fad3a1d3Sopenharmony_ci } 704fad3a1d3Sopenharmony_ci } 705fad3a1d3Sopenharmony_ci 706fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 707fad3a1d3Sopenharmony_ci impl Parse for TypeParam { 708fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 709fad3a1d3Sopenharmony_ci let attrs = input.call(Attribute::parse_outer)?; 710fad3a1d3Sopenharmony_ci let ident: Ident = input.parse()?; 711fad3a1d3Sopenharmony_ci let colon_token: Option<Token![:]> = input.parse()?; 712fad3a1d3Sopenharmony_ci 713fad3a1d3Sopenharmony_ci let mut bounds = Punctuated::new(); 714fad3a1d3Sopenharmony_ci if colon_token.is_some() { 715fad3a1d3Sopenharmony_ci loop { 716fad3a1d3Sopenharmony_ci if input.peek(Token![,]) || input.peek(Token![>]) || input.peek(Token![=]) { 717fad3a1d3Sopenharmony_ci break; 718fad3a1d3Sopenharmony_ci } 719fad3a1d3Sopenharmony_ci let value: TypeParamBound = input.parse()?; 720fad3a1d3Sopenharmony_ci bounds.push_value(value); 721fad3a1d3Sopenharmony_ci if !input.peek(Token![+]) { 722fad3a1d3Sopenharmony_ci break; 723fad3a1d3Sopenharmony_ci } 724fad3a1d3Sopenharmony_ci let punct: Token![+] = input.parse()?; 725fad3a1d3Sopenharmony_ci bounds.push_punct(punct); 726fad3a1d3Sopenharmony_ci } 727fad3a1d3Sopenharmony_ci } 728fad3a1d3Sopenharmony_ci 729fad3a1d3Sopenharmony_ci let eq_token: Option<Token![=]> = input.parse()?; 730fad3a1d3Sopenharmony_ci let default = if eq_token.is_some() { 731fad3a1d3Sopenharmony_ci Some(input.parse::<Type>()?) 732fad3a1d3Sopenharmony_ci } else { 733fad3a1d3Sopenharmony_ci None 734fad3a1d3Sopenharmony_ci }; 735fad3a1d3Sopenharmony_ci 736fad3a1d3Sopenharmony_ci Ok(TypeParam { 737fad3a1d3Sopenharmony_ci attrs, 738fad3a1d3Sopenharmony_ci ident, 739fad3a1d3Sopenharmony_ci colon_token, 740fad3a1d3Sopenharmony_ci bounds, 741fad3a1d3Sopenharmony_ci eq_token, 742fad3a1d3Sopenharmony_ci default, 743fad3a1d3Sopenharmony_ci }) 744fad3a1d3Sopenharmony_ci } 745fad3a1d3Sopenharmony_ci } 746fad3a1d3Sopenharmony_ci 747fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 748fad3a1d3Sopenharmony_ci impl Parse for TypeParamBound { 749fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 750fad3a1d3Sopenharmony_ci if input.peek(Lifetime) { 751fad3a1d3Sopenharmony_ci return input.parse().map(TypeParamBound::Lifetime); 752fad3a1d3Sopenharmony_ci } 753fad3a1d3Sopenharmony_ci 754fad3a1d3Sopenharmony_ci let begin = input.fork(); 755fad3a1d3Sopenharmony_ci 756fad3a1d3Sopenharmony_ci let content; 757fad3a1d3Sopenharmony_ci let (paren_token, content) = if input.peek(token::Paren) { 758fad3a1d3Sopenharmony_ci (Some(parenthesized!(content in input)), &content) 759fad3a1d3Sopenharmony_ci } else { 760fad3a1d3Sopenharmony_ci (None, input) 761fad3a1d3Sopenharmony_ci }; 762fad3a1d3Sopenharmony_ci 763fad3a1d3Sopenharmony_ci let is_tilde_const = 764fad3a1d3Sopenharmony_ci cfg!(feature = "full") && content.peek(Token![~]) && content.peek2(Token![const]); 765fad3a1d3Sopenharmony_ci if is_tilde_const { 766fad3a1d3Sopenharmony_ci content.parse::<Token![~]>()?; 767fad3a1d3Sopenharmony_ci content.parse::<Token![const]>()?; 768fad3a1d3Sopenharmony_ci } 769fad3a1d3Sopenharmony_ci 770fad3a1d3Sopenharmony_ci let mut bound: TraitBound = content.parse()?; 771fad3a1d3Sopenharmony_ci bound.paren_token = paren_token; 772fad3a1d3Sopenharmony_ci 773fad3a1d3Sopenharmony_ci if is_tilde_const { 774fad3a1d3Sopenharmony_ci Ok(TypeParamBound::Verbatim(verbatim::between(&begin, input))) 775fad3a1d3Sopenharmony_ci } else { 776fad3a1d3Sopenharmony_ci Ok(TypeParamBound::Trait(bound)) 777fad3a1d3Sopenharmony_ci } 778fad3a1d3Sopenharmony_ci } 779fad3a1d3Sopenharmony_ci } 780fad3a1d3Sopenharmony_ci 781fad3a1d3Sopenharmony_ci impl TypeParamBound { 782fad3a1d3Sopenharmony_ci pub(crate) fn parse_multiple( 783fad3a1d3Sopenharmony_ci input: ParseStream, 784fad3a1d3Sopenharmony_ci allow_plus: bool, 785fad3a1d3Sopenharmony_ci ) -> Result<Punctuated<Self, Token![+]>> { 786fad3a1d3Sopenharmony_ci let mut bounds = Punctuated::new(); 787fad3a1d3Sopenharmony_ci loop { 788fad3a1d3Sopenharmony_ci bounds.push_value(input.parse()?); 789fad3a1d3Sopenharmony_ci if !(allow_plus && input.peek(Token![+])) { 790fad3a1d3Sopenharmony_ci break; 791fad3a1d3Sopenharmony_ci } 792fad3a1d3Sopenharmony_ci bounds.push_punct(input.parse()?); 793fad3a1d3Sopenharmony_ci if !(input.peek(Ident::peek_any) 794fad3a1d3Sopenharmony_ci || input.peek(Token![::]) 795fad3a1d3Sopenharmony_ci || input.peek(Token![?]) 796fad3a1d3Sopenharmony_ci || input.peek(Lifetime) 797fad3a1d3Sopenharmony_ci || input.peek(token::Paren) 798fad3a1d3Sopenharmony_ci || input.peek(Token![~])) 799fad3a1d3Sopenharmony_ci { 800fad3a1d3Sopenharmony_ci break; 801fad3a1d3Sopenharmony_ci } 802fad3a1d3Sopenharmony_ci } 803fad3a1d3Sopenharmony_ci Ok(bounds) 804fad3a1d3Sopenharmony_ci } 805fad3a1d3Sopenharmony_ci } 806fad3a1d3Sopenharmony_ci 807fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 808fad3a1d3Sopenharmony_ci impl Parse for TraitBound { 809fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 810fad3a1d3Sopenharmony_ci let modifier: TraitBoundModifier = input.parse()?; 811fad3a1d3Sopenharmony_ci let lifetimes: Option<BoundLifetimes> = input.parse()?; 812fad3a1d3Sopenharmony_ci 813fad3a1d3Sopenharmony_ci let mut path: Path = input.parse()?; 814fad3a1d3Sopenharmony_ci if path.segments.last().unwrap().arguments.is_empty() 815fad3a1d3Sopenharmony_ci && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren)) 816fad3a1d3Sopenharmony_ci { 817fad3a1d3Sopenharmony_ci input.parse::<Option<Token![::]>>()?; 818fad3a1d3Sopenharmony_ci let args: ParenthesizedGenericArguments = input.parse()?; 819fad3a1d3Sopenharmony_ci let parenthesized = PathArguments::Parenthesized(args); 820fad3a1d3Sopenharmony_ci path.segments.last_mut().unwrap().arguments = parenthesized; 821fad3a1d3Sopenharmony_ci } 822fad3a1d3Sopenharmony_ci 823fad3a1d3Sopenharmony_ci Ok(TraitBound { 824fad3a1d3Sopenharmony_ci paren_token: None, 825fad3a1d3Sopenharmony_ci modifier, 826fad3a1d3Sopenharmony_ci lifetimes, 827fad3a1d3Sopenharmony_ci path, 828fad3a1d3Sopenharmony_ci }) 829fad3a1d3Sopenharmony_ci } 830fad3a1d3Sopenharmony_ci } 831fad3a1d3Sopenharmony_ci 832fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 833fad3a1d3Sopenharmony_ci impl Parse for TraitBoundModifier { 834fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 835fad3a1d3Sopenharmony_ci if input.peek(Token![?]) { 836fad3a1d3Sopenharmony_ci input.parse().map(TraitBoundModifier::Maybe) 837fad3a1d3Sopenharmony_ci } else { 838fad3a1d3Sopenharmony_ci Ok(TraitBoundModifier::None) 839fad3a1d3Sopenharmony_ci } 840fad3a1d3Sopenharmony_ci } 841fad3a1d3Sopenharmony_ci } 842fad3a1d3Sopenharmony_ci 843fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 844fad3a1d3Sopenharmony_ci impl Parse for ConstParam { 845fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 846fad3a1d3Sopenharmony_ci let mut default = None; 847fad3a1d3Sopenharmony_ci Ok(ConstParam { 848fad3a1d3Sopenharmony_ci attrs: input.call(Attribute::parse_outer)?, 849fad3a1d3Sopenharmony_ci const_token: input.parse()?, 850fad3a1d3Sopenharmony_ci ident: input.parse()?, 851fad3a1d3Sopenharmony_ci colon_token: input.parse()?, 852fad3a1d3Sopenharmony_ci ty: input.parse()?, 853fad3a1d3Sopenharmony_ci eq_token: { 854fad3a1d3Sopenharmony_ci if input.peek(Token![=]) { 855fad3a1d3Sopenharmony_ci let eq_token = input.parse()?; 856fad3a1d3Sopenharmony_ci default = Some(path::parsing::const_argument(input)?); 857fad3a1d3Sopenharmony_ci Some(eq_token) 858fad3a1d3Sopenharmony_ci } else { 859fad3a1d3Sopenharmony_ci None 860fad3a1d3Sopenharmony_ci } 861fad3a1d3Sopenharmony_ci }, 862fad3a1d3Sopenharmony_ci default, 863fad3a1d3Sopenharmony_ci }) 864fad3a1d3Sopenharmony_ci } 865fad3a1d3Sopenharmony_ci } 866fad3a1d3Sopenharmony_ci 867fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 868fad3a1d3Sopenharmony_ci impl Parse for WhereClause { 869fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 870fad3a1d3Sopenharmony_ci Ok(WhereClause { 871fad3a1d3Sopenharmony_ci where_token: input.parse()?, 872fad3a1d3Sopenharmony_ci predicates: { 873fad3a1d3Sopenharmony_ci let mut predicates = Punctuated::new(); 874fad3a1d3Sopenharmony_ci loop { 875fad3a1d3Sopenharmony_ci if input.is_empty() 876fad3a1d3Sopenharmony_ci || input.peek(token::Brace) 877fad3a1d3Sopenharmony_ci || input.peek(Token![,]) 878fad3a1d3Sopenharmony_ci || input.peek(Token![;]) 879fad3a1d3Sopenharmony_ci || input.peek(Token![:]) && !input.peek(Token![::]) 880fad3a1d3Sopenharmony_ci || input.peek(Token![=]) 881fad3a1d3Sopenharmony_ci { 882fad3a1d3Sopenharmony_ci break; 883fad3a1d3Sopenharmony_ci } 884fad3a1d3Sopenharmony_ci let value = input.parse()?; 885fad3a1d3Sopenharmony_ci predicates.push_value(value); 886fad3a1d3Sopenharmony_ci if !input.peek(Token![,]) { 887fad3a1d3Sopenharmony_ci break; 888fad3a1d3Sopenharmony_ci } 889fad3a1d3Sopenharmony_ci let punct = input.parse()?; 890fad3a1d3Sopenharmony_ci predicates.push_punct(punct); 891fad3a1d3Sopenharmony_ci } 892fad3a1d3Sopenharmony_ci predicates 893fad3a1d3Sopenharmony_ci }, 894fad3a1d3Sopenharmony_ci }) 895fad3a1d3Sopenharmony_ci } 896fad3a1d3Sopenharmony_ci } 897fad3a1d3Sopenharmony_ci 898fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 899fad3a1d3Sopenharmony_ci impl Parse for Option<WhereClause> { 900fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 901fad3a1d3Sopenharmony_ci if input.peek(Token![where]) { 902fad3a1d3Sopenharmony_ci input.parse().map(Some) 903fad3a1d3Sopenharmony_ci } else { 904fad3a1d3Sopenharmony_ci Ok(None) 905fad3a1d3Sopenharmony_ci } 906fad3a1d3Sopenharmony_ci } 907fad3a1d3Sopenharmony_ci } 908fad3a1d3Sopenharmony_ci 909fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 910fad3a1d3Sopenharmony_ci impl Parse for WherePredicate { 911fad3a1d3Sopenharmony_ci fn parse(input: ParseStream) -> Result<Self> { 912fad3a1d3Sopenharmony_ci if input.peek(Lifetime) && input.peek2(Token![:]) { 913fad3a1d3Sopenharmony_ci Ok(WherePredicate::Lifetime(PredicateLifetime { 914fad3a1d3Sopenharmony_ci lifetime: input.parse()?, 915fad3a1d3Sopenharmony_ci colon_token: input.parse()?, 916fad3a1d3Sopenharmony_ci bounds: { 917fad3a1d3Sopenharmony_ci let mut bounds = Punctuated::new(); 918fad3a1d3Sopenharmony_ci loop { 919fad3a1d3Sopenharmony_ci if input.is_empty() 920fad3a1d3Sopenharmony_ci || input.peek(token::Brace) 921fad3a1d3Sopenharmony_ci || input.peek(Token![,]) 922fad3a1d3Sopenharmony_ci || input.peek(Token![;]) 923fad3a1d3Sopenharmony_ci || input.peek(Token![:]) 924fad3a1d3Sopenharmony_ci || input.peek(Token![=]) 925fad3a1d3Sopenharmony_ci { 926fad3a1d3Sopenharmony_ci break; 927fad3a1d3Sopenharmony_ci } 928fad3a1d3Sopenharmony_ci let value = input.parse()?; 929fad3a1d3Sopenharmony_ci bounds.push_value(value); 930fad3a1d3Sopenharmony_ci if !input.peek(Token![+]) { 931fad3a1d3Sopenharmony_ci break; 932fad3a1d3Sopenharmony_ci } 933fad3a1d3Sopenharmony_ci let punct = input.parse()?; 934fad3a1d3Sopenharmony_ci bounds.push_punct(punct); 935fad3a1d3Sopenharmony_ci } 936fad3a1d3Sopenharmony_ci bounds 937fad3a1d3Sopenharmony_ci }, 938fad3a1d3Sopenharmony_ci })) 939fad3a1d3Sopenharmony_ci } else { 940fad3a1d3Sopenharmony_ci Ok(WherePredicate::Type(PredicateType { 941fad3a1d3Sopenharmony_ci lifetimes: input.parse()?, 942fad3a1d3Sopenharmony_ci bounded_ty: input.parse()?, 943fad3a1d3Sopenharmony_ci colon_token: input.parse()?, 944fad3a1d3Sopenharmony_ci bounds: { 945fad3a1d3Sopenharmony_ci let mut bounds = Punctuated::new(); 946fad3a1d3Sopenharmony_ci loop { 947fad3a1d3Sopenharmony_ci if input.is_empty() 948fad3a1d3Sopenharmony_ci || input.peek(token::Brace) 949fad3a1d3Sopenharmony_ci || input.peek(Token![,]) 950fad3a1d3Sopenharmony_ci || input.peek(Token![;]) 951fad3a1d3Sopenharmony_ci || input.peek(Token![:]) && !input.peek(Token![::]) 952fad3a1d3Sopenharmony_ci || input.peek(Token![=]) 953fad3a1d3Sopenharmony_ci { 954fad3a1d3Sopenharmony_ci break; 955fad3a1d3Sopenharmony_ci } 956fad3a1d3Sopenharmony_ci let value = input.parse()?; 957fad3a1d3Sopenharmony_ci bounds.push_value(value); 958fad3a1d3Sopenharmony_ci if !input.peek(Token![+]) { 959fad3a1d3Sopenharmony_ci break; 960fad3a1d3Sopenharmony_ci } 961fad3a1d3Sopenharmony_ci let punct = input.parse()?; 962fad3a1d3Sopenharmony_ci bounds.push_punct(punct); 963fad3a1d3Sopenharmony_ci } 964fad3a1d3Sopenharmony_ci bounds 965fad3a1d3Sopenharmony_ci }, 966fad3a1d3Sopenharmony_ci })) 967fad3a1d3Sopenharmony_ci } 968fad3a1d3Sopenharmony_ci } 969fad3a1d3Sopenharmony_ci } 970fad3a1d3Sopenharmony_ci} 971fad3a1d3Sopenharmony_ci 972fad3a1d3Sopenharmony_ci#[cfg(feature = "printing")] 973fad3a1d3Sopenharmony_cimod printing { 974fad3a1d3Sopenharmony_ci use super::*; 975fad3a1d3Sopenharmony_ci use crate::attr::FilterAttrs; 976fad3a1d3Sopenharmony_ci use crate::print::TokensOrDefault; 977fad3a1d3Sopenharmony_ci use proc_macro2::TokenStream; 978fad3a1d3Sopenharmony_ci use quote::{ToTokens, TokenStreamExt}; 979fad3a1d3Sopenharmony_ci 980fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 981fad3a1d3Sopenharmony_ci impl ToTokens for Generics { 982fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 983fad3a1d3Sopenharmony_ci if self.params.is_empty() { 984fad3a1d3Sopenharmony_ci return; 985fad3a1d3Sopenharmony_ci } 986fad3a1d3Sopenharmony_ci 987fad3a1d3Sopenharmony_ci TokensOrDefault(&self.lt_token).to_tokens(tokens); 988fad3a1d3Sopenharmony_ci 989fad3a1d3Sopenharmony_ci // Print lifetimes before types and consts, regardless of their 990fad3a1d3Sopenharmony_ci // order in self.params. 991fad3a1d3Sopenharmony_ci let mut trailing_or_empty = true; 992fad3a1d3Sopenharmony_ci for param in self.params.pairs() { 993fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(_) = **param.value() { 994fad3a1d3Sopenharmony_ci param.to_tokens(tokens); 995fad3a1d3Sopenharmony_ci trailing_or_empty = param.punct().is_some(); 996fad3a1d3Sopenharmony_ci } 997fad3a1d3Sopenharmony_ci } 998fad3a1d3Sopenharmony_ci for param in self.params.pairs() { 999fad3a1d3Sopenharmony_ci match param.value() { 1000fad3a1d3Sopenharmony_ci GenericParam::Type(_) | GenericParam::Const(_) => { 1001fad3a1d3Sopenharmony_ci if !trailing_or_empty { 1002fad3a1d3Sopenharmony_ci <Token![,]>::default().to_tokens(tokens); 1003fad3a1d3Sopenharmony_ci trailing_or_empty = true; 1004fad3a1d3Sopenharmony_ci } 1005fad3a1d3Sopenharmony_ci param.to_tokens(tokens); 1006fad3a1d3Sopenharmony_ci } 1007fad3a1d3Sopenharmony_ci GenericParam::Lifetime(_) => {} 1008fad3a1d3Sopenharmony_ci } 1009fad3a1d3Sopenharmony_ci } 1010fad3a1d3Sopenharmony_ci 1011fad3a1d3Sopenharmony_ci TokensOrDefault(&self.gt_token).to_tokens(tokens); 1012fad3a1d3Sopenharmony_ci } 1013fad3a1d3Sopenharmony_ci } 1014fad3a1d3Sopenharmony_ci 1015fad3a1d3Sopenharmony_ci impl<'a> ToTokens for ImplGenerics<'a> { 1016fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1017fad3a1d3Sopenharmony_ci if self.0.params.is_empty() { 1018fad3a1d3Sopenharmony_ci return; 1019fad3a1d3Sopenharmony_ci } 1020fad3a1d3Sopenharmony_ci 1021fad3a1d3Sopenharmony_ci TokensOrDefault(&self.0.lt_token).to_tokens(tokens); 1022fad3a1d3Sopenharmony_ci 1023fad3a1d3Sopenharmony_ci // Print lifetimes before types and consts, regardless of their 1024fad3a1d3Sopenharmony_ci // order in self.params. 1025fad3a1d3Sopenharmony_ci let mut trailing_or_empty = true; 1026fad3a1d3Sopenharmony_ci for param in self.0.params.pairs() { 1027fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(_) = **param.value() { 1028fad3a1d3Sopenharmony_ci param.to_tokens(tokens); 1029fad3a1d3Sopenharmony_ci trailing_or_empty = param.punct().is_some(); 1030fad3a1d3Sopenharmony_ci } 1031fad3a1d3Sopenharmony_ci } 1032fad3a1d3Sopenharmony_ci for param in self.0.params.pairs() { 1033fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(_) = **param.value() { 1034fad3a1d3Sopenharmony_ci continue; 1035fad3a1d3Sopenharmony_ci } 1036fad3a1d3Sopenharmony_ci if !trailing_or_empty { 1037fad3a1d3Sopenharmony_ci <Token![,]>::default().to_tokens(tokens); 1038fad3a1d3Sopenharmony_ci trailing_or_empty = true; 1039fad3a1d3Sopenharmony_ci } 1040fad3a1d3Sopenharmony_ci match param.value() { 1041fad3a1d3Sopenharmony_ci GenericParam::Lifetime(_) => unreachable!(), 1042fad3a1d3Sopenharmony_ci GenericParam::Type(param) => { 1043fad3a1d3Sopenharmony_ci // Leave off the type parameter defaults 1044fad3a1d3Sopenharmony_ci tokens.append_all(param.attrs.outer()); 1045fad3a1d3Sopenharmony_ci param.ident.to_tokens(tokens); 1046fad3a1d3Sopenharmony_ci if !param.bounds.is_empty() { 1047fad3a1d3Sopenharmony_ci TokensOrDefault(¶m.colon_token).to_tokens(tokens); 1048fad3a1d3Sopenharmony_ci param.bounds.to_tokens(tokens); 1049fad3a1d3Sopenharmony_ci } 1050fad3a1d3Sopenharmony_ci } 1051fad3a1d3Sopenharmony_ci GenericParam::Const(param) => { 1052fad3a1d3Sopenharmony_ci // Leave off the const parameter defaults 1053fad3a1d3Sopenharmony_ci tokens.append_all(param.attrs.outer()); 1054fad3a1d3Sopenharmony_ci param.const_token.to_tokens(tokens); 1055fad3a1d3Sopenharmony_ci param.ident.to_tokens(tokens); 1056fad3a1d3Sopenharmony_ci param.colon_token.to_tokens(tokens); 1057fad3a1d3Sopenharmony_ci param.ty.to_tokens(tokens); 1058fad3a1d3Sopenharmony_ci } 1059fad3a1d3Sopenharmony_ci } 1060fad3a1d3Sopenharmony_ci param.punct().to_tokens(tokens); 1061fad3a1d3Sopenharmony_ci } 1062fad3a1d3Sopenharmony_ci 1063fad3a1d3Sopenharmony_ci TokensOrDefault(&self.0.gt_token).to_tokens(tokens); 1064fad3a1d3Sopenharmony_ci } 1065fad3a1d3Sopenharmony_ci } 1066fad3a1d3Sopenharmony_ci 1067fad3a1d3Sopenharmony_ci impl<'a> ToTokens for TypeGenerics<'a> { 1068fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1069fad3a1d3Sopenharmony_ci if self.0.params.is_empty() { 1070fad3a1d3Sopenharmony_ci return; 1071fad3a1d3Sopenharmony_ci } 1072fad3a1d3Sopenharmony_ci 1073fad3a1d3Sopenharmony_ci TokensOrDefault(&self.0.lt_token).to_tokens(tokens); 1074fad3a1d3Sopenharmony_ci 1075fad3a1d3Sopenharmony_ci // Print lifetimes before types and consts, regardless of their 1076fad3a1d3Sopenharmony_ci // order in self.params. 1077fad3a1d3Sopenharmony_ci let mut trailing_or_empty = true; 1078fad3a1d3Sopenharmony_ci for param in self.0.params.pairs() { 1079fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(def) = *param.value() { 1080fad3a1d3Sopenharmony_ci // Leave off the lifetime bounds and attributes 1081fad3a1d3Sopenharmony_ci def.lifetime.to_tokens(tokens); 1082fad3a1d3Sopenharmony_ci param.punct().to_tokens(tokens); 1083fad3a1d3Sopenharmony_ci trailing_or_empty = param.punct().is_some(); 1084fad3a1d3Sopenharmony_ci } 1085fad3a1d3Sopenharmony_ci } 1086fad3a1d3Sopenharmony_ci for param in self.0.params.pairs() { 1087fad3a1d3Sopenharmony_ci if let GenericParam::Lifetime(_) = **param.value() { 1088fad3a1d3Sopenharmony_ci continue; 1089fad3a1d3Sopenharmony_ci } 1090fad3a1d3Sopenharmony_ci if !trailing_or_empty { 1091fad3a1d3Sopenharmony_ci <Token![,]>::default().to_tokens(tokens); 1092fad3a1d3Sopenharmony_ci trailing_or_empty = true; 1093fad3a1d3Sopenharmony_ci } 1094fad3a1d3Sopenharmony_ci match param.value() { 1095fad3a1d3Sopenharmony_ci GenericParam::Lifetime(_) => unreachable!(), 1096fad3a1d3Sopenharmony_ci GenericParam::Type(param) => { 1097fad3a1d3Sopenharmony_ci // Leave off the type parameter defaults 1098fad3a1d3Sopenharmony_ci param.ident.to_tokens(tokens); 1099fad3a1d3Sopenharmony_ci } 1100fad3a1d3Sopenharmony_ci GenericParam::Const(param) => { 1101fad3a1d3Sopenharmony_ci // Leave off the const parameter defaults 1102fad3a1d3Sopenharmony_ci param.ident.to_tokens(tokens); 1103fad3a1d3Sopenharmony_ci } 1104fad3a1d3Sopenharmony_ci } 1105fad3a1d3Sopenharmony_ci param.punct().to_tokens(tokens); 1106fad3a1d3Sopenharmony_ci } 1107fad3a1d3Sopenharmony_ci 1108fad3a1d3Sopenharmony_ci TokensOrDefault(&self.0.gt_token).to_tokens(tokens); 1109fad3a1d3Sopenharmony_ci } 1110fad3a1d3Sopenharmony_ci } 1111fad3a1d3Sopenharmony_ci 1112fad3a1d3Sopenharmony_ci impl<'a> ToTokens for Turbofish<'a> { 1113fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1114fad3a1d3Sopenharmony_ci if !self.0.params.is_empty() { 1115fad3a1d3Sopenharmony_ci <Token![::]>::default().to_tokens(tokens); 1116fad3a1d3Sopenharmony_ci TypeGenerics(self.0).to_tokens(tokens); 1117fad3a1d3Sopenharmony_ci } 1118fad3a1d3Sopenharmony_ci } 1119fad3a1d3Sopenharmony_ci } 1120fad3a1d3Sopenharmony_ci 1121fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1122fad3a1d3Sopenharmony_ci impl ToTokens for BoundLifetimes { 1123fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1124fad3a1d3Sopenharmony_ci self.for_token.to_tokens(tokens); 1125fad3a1d3Sopenharmony_ci self.lt_token.to_tokens(tokens); 1126fad3a1d3Sopenharmony_ci self.lifetimes.to_tokens(tokens); 1127fad3a1d3Sopenharmony_ci self.gt_token.to_tokens(tokens); 1128fad3a1d3Sopenharmony_ci } 1129fad3a1d3Sopenharmony_ci } 1130fad3a1d3Sopenharmony_ci 1131fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1132fad3a1d3Sopenharmony_ci impl ToTokens for LifetimeParam { 1133fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1134fad3a1d3Sopenharmony_ci tokens.append_all(self.attrs.outer()); 1135fad3a1d3Sopenharmony_ci self.lifetime.to_tokens(tokens); 1136fad3a1d3Sopenharmony_ci if !self.bounds.is_empty() { 1137fad3a1d3Sopenharmony_ci TokensOrDefault(&self.colon_token).to_tokens(tokens); 1138fad3a1d3Sopenharmony_ci self.bounds.to_tokens(tokens); 1139fad3a1d3Sopenharmony_ci } 1140fad3a1d3Sopenharmony_ci } 1141fad3a1d3Sopenharmony_ci } 1142fad3a1d3Sopenharmony_ci 1143fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1144fad3a1d3Sopenharmony_ci impl ToTokens for TypeParam { 1145fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1146fad3a1d3Sopenharmony_ci tokens.append_all(self.attrs.outer()); 1147fad3a1d3Sopenharmony_ci self.ident.to_tokens(tokens); 1148fad3a1d3Sopenharmony_ci if !self.bounds.is_empty() { 1149fad3a1d3Sopenharmony_ci TokensOrDefault(&self.colon_token).to_tokens(tokens); 1150fad3a1d3Sopenharmony_ci self.bounds.to_tokens(tokens); 1151fad3a1d3Sopenharmony_ci } 1152fad3a1d3Sopenharmony_ci if let Some(default) = &self.default { 1153fad3a1d3Sopenharmony_ci TokensOrDefault(&self.eq_token).to_tokens(tokens); 1154fad3a1d3Sopenharmony_ci default.to_tokens(tokens); 1155fad3a1d3Sopenharmony_ci } 1156fad3a1d3Sopenharmony_ci } 1157fad3a1d3Sopenharmony_ci } 1158fad3a1d3Sopenharmony_ci 1159fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1160fad3a1d3Sopenharmony_ci impl ToTokens for TraitBound { 1161fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1162fad3a1d3Sopenharmony_ci let to_tokens = |tokens: &mut TokenStream| { 1163fad3a1d3Sopenharmony_ci self.modifier.to_tokens(tokens); 1164fad3a1d3Sopenharmony_ci self.lifetimes.to_tokens(tokens); 1165fad3a1d3Sopenharmony_ci self.path.to_tokens(tokens); 1166fad3a1d3Sopenharmony_ci }; 1167fad3a1d3Sopenharmony_ci match &self.paren_token { 1168fad3a1d3Sopenharmony_ci Some(paren) => paren.surround(tokens, to_tokens), 1169fad3a1d3Sopenharmony_ci None => to_tokens(tokens), 1170fad3a1d3Sopenharmony_ci } 1171fad3a1d3Sopenharmony_ci } 1172fad3a1d3Sopenharmony_ci } 1173fad3a1d3Sopenharmony_ci 1174fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1175fad3a1d3Sopenharmony_ci impl ToTokens for TraitBoundModifier { 1176fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1177fad3a1d3Sopenharmony_ci match self { 1178fad3a1d3Sopenharmony_ci TraitBoundModifier::None => {} 1179fad3a1d3Sopenharmony_ci TraitBoundModifier::Maybe(t) => t.to_tokens(tokens), 1180fad3a1d3Sopenharmony_ci } 1181fad3a1d3Sopenharmony_ci } 1182fad3a1d3Sopenharmony_ci } 1183fad3a1d3Sopenharmony_ci 1184fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1185fad3a1d3Sopenharmony_ci impl ToTokens for ConstParam { 1186fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1187fad3a1d3Sopenharmony_ci tokens.append_all(self.attrs.outer()); 1188fad3a1d3Sopenharmony_ci self.const_token.to_tokens(tokens); 1189fad3a1d3Sopenharmony_ci self.ident.to_tokens(tokens); 1190fad3a1d3Sopenharmony_ci self.colon_token.to_tokens(tokens); 1191fad3a1d3Sopenharmony_ci self.ty.to_tokens(tokens); 1192fad3a1d3Sopenharmony_ci if let Some(default) = &self.default { 1193fad3a1d3Sopenharmony_ci TokensOrDefault(&self.eq_token).to_tokens(tokens); 1194fad3a1d3Sopenharmony_ci default.to_tokens(tokens); 1195fad3a1d3Sopenharmony_ci } 1196fad3a1d3Sopenharmony_ci } 1197fad3a1d3Sopenharmony_ci } 1198fad3a1d3Sopenharmony_ci 1199fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1200fad3a1d3Sopenharmony_ci impl ToTokens for WhereClause { 1201fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1202fad3a1d3Sopenharmony_ci if !self.predicates.is_empty() { 1203fad3a1d3Sopenharmony_ci self.where_token.to_tokens(tokens); 1204fad3a1d3Sopenharmony_ci self.predicates.to_tokens(tokens); 1205fad3a1d3Sopenharmony_ci } 1206fad3a1d3Sopenharmony_ci } 1207fad3a1d3Sopenharmony_ci } 1208fad3a1d3Sopenharmony_ci 1209fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1210fad3a1d3Sopenharmony_ci impl ToTokens for PredicateLifetime { 1211fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1212fad3a1d3Sopenharmony_ci self.lifetime.to_tokens(tokens); 1213fad3a1d3Sopenharmony_ci self.colon_token.to_tokens(tokens); 1214fad3a1d3Sopenharmony_ci self.bounds.to_tokens(tokens); 1215fad3a1d3Sopenharmony_ci } 1216fad3a1d3Sopenharmony_ci } 1217fad3a1d3Sopenharmony_ci 1218fad3a1d3Sopenharmony_ci #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1219fad3a1d3Sopenharmony_ci impl ToTokens for PredicateType { 1220fad3a1d3Sopenharmony_ci fn to_tokens(&self, tokens: &mut TokenStream) { 1221fad3a1d3Sopenharmony_ci self.lifetimes.to_tokens(tokens); 1222fad3a1d3Sopenharmony_ci self.bounded_ty.to_tokens(tokens); 1223fad3a1d3Sopenharmony_ci self.colon_token.to_tokens(tokens); 1224fad3a1d3Sopenharmony_ci self.bounds.to_tokens(tokens); 1225fad3a1d3Sopenharmony_ci } 1226fad3a1d3Sopenharmony_ci } 1227fad3a1d3Sopenharmony_ci} 1228