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