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