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