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