1 use super::*; 2 use crate::punctuated::Punctuated; 3 #[cfg(feature = "extra-traits")] 4 use crate::tt::TokenStreamHelper; 5 use proc_macro2::TokenStream; 6 #[cfg(feature = "extra-traits")] 7 use std::hash::{Hash, Hasher}; 8 9 ast_enum_of_structs! { 10 /// The possible types that a Rust value could have. 11 /// 12 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 13 /// feature.* 14 /// 15 /// # Syntax tree enum 16 /// 17 /// This type is a [syntax tree enum]. 18 /// 19 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums 20 // 21 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently 22 // blocked on https://github.com/rust-lang/rust/issues/62833 23 pub enum Type #manual_extra_traits { 24 /// A fixed size array type: `[T; n]`. 25 Array(TypeArray), 26 27 /// A bare function type: `fn(usize) -> bool`. 28 BareFn(TypeBareFn), 29 30 /// A type contained within invisible delimiters. 31 Group(TypeGroup), 32 33 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or 34 /// a lifetime. 35 ImplTrait(TypeImplTrait), 36 37 /// Indication that a type should be inferred by the compiler: `_`. 38 Infer(TypeInfer), 39 40 /// A macro in the type position. 41 Macro(TypeMacro), 42 43 /// The never type: `!`. 44 Never(TypeNever), 45 46 /// A parenthesized type equivalent to the inner type. 47 Paren(TypeParen), 48 49 /// A path like `std::slice::Iter`, optionally qualified with a 50 /// self-type as in `<Vec<T> as SomeTrait>::Associated`. 51 Path(TypePath), 52 53 /// A raw pointer type: `*const T` or `*mut T`. 54 Ptr(TypePtr), 55 56 /// A reference type: `&'a T` or `&'a mut T`. 57 Reference(TypeReference), 58 59 /// A dynamically sized slice type: `[T]`. 60 Slice(TypeSlice), 61 62 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a 63 /// trait or a lifetime. 64 TraitObject(TypeTraitObject), 65 66 /// A tuple type: `(A, B, C, String)`. 67 Tuple(TypeTuple), 68 69 /// Tokens in type position not interpreted by Syn. 70 Verbatim(TokenStream), 71 72 #[doc(hidden)] 73 __Nonexhaustive, 74 } 75 } 76 77 ast_struct! { 78 /// A fixed size array type: `[T; n]`. 79 /// 80 /// *This type is available only if Syn is built with the `"derive"` or 81 /// `"full"` feature.* 82 pub struct TypeArray { 83 pub bracket_token: token::Bracket, 84 pub elem: Box<Type>, 85 pub semi_token: Token![;], 86 pub len: Expr, 87 } 88 } 89 90 ast_struct! { 91 /// A bare function type: `fn(usize) -> bool`. 92 /// 93 /// *This type is available only if Syn is built with the `"derive"` or 94 /// `"full"` feature.* 95 pub struct TypeBareFn { 96 pub lifetimes: Option<BoundLifetimes>, 97 pub unsafety: Option<Token![unsafe]>, 98 pub abi: Option<Abi>, 99 pub fn_token: Token![fn], 100 pub paren_token: token::Paren, 101 pub inputs: Punctuated<BareFnArg, Token![,]>, 102 pub variadic: Option<Variadic>, 103 pub output: ReturnType, 104 } 105 } 106 107 ast_struct! { 108 /// A type contained within invisible delimiters. 109 /// 110 /// *This type is available only if Syn is built with the `"derive"` or 111 /// `"full"` feature.* 112 pub struct TypeGroup { 113 pub group_token: token::Group, 114 pub elem: Box<Type>, 115 } 116 } 117 118 ast_struct! { 119 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or 120 /// a lifetime. 121 /// 122 /// *This type is available only if Syn is built with the `"derive"` or 123 /// `"full"` feature.* 124 pub struct TypeImplTrait { 125 pub impl_token: Token![impl], 126 pub bounds: Punctuated<TypeParamBound, Token![+]>, 127 } 128 } 129 130 ast_struct! { 131 /// Indication that a type should be inferred by the compiler: `_`. 132 /// 133 /// *This type is available only if Syn is built with the `"derive"` or 134 /// `"full"` feature.* 135 pub struct TypeInfer { 136 pub underscore_token: Token![_], 137 } 138 } 139 140 ast_struct! { 141 /// A macro in the type position. 142 /// 143 /// *This type is available only if Syn is built with the `"derive"` or 144 /// `"full"` feature.* 145 pub struct TypeMacro { 146 pub mac: Macro, 147 } 148 } 149 150 ast_struct! { 151 /// The never type: `!`. 152 /// 153 /// *This type is available only if Syn is built with the `"derive"` or 154 /// `"full"` feature.* 155 pub struct TypeNever { 156 pub bang_token: Token![!], 157 } 158 } 159 160 ast_struct! { 161 /// A parenthesized type equivalent to the inner type. 162 /// 163 /// *This type is available only if Syn is built with the `"derive"` or 164 /// `"full"` feature.* 165 pub struct TypeParen { 166 pub paren_token: token::Paren, 167 pub elem: Box<Type>, 168 } 169 } 170 171 ast_struct! { 172 /// A path like `std::slice::Iter`, optionally qualified with a 173 /// self-type as in `<Vec<T> as SomeTrait>::Associated`. 174 /// 175 /// *This type is available only if Syn is built with the `"derive"` or 176 /// `"full"` feature.* 177 pub struct TypePath { 178 pub qself: Option<QSelf>, 179 pub path: Path, 180 } 181 } 182 183 ast_struct! { 184 /// A raw pointer type: `*const T` or `*mut T`. 185 /// 186 /// *This type is available only if Syn is built with the `"derive"` or 187 /// `"full"` feature.* 188 pub struct TypePtr { 189 pub star_token: Token![*], 190 pub const_token: Option<Token![const]>, 191 pub mutability: Option<Token![mut]>, 192 pub elem: Box<Type>, 193 } 194 } 195 196 ast_struct! { 197 /// A reference type: `&'a T` or `&'a mut T`. 198 /// 199 /// *This type is available only if Syn is built with the `"derive"` or 200 /// `"full"` feature.* 201 pub struct TypeReference { 202 pub and_token: Token![&], 203 pub lifetime: Option<Lifetime>, 204 pub mutability: Option<Token![mut]>, 205 pub elem: Box<Type>, 206 } 207 } 208 209 ast_struct! { 210 /// A dynamically sized slice type: `[T]`. 211 /// 212 /// *This type is available only if Syn is built with the `"derive"` or 213 /// `"full"` feature.* 214 pub struct TypeSlice { 215 pub bracket_token: token::Bracket, 216 pub elem: Box<Type>, 217 } 218 } 219 220 ast_struct! { 221 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a 222 /// trait or a lifetime. 223 /// 224 /// *This type is available only if Syn is built with the `"derive"` or 225 /// `"full"` feature.* 226 pub struct TypeTraitObject { 227 pub dyn_token: Option<Token![dyn]>, 228 pub bounds: Punctuated<TypeParamBound, Token![+]>, 229 } 230 } 231 232 ast_struct! { 233 /// A tuple type: `(A, B, C, String)`. 234 /// 235 /// *This type is available only if Syn is built with the `"derive"` or 236 /// `"full"` feature.* 237 pub struct TypeTuple { 238 pub paren_token: token::Paren, 239 pub elems: Punctuated<Type, Token![,]>, 240 } 241 } 242 243 #[cfg(feature = "extra-traits")] 244 impl Eq for Type {} 245 246 #[cfg(feature = "extra-traits")] 247 impl PartialEq for Type { eq(&self, other: &Self) -> bool248 fn eq(&self, other: &Self) -> bool { 249 match (self, other) { 250 (Type::Array(this), Type::Array(other)) => this == other, 251 (Type::BareFn(this), Type::BareFn(other)) => this == other, 252 (Type::Group(this), Type::Group(other)) => this == other, 253 (Type::ImplTrait(this), Type::ImplTrait(other)) => this == other, 254 (Type::Infer(this), Type::Infer(other)) => this == other, 255 (Type::Macro(this), Type::Macro(other)) => this == other, 256 (Type::Never(this), Type::Never(other)) => this == other, 257 (Type::Paren(this), Type::Paren(other)) => this == other, 258 (Type::Path(this), Type::Path(other)) => this == other, 259 (Type::Ptr(this), Type::Ptr(other)) => this == other, 260 (Type::Reference(this), Type::Reference(other)) => this == other, 261 (Type::Slice(this), Type::Slice(other)) => this == other, 262 (Type::TraitObject(this), Type::TraitObject(other)) => this == other, 263 (Type::Tuple(this), Type::Tuple(other)) => this == other, 264 (Type::Verbatim(this), Type::Verbatim(other)) => { 265 TokenStreamHelper(this) == TokenStreamHelper(other) 266 } 267 _ => false, 268 } 269 } 270 } 271 272 #[cfg(feature = "extra-traits")] 273 impl Hash for Type { hash<H>(&self, hash: &mut H) where H: Hasher,274 fn hash<H>(&self, hash: &mut H) 275 where 276 H: Hasher, 277 { 278 match self { 279 Type::Array(ty) => { 280 hash.write_u8(0); 281 ty.hash(hash); 282 } 283 Type::BareFn(ty) => { 284 hash.write_u8(1); 285 ty.hash(hash); 286 } 287 Type::Group(ty) => { 288 hash.write_u8(2); 289 ty.hash(hash); 290 } 291 Type::ImplTrait(ty) => { 292 hash.write_u8(3); 293 ty.hash(hash); 294 } 295 Type::Infer(ty) => { 296 hash.write_u8(4); 297 ty.hash(hash); 298 } 299 Type::Macro(ty) => { 300 hash.write_u8(5); 301 ty.hash(hash); 302 } 303 Type::Never(ty) => { 304 hash.write_u8(6); 305 ty.hash(hash); 306 } 307 Type::Paren(ty) => { 308 hash.write_u8(7); 309 ty.hash(hash); 310 } 311 Type::Path(ty) => { 312 hash.write_u8(8); 313 ty.hash(hash); 314 } 315 Type::Ptr(ty) => { 316 hash.write_u8(9); 317 ty.hash(hash); 318 } 319 Type::Reference(ty) => { 320 hash.write_u8(10); 321 ty.hash(hash); 322 } 323 Type::Slice(ty) => { 324 hash.write_u8(11); 325 ty.hash(hash); 326 } 327 Type::TraitObject(ty) => { 328 hash.write_u8(12); 329 ty.hash(hash); 330 } 331 Type::Tuple(ty) => { 332 hash.write_u8(13); 333 ty.hash(hash); 334 } 335 Type::Verbatim(ty) => { 336 hash.write_u8(14); 337 TokenStreamHelper(ty).hash(hash); 338 } 339 Type::__Nonexhaustive => unreachable!(), 340 } 341 } 342 } 343 344 ast_struct! { 345 /// The binary interface of a function: `extern "C"`. 346 /// 347 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 348 /// feature.* 349 pub struct Abi { 350 pub extern_token: Token![extern], 351 pub name: Option<LitStr>, 352 } 353 } 354 355 ast_struct! { 356 /// An argument in a function type: the `usize` in `fn(usize) -> bool`. 357 /// 358 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 359 /// feature.* 360 pub struct BareFnArg { 361 pub attrs: Vec<Attribute>, 362 pub name: Option<(Ident, Token![:])>, 363 pub ty: Type, 364 } 365 } 366 367 ast_struct! { 368 /// The variadic argument of a foreign function. 369 /// 370 /// ```rust 371 /// # struct c_char; 372 /// # struct c_int; 373 /// # 374 /// extern "C" { 375 /// fn printf(format: *const c_char, ...) -> c_int; 376 /// // ^^^ 377 /// } 378 /// ``` 379 /// 380 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 381 /// feature.* 382 pub struct Variadic { 383 pub attrs: Vec<Attribute>, 384 pub dots: Token![...], 385 } 386 } 387 388 ast_enum! { 389 /// Return type of a function signature. 390 /// 391 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 392 /// feature.* 393 pub enum ReturnType { 394 /// Return type is not specified. 395 /// 396 /// Functions default to `()` and closures default to type inference. 397 Default, 398 /// A particular type is returned. 399 Type(Token![->], Box<Type>), 400 } 401 } 402 403 #[cfg(feature = "parsing")] 404 pub mod parsing { 405 use super::*; 406 407 use crate::ext::IdentExt; 408 use crate::parse::{Parse, ParseStream, Result}; 409 use crate::path; 410 use proc_macro2::{Punct, Spacing, TokenTree}; 411 use std::iter::FromIterator; 412 413 impl Parse for Type { parse(input: ParseStream) -> Result<Self>414 fn parse(input: ParseStream) -> Result<Self> { 415 let allow_plus = true; 416 ambig_ty(input, allow_plus) 417 } 418 } 419 420 impl Type { 421 /// In some positions, types may not contain the `+` character, to 422 /// disambiguate them. For example in the expression `1 as T`, T may not 423 /// contain a `+` character. 424 /// 425 /// This parser does not allow a `+`, while the default parser does. without_plus(input: ParseStream) -> Result<Self>426 pub fn without_plus(input: ParseStream) -> Result<Self> { 427 let allow_plus = false; 428 ambig_ty(input, allow_plus) 429 } 430 } 431 ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type>432 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> { 433 if input.peek(token::Group) && !input.peek2(Token![::]) && !input.peek2(Token![<]) { 434 return input.parse().map(Type::Group); 435 } 436 437 let begin = input.fork(); 438 let mut lifetimes = None::<BoundLifetimes>; 439 let mut lookahead = input.lookahead1(); 440 if lookahead.peek(Token![for]) { 441 lifetimes = input.parse()?; 442 lookahead = input.lookahead1(); 443 if !lookahead.peek(Ident) 444 && !lookahead.peek(Token![fn]) 445 && !lookahead.peek(Token![unsafe]) 446 && !lookahead.peek(Token![extern]) 447 && !lookahead.peek(Token![super]) 448 && !lookahead.peek(Token![self]) 449 && !lookahead.peek(Token![Self]) 450 && !lookahead.peek(Token![crate]) 451 { 452 return Err(lookahead.error()); 453 } 454 } 455 456 if lookahead.peek(token::Paren) { 457 let content; 458 let paren_token = parenthesized!(content in input); 459 if content.is_empty() { 460 return Ok(Type::Tuple(TypeTuple { 461 paren_token, 462 elems: Punctuated::new(), 463 })); 464 } 465 if content.peek(Lifetime) { 466 return Ok(Type::Paren(TypeParen { 467 paren_token, 468 elem: Box::new(Type::TraitObject(content.parse()?)), 469 })); 470 } 471 if content.peek(Token![?]) { 472 return Ok(Type::TraitObject(TypeTraitObject { 473 dyn_token: None, 474 bounds: { 475 let mut bounds = Punctuated::new(); 476 bounds.push_value(TypeParamBound::Trait(TraitBound { 477 paren_token: Some(paren_token), 478 ..content.parse()? 479 })); 480 while let Some(plus) = input.parse()? { 481 bounds.push_punct(plus); 482 bounds.push_value(input.parse()?); 483 } 484 bounds 485 }, 486 })); 487 } 488 let mut first: Type = content.parse()?; 489 if content.peek(Token![,]) { 490 return Ok(Type::Tuple(TypeTuple { 491 paren_token, 492 elems: { 493 let mut elems = Punctuated::new(); 494 elems.push_value(first); 495 elems.push_punct(content.parse()?); 496 let rest: Punctuated<Type, Token![,]> = 497 content.parse_terminated(Parse::parse)?; 498 elems.extend(rest); 499 elems 500 }, 501 })); 502 } 503 if allow_plus && input.peek(Token![+]) { 504 loop { 505 let first = match first { 506 Type::Path(TypePath { qself: None, path }) => { 507 TypeParamBound::Trait(TraitBound { 508 paren_token: Some(paren_token), 509 modifier: TraitBoundModifier::None, 510 lifetimes: None, 511 path, 512 }) 513 } 514 Type::TraitObject(TypeTraitObject { 515 dyn_token: None, 516 bounds, 517 }) => { 518 if bounds.len() > 1 || bounds.trailing_punct() { 519 first = Type::TraitObject(TypeTraitObject { 520 dyn_token: None, 521 bounds, 522 }); 523 break; 524 } 525 match bounds.into_iter().next().unwrap() { 526 TypeParamBound::Trait(trait_bound) => { 527 TypeParamBound::Trait(TraitBound { 528 paren_token: Some(paren_token), 529 ..trait_bound 530 }) 531 } 532 other @ TypeParamBound::Lifetime(_) => other, 533 } 534 } 535 _ => break, 536 }; 537 return Ok(Type::TraitObject(TypeTraitObject { 538 dyn_token: None, 539 bounds: { 540 let mut bounds = Punctuated::new(); 541 bounds.push_value(first); 542 while let Some(plus) = input.parse()? { 543 bounds.push_punct(plus); 544 bounds.push_value(input.parse()?); 545 } 546 bounds 547 }, 548 })); 549 } 550 } 551 Ok(Type::Paren(TypeParen { 552 paren_token, 553 elem: Box::new(first), 554 })) 555 } else if lookahead.peek(Token![fn]) 556 || lookahead.peek(Token![unsafe]) 557 || lookahead.peek(Token![extern]) 558 { 559 let allow_mut_self = true; 560 if let Some(mut bare_fn) = parse_bare_fn(input, allow_mut_self)? { 561 bare_fn.lifetimes = lifetimes; 562 Ok(Type::BareFn(bare_fn)) 563 } else { 564 Ok(Type::Verbatim(verbatim::between(begin, input))) 565 } 566 } else if lookahead.peek(Ident) 567 || input.peek(Token![super]) 568 || input.peek(Token![self]) 569 || input.peek(Token![Self]) 570 || input.peek(Token![crate]) 571 || lookahead.peek(Token![::]) 572 || lookahead.peek(Token![<]) 573 { 574 if input.peek(Token![dyn]) { 575 let mut trait_object: TypeTraitObject = input.parse()?; 576 if lifetimes.is_some() { 577 match trait_object.bounds.iter_mut().next().unwrap() { 578 TypeParamBound::Trait(trait_bound) => { 579 trait_bound.lifetimes = lifetimes; 580 } 581 TypeParamBound::Lifetime(_) => unreachable!(), 582 } 583 } 584 return Ok(Type::TraitObject(trait_object)); 585 } 586 587 let ty: TypePath = input.parse()?; 588 if ty.qself.is_some() { 589 return Ok(Type::Path(ty)); 590 } 591 592 if input.peek(Token![!]) && !input.peek(Token![!=]) { 593 let mut contains_arguments = false; 594 for segment in &ty.path.segments { 595 match segment.arguments { 596 PathArguments::None => {} 597 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => { 598 contains_arguments = true; 599 } 600 } 601 } 602 603 if !contains_arguments { 604 let bang_token: Token![!] = input.parse()?; 605 let (delimiter, tokens) = mac::parse_delimiter(input)?; 606 return Ok(Type::Macro(TypeMacro { 607 mac: Macro { 608 path: ty.path, 609 bang_token, 610 delimiter, 611 tokens, 612 }, 613 })); 614 } 615 } 616 617 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) { 618 let mut bounds = Punctuated::new(); 619 bounds.push_value(TypeParamBound::Trait(TraitBound { 620 paren_token: None, 621 modifier: TraitBoundModifier::None, 622 lifetimes, 623 path: ty.path, 624 })); 625 if allow_plus { 626 while input.peek(Token![+]) { 627 bounds.push_punct(input.parse()?); 628 if input.peek(Token![>]) { 629 break; 630 } 631 bounds.push_value(input.parse()?); 632 } 633 } 634 return Ok(Type::TraitObject(TypeTraitObject { 635 dyn_token: None, 636 bounds, 637 })); 638 } 639 640 Ok(Type::Path(ty)) 641 } else if lookahead.peek(token::Bracket) { 642 let content; 643 let bracket_token = bracketed!(content in input); 644 let elem: Type = content.parse()?; 645 if content.peek(Token![;]) { 646 Ok(Type::Array(TypeArray { 647 bracket_token, 648 elem: Box::new(elem), 649 semi_token: content.parse()?, 650 len: content.parse()?, 651 })) 652 } else { 653 Ok(Type::Slice(TypeSlice { 654 bracket_token, 655 elem: Box::new(elem), 656 })) 657 } 658 } else if lookahead.peek(Token![*]) { 659 input.parse().map(Type::Ptr) 660 } else if lookahead.peek(Token![&]) { 661 input.parse().map(Type::Reference) 662 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) { 663 input.parse().map(Type::Never) 664 } else if lookahead.peek(Token![impl]) { 665 input.parse().map(Type::ImplTrait) 666 } else if lookahead.peek(Token![_]) { 667 input.parse().map(Type::Infer) 668 } else if lookahead.peek(Lifetime) { 669 input.parse().map(Type::TraitObject) 670 } else { 671 Err(lookahead.error()) 672 } 673 } 674 675 impl Parse for TypeSlice { parse(input: ParseStream) -> Result<Self>676 fn parse(input: ParseStream) -> Result<Self> { 677 let content; 678 Ok(TypeSlice { 679 bracket_token: bracketed!(content in input), 680 elem: content.parse()?, 681 }) 682 } 683 } 684 685 impl Parse for TypeArray { parse(input: ParseStream) -> Result<Self>686 fn parse(input: ParseStream) -> Result<Self> { 687 let content; 688 Ok(TypeArray { 689 bracket_token: bracketed!(content in input), 690 elem: content.parse()?, 691 semi_token: content.parse()?, 692 len: content.parse()?, 693 }) 694 } 695 } 696 697 impl Parse for TypePtr { parse(input: ParseStream) -> Result<Self>698 fn parse(input: ParseStream) -> Result<Self> { 699 let star_token: Token![*] = input.parse()?; 700 701 let lookahead = input.lookahead1(); 702 let (const_token, mutability) = if lookahead.peek(Token![const]) { 703 (Some(input.parse()?), None) 704 } else if lookahead.peek(Token![mut]) { 705 (None, Some(input.parse()?)) 706 } else { 707 return Err(lookahead.error()); 708 }; 709 710 Ok(TypePtr { 711 star_token, 712 const_token, 713 mutability, 714 elem: Box::new(input.call(Type::without_plus)?), 715 }) 716 } 717 } 718 719 impl Parse for TypeReference { parse(input: ParseStream) -> Result<Self>720 fn parse(input: ParseStream) -> Result<Self> { 721 Ok(TypeReference { 722 and_token: input.parse()?, 723 lifetime: input.parse()?, 724 mutability: input.parse()?, 725 // & binds tighter than +, so we don't allow + here. 726 elem: Box::new(input.call(Type::without_plus)?), 727 }) 728 } 729 } 730 731 impl Parse for TypeBareFn { parse(input: ParseStream) -> Result<Self>732 fn parse(input: ParseStream) -> Result<Self> { 733 let allow_mut_self = false; 734 parse_bare_fn(input, allow_mut_self).map(Option::unwrap) 735 } 736 } 737 parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>>738 fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> { 739 let args; 740 let mut variadic = None; 741 let mut has_mut_self = false; 742 743 let bare_fn = TypeBareFn { 744 lifetimes: input.parse()?, 745 unsafety: input.parse()?, 746 abi: input.parse()?, 747 fn_token: input.parse()?, 748 paren_token: parenthesized!(args in input), 749 inputs: { 750 let mut inputs = Punctuated::new(); 751 752 while !args.is_empty() { 753 let attrs = args.call(Attribute::parse_outer)?; 754 755 if inputs.empty_or_trailing() && args.peek(Token![...]) { 756 variadic = Some(Variadic { 757 attrs, 758 dots: args.parse()?, 759 }); 760 break; 761 } 762 763 if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? { 764 inputs.push_value(BareFnArg { attrs, ..arg }); 765 } else { 766 has_mut_self = true; 767 } 768 if args.is_empty() { 769 break; 770 } 771 772 inputs.push_punct(args.parse()?); 773 } 774 775 inputs 776 }, 777 variadic, 778 output: input.call(ReturnType::without_plus)?, 779 }; 780 781 if has_mut_self { 782 Ok(None) 783 } else { 784 Ok(Some(bare_fn)) 785 } 786 } 787 788 impl Parse for TypeNever { parse(input: ParseStream) -> Result<Self>789 fn parse(input: ParseStream) -> Result<Self> { 790 Ok(TypeNever { 791 bang_token: input.parse()?, 792 }) 793 } 794 } 795 796 impl Parse for TypeInfer { parse(input: ParseStream) -> Result<Self>797 fn parse(input: ParseStream) -> Result<Self> { 798 Ok(TypeInfer { 799 underscore_token: input.parse()?, 800 }) 801 } 802 } 803 804 impl Parse for TypeTuple { parse(input: ParseStream) -> Result<Self>805 fn parse(input: ParseStream) -> Result<Self> { 806 let content; 807 let paren_token = parenthesized!(content in input); 808 809 if content.is_empty() { 810 return Ok(TypeTuple { 811 paren_token, 812 elems: Punctuated::new(), 813 }); 814 } 815 816 let first: Type = content.parse()?; 817 Ok(TypeTuple { 818 paren_token, 819 elems: { 820 let mut elems = Punctuated::new(); 821 elems.push_value(first); 822 elems.push_punct(content.parse()?); 823 let rest: Punctuated<Type, Token![,]> = 824 content.parse_terminated(Parse::parse)?; 825 elems.extend(rest); 826 elems 827 }, 828 }) 829 } 830 } 831 832 impl Parse for TypeMacro { parse(input: ParseStream) -> Result<Self>833 fn parse(input: ParseStream) -> Result<Self> { 834 Ok(TypeMacro { 835 mac: input.parse()?, 836 }) 837 } 838 } 839 840 impl Parse for TypePath { parse(input: ParseStream) -> Result<Self>841 fn parse(input: ParseStream) -> Result<Self> { 842 let (qself, mut path) = path::parsing::qpath(input, false)?; 843 844 if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) { 845 let args: ParenthesizedGenericArguments = input.parse()?; 846 let parenthesized = PathArguments::Parenthesized(args); 847 path.segments.last_mut().unwrap().arguments = parenthesized; 848 } 849 850 Ok(TypePath { qself, path }) 851 } 852 } 853 854 impl ReturnType { without_plus(input: ParseStream) -> Result<Self>855 pub fn without_plus(input: ParseStream) -> Result<Self> { 856 let allow_plus = false; 857 Self::parse(input, allow_plus) 858 } 859 860 #[doc(hidden)] parse(input: ParseStream, allow_plus: bool) -> Result<Self>861 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 862 if input.peek(Token![->]) { 863 let arrow = input.parse()?; 864 let ty = ambig_ty(input, allow_plus)?; 865 Ok(ReturnType::Type(arrow, Box::new(ty))) 866 } else { 867 Ok(ReturnType::Default) 868 } 869 } 870 } 871 872 impl Parse for ReturnType { parse(input: ParseStream) -> Result<Self>873 fn parse(input: ParseStream) -> Result<Self> { 874 Self::parse(input, true) 875 } 876 } 877 878 impl Parse for TypeTraitObject { parse(input: ParseStream) -> Result<Self>879 fn parse(input: ParseStream) -> Result<Self> { 880 Self::parse(input, true) 881 } 882 } 883 at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool884 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { 885 for bound in bounds { 886 if let TypeParamBound::Trait(_) = *bound { 887 return true; 888 } 889 } 890 false 891 } 892 893 impl TypeTraitObject { without_plus(input: ParseStream) -> Result<Self>894 pub fn without_plus(input: ParseStream) -> Result<Self> { 895 let allow_plus = false; 896 Self::parse(input, allow_plus) 897 } 898 899 // Only allow multiple trait references if allow_plus is true. 900 #[doc(hidden)] parse(input: ParseStream, allow_plus: bool) -> Result<Self>901 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 902 Ok(TypeTraitObject { 903 dyn_token: input.parse()?, 904 bounds: { 905 let mut bounds = Punctuated::new(); 906 if allow_plus { 907 loop { 908 bounds.push_value(input.parse()?); 909 if !input.peek(Token![+]) { 910 break; 911 } 912 bounds.push_punct(input.parse()?); 913 if input.peek(Token![>]) { 914 break; 915 } 916 } 917 } else { 918 bounds.push_value(input.parse()?); 919 } 920 // Just lifetimes like `'a + 'b` is not a TraitObject. 921 if !at_least_one_type(&bounds) { 922 return Err(input.error("expected at least one type")); 923 } 924 bounds 925 }, 926 }) 927 } 928 } 929 930 impl Parse for TypeImplTrait { parse(input: ParseStream) -> Result<Self>931 fn parse(input: ParseStream) -> Result<Self> { 932 Ok(TypeImplTrait { 933 impl_token: input.parse()?, 934 // NOTE: rust-lang/rust#34511 includes discussion about whether 935 // or not + should be allowed in ImplTrait directly without (). 936 bounds: { 937 let mut bounds = Punctuated::new(); 938 loop { 939 bounds.push_value(input.parse()?); 940 if !input.peek(Token![+]) { 941 break; 942 } 943 bounds.push_punct(input.parse()?); 944 } 945 bounds 946 }, 947 }) 948 } 949 } 950 951 impl Parse for TypeGroup { parse(input: ParseStream) -> Result<Self>952 fn parse(input: ParseStream) -> Result<Self> { 953 let group = crate::group::parse_group(input)?; 954 Ok(TypeGroup { 955 group_token: group.token, 956 elem: group.content.parse()?, 957 }) 958 } 959 } 960 961 impl Parse for TypeParen { parse(input: ParseStream) -> Result<Self>962 fn parse(input: ParseStream) -> Result<Self> { 963 let allow_plus = false; 964 Self::parse(input, allow_plus) 965 } 966 } 967 968 impl TypeParen { parse(input: ParseStream, allow_plus: bool) -> Result<Self>969 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 970 let content; 971 Ok(TypeParen { 972 paren_token: parenthesized!(content in input), 973 elem: Box::new(ambig_ty(&content, allow_plus)?), 974 }) 975 } 976 } 977 978 impl Parse for BareFnArg { parse(input: ParseStream) -> Result<Self>979 fn parse(input: ParseStream) -> Result<Self> { 980 let allow_mut_self = false; 981 parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap) 982 } 983 } 984 parse_bare_fn_arg( input: ParseStream, mut allow_mut_self: bool, ) -> Result<Option<BareFnArg>>985 fn parse_bare_fn_arg( 986 input: ParseStream, 987 mut allow_mut_self: bool, 988 ) -> Result<Option<BareFnArg>> { 989 let mut has_mut_self = false; 990 let arg = BareFnArg { 991 attrs: input.call(Attribute::parse_outer)?, 992 name: { 993 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self])) 994 && input.peek2(Token![:]) 995 && !input.peek2(Token![::]) 996 { 997 let name = input.call(Ident::parse_any)?; 998 let colon: Token![:] = input.parse()?; 999 Some((name, colon)) 1000 } else if allow_mut_self 1001 && input.peek(Token![mut]) 1002 && input.peek2(Token![self]) 1003 && input.peek3(Token![:]) 1004 && !input.peek3(Token![::]) 1005 { 1006 has_mut_self = true; 1007 allow_mut_self = false; 1008 input.parse::<Token![mut]>()?; 1009 input.parse::<Token![self]>()?; 1010 input.parse::<Token![:]>()?; 1011 None 1012 } else { 1013 None 1014 } 1015 }, 1016 ty: if !has_mut_self && input.peek(Token![...]) { 1017 let dot3 = input.parse::<Token![...]>()?; 1018 let args = vec![ 1019 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1020 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1021 TokenTree::Punct(Punct::new('.', Spacing::Alone)), 1022 ]; 1023 let tokens = TokenStream::from_iter(args.into_iter().zip(&dot3.spans).map( 1024 |(mut arg, span)| { 1025 arg.set_span(*span); 1026 arg 1027 }, 1028 )); 1029 Type::Verbatim(tokens) 1030 } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) { 1031 has_mut_self = true; 1032 input.parse::<Token![mut]>()?; 1033 Type::Path(TypePath { 1034 qself: None, 1035 path: input.parse::<Token![self]>()?.into(), 1036 }) 1037 } else { 1038 input.parse()? 1039 }, 1040 }; 1041 1042 if has_mut_self { 1043 Ok(None) 1044 } else { 1045 Ok(Some(arg)) 1046 } 1047 } 1048 1049 impl Parse for Abi { parse(input: ParseStream) -> Result<Self>1050 fn parse(input: ParseStream) -> Result<Self> { 1051 Ok(Abi { 1052 extern_token: input.parse()?, 1053 name: input.parse()?, 1054 }) 1055 } 1056 } 1057 1058 impl Parse for Option<Abi> { parse(input: ParseStream) -> Result<Self>1059 fn parse(input: ParseStream) -> Result<Self> { 1060 if input.peek(Token![extern]) { 1061 input.parse().map(Some) 1062 } else { 1063 Ok(None) 1064 } 1065 } 1066 } 1067 } 1068 1069 #[cfg(feature = "printing")] 1070 mod printing { 1071 use super::*; 1072 1073 use proc_macro2::TokenStream; 1074 use quote::{ToTokens, TokenStreamExt}; 1075 1076 use crate::attr::FilterAttrs; 1077 use crate::print::TokensOrDefault; 1078 1079 impl ToTokens for TypeSlice { to_tokens(&self, tokens: &mut TokenStream)1080 fn to_tokens(&self, tokens: &mut TokenStream) { 1081 self.bracket_token.surround(tokens, |tokens| { 1082 self.elem.to_tokens(tokens); 1083 }); 1084 } 1085 } 1086 1087 impl ToTokens for TypeArray { to_tokens(&self, tokens: &mut TokenStream)1088 fn to_tokens(&self, tokens: &mut TokenStream) { 1089 self.bracket_token.surround(tokens, |tokens| { 1090 self.elem.to_tokens(tokens); 1091 self.semi_token.to_tokens(tokens); 1092 self.len.to_tokens(tokens); 1093 }); 1094 } 1095 } 1096 1097 impl ToTokens for TypePtr { to_tokens(&self, tokens: &mut TokenStream)1098 fn to_tokens(&self, tokens: &mut TokenStream) { 1099 self.star_token.to_tokens(tokens); 1100 match &self.mutability { 1101 Some(tok) => tok.to_tokens(tokens), 1102 None => { 1103 TokensOrDefault(&self.const_token).to_tokens(tokens); 1104 } 1105 } 1106 self.elem.to_tokens(tokens); 1107 } 1108 } 1109 1110 impl ToTokens for TypeReference { to_tokens(&self, tokens: &mut TokenStream)1111 fn to_tokens(&self, tokens: &mut TokenStream) { 1112 self.and_token.to_tokens(tokens); 1113 self.lifetime.to_tokens(tokens); 1114 self.mutability.to_tokens(tokens); 1115 self.elem.to_tokens(tokens); 1116 } 1117 } 1118 1119 impl ToTokens for TypeBareFn { to_tokens(&self, tokens: &mut TokenStream)1120 fn to_tokens(&self, tokens: &mut TokenStream) { 1121 self.lifetimes.to_tokens(tokens); 1122 self.unsafety.to_tokens(tokens); 1123 self.abi.to_tokens(tokens); 1124 self.fn_token.to_tokens(tokens); 1125 self.paren_token.surround(tokens, |tokens| { 1126 self.inputs.to_tokens(tokens); 1127 if let Some(variadic) = &self.variadic { 1128 if !self.inputs.empty_or_trailing() { 1129 let span = variadic.dots.spans[0]; 1130 Token![,](span).to_tokens(tokens); 1131 } 1132 variadic.to_tokens(tokens); 1133 } 1134 }); 1135 self.output.to_tokens(tokens); 1136 } 1137 } 1138 1139 impl ToTokens for TypeNever { to_tokens(&self, tokens: &mut TokenStream)1140 fn to_tokens(&self, tokens: &mut TokenStream) { 1141 self.bang_token.to_tokens(tokens); 1142 } 1143 } 1144 1145 impl ToTokens for TypeTuple { to_tokens(&self, tokens: &mut TokenStream)1146 fn to_tokens(&self, tokens: &mut TokenStream) { 1147 self.paren_token.surround(tokens, |tokens| { 1148 self.elems.to_tokens(tokens); 1149 }); 1150 } 1151 } 1152 1153 impl ToTokens for TypePath { to_tokens(&self, tokens: &mut TokenStream)1154 fn to_tokens(&self, tokens: &mut TokenStream) { 1155 private::print_path(tokens, &self.qself, &self.path); 1156 } 1157 } 1158 1159 impl ToTokens for TypeTraitObject { to_tokens(&self, tokens: &mut TokenStream)1160 fn to_tokens(&self, tokens: &mut TokenStream) { 1161 self.dyn_token.to_tokens(tokens); 1162 self.bounds.to_tokens(tokens); 1163 } 1164 } 1165 1166 impl ToTokens for TypeImplTrait { to_tokens(&self, tokens: &mut TokenStream)1167 fn to_tokens(&self, tokens: &mut TokenStream) { 1168 self.impl_token.to_tokens(tokens); 1169 self.bounds.to_tokens(tokens); 1170 } 1171 } 1172 1173 impl ToTokens for TypeGroup { to_tokens(&self, tokens: &mut TokenStream)1174 fn to_tokens(&self, tokens: &mut TokenStream) { 1175 self.group_token.surround(tokens, |tokens| { 1176 self.elem.to_tokens(tokens); 1177 }); 1178 } 1179 } 1180 1181 impl ToTokens for TypeParen { to_tokens(&self, tokens: &mut TokenStream)1182 fn to_tokens(&self, tokens: &mut TokenStream) { 1183 self.paren_token.surround(tokens, |tokens| { 1184 self.elem.to_tokens(tokens); 1185 }); 1186 } 1187 } 1188 1189 impl ToTokens for TypeInfer { to_tokens(&self, tokens: &mut TokenStream)1190 fn to_tokens(&self, tokens: &mut TokenStream) { 1191 self.underscore_token.to_tokens(tokens); 1192 } 1193 } 1194 1195 impl ToTokens for TypeMacro { to_tokens(&self, tokens: &mut TokenStream)1196 fn to_tokens(&self, tokens: &mut TokenStream) { 1197 self.mac.to_tokens(tokens); 1198 } 1199 } 1200 1201 impl ToTokens for ReturnType { to_tokens(&self, tokens: &mut TokenStream)1202 fn to_tokens(&self, tokens: &mut TokenStream) { 1203 match self { 1204 ReturnType::Default => {} 1205 ReturnType::Type(arrow, ty) => { 1206 arrow.to_tokens(tokens); 1207 ty.to_tokens(tokens); 1208 } 1209 } 1210 } 1211 } 1212 1213 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut TokenStream)1214 fn to_tokens(&self, tokens: &mut TokenStream) { 1215 tokens.append_all(self.attrs.outer()); 1216 if let Some((name, colon)) = &self.name { 1217 name.to_tokens(tokens); 1218 colon.to_tokens(tokens); 1219 } 1220 self.ty.to_tokens(tokens); 1221 } 1222 } 1223 1224 impl ToTokens for Variadic { to_tokens(&self, tokens: &mut TokenStream)1225 fn to_tokens(&self, tokens: &mut TokenStream) { 1226 tokens.append_all(self.attrs.outer()); 1227 self.dots.to_tokens(tokens); 1228 } 1229 } 1230 1231 impl ToTokens for Abi { to_tokens(&self, tokens: &mut TokenStream)1232 fn to_tokens(&self, tokens: &mut TokenStream) { 1233 self.extern_token.to_tokens(tokens); 1234 self.name.to_tokens(tokens); 1235 } 1236 } 1237 } 1238