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