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 { 416 return Err(lookahead.error()); 417 } 418 } 419 420 if lookahead.peek(token::Paren) { 421 let content; 422 let paren_token = parenthesized!(content in input); 423 if content.is_empty() { 424 return Ok(Type::Tuple(TypeTuple { 425 paren_token, 426 elems: Punctuated::new(), 427 })); 428 } 429 if content.peek(Lifetime) { 430 return Ok(Type::Paren(TypeParen { 431 paren_token, 432 elem: Box::new(Type::TraitObject(content.parse()?)), 433 })); 434 } 435 if content.peek(Token![?]) { 436 return Ok(Type::TraitObject(TypeTraitObject { 437 dyn_token: None, 438 bounds: { 439 let mut bounds = Punctuated::new(); 440 bounds.push_value(TypeParamBound::Trait(TraitBound { 441 paren_token: Some(paren_token), 442 ..content.parse()? 443 })); 444 while let Some(plus) = input.parse()? { 445 bounds.push_punct(plus); 446 bounds.push_value(input.parse()?); 447 } 448 bounds 449 }, 450 })); 451 } 452 let mut first: Type = content.parse()?; 453 if content.peek(Token![,]) { 454 return Ok(Type::Tuple(TypeTuple { 455 paren_token, 456 elems: { 457 let mut elems = Punctuated::new(); 458 elems.push_value(first); 459 elems.push_punct(content.parse()?); 460 while !content.is_empty() { 461 elems.push_value(content.parse()?); 462 if content.is_empty() { 463 break; 464 } 465 elems.push_punct(content.parse()?); 466 } 467 elems 468 }, 469 })); 470 } 471 if allow_plus && input.peek(Token![+]) { 472 loop { 473 let first = match first { 474 Type::Path(TypePath { qself: None, path }) => { 475 TypeParamBound::Trait(TraitBound { 476 paren_token: Some(paren_token), 477 modifier: TraitBoundModifier::None, 478 lifetimes: None, 479 path, 480 }) 481 } 482 Type::TraitObject(TypeTraitObject { 483 dyn_token: None, 484 bounds, 485 }) => { 486 if bounds.len() > 1 || bounds.trailing_punct() { 487 first = Type::TraitObject(TypeTraitObject { 488 dyn_token: None, 489 bounds, 490 }); 491 break; 492 } 493 match bounds.into_iter().next().unwrap() { 494 TypeParamBound::Trait(trait_bound) => { 495 TypeParamBound::Trait(TraitBound { 496 paren_token: Some(paren_token), 497 ..trait_bound 498 }) 499 } 500 other @ TypeParamBound::Lifetime(_) => other, 501 } 502 } 503 _ => break, 504 }; 505 return Ok(Type::TraitObject(TypeTraitObject { 506 dyn_token: None, 507 bounds: { 508 let mut bounds = Punctuated::new(); 509 bounds.push_value(first); 510 while let Some(plus) = input.parse()? { 511 bounds.push_punct(plus); 512 bounds.push_value(input.parse()?); 513 } 514 bounds 515 }, 516 })); 517 } 518 } 519 Ok(Type::Paren(TypeParen { 520 paren_token, 521 elem: Box::new(first), 522 })) 523 } else if lookahead.peek(Token![fn]) 524 || lookahead.peek(Token![unsafe]) 525 || lookahead.peek(Token![extern]) 526 { 527 let allow_mut_self = true; 528 if let Some(mut bare_fn) = parse_bare_fn(input, allow_mut_self)? { 529 bare_fn.lifetimes = lifetimes; 530 Ok(Type::BareFn(bare_fn)) 531 } else { 532 Ok(Type::Verbatim(verbatim::between(begin, input))) 533 } 534 } else if lookahead.peek(Ident) 535 || input.peek(Token![super]) 536 || input.peek(Token![self]) 537 || input.peek(Token![Self]) 538 || input.peek(Token![crate]) 539 || lookahead.peek(Token![::]) 540 || lookahead.peek(Token![<]) 541 { 542 if input.peek(Token![dyn]) { 543 let mut trait_object: TypeTraitObject = input.parse()?; 544 if lifetimes.is_some() { 545 match trait_object.bounds.iter_mut().next().unwrap() { 546 TypeParamBound::Trait(trait_bound) => { 547 trait_bound.lifetimes = lifetimes; 548 } 549 TypeParamBound::Lifetime(_) => unreachable!(), 550 } 551 } 552 return Ok(Type::TraitObject(trait_object)); 553 } 554 555 let ty: TypePath = input.parse()?; 556 if ty.qself.is_some() { 557 return Ok(Type::Path(ty)); 558 } 559 560 if input.peek(Token![!]) && !input.peek(Token![!=]) { 561 let mut contains_arguments = false; 562 for segment in &ty.path.segments { 563 match segment.arguments { 564 PathArguments::None => {} 565 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => { 566 contains_arguments = true; 567 } 568 } 569 } 570 571 if !contains_arguments { 572 let bang_token: Token![!] = input.parse()?; 573 let (delimiter, tokens) = mac::parse_delimiter(input)?; 574 return Ok(Type::Macro(TypeMacro { 575 mac: Macro { 576 path: ty.path, 577 bang_token, 578 delimiter, 579 tokens, 580 }, 581 })); 582 } 583 } 584 585 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) { 586 let mut bounds = Punctuated::new(); 587 bounds.push_value(TypeParamBound::Trait(TraitBound { 588 paren_token: None, 589 modifier: TraitBoundModifier::None, 590 lifetimes, 591 path: ty.path, 592 })); 593 if allow_plus { 594 while input.peek(Token![+]) { 595 bounds.push_punct(input.parse()?); 596 if input.peek(Token![>]) { 597 break; 598 } 599 bounds.push_value(input.parse()?); 600 } 601 } 602 return Ok(Type::TraitObject(TypeTraitObject { 603 dyn_token: None, 604 bounds, 605 })); 606 } 607 608 Ok(Type::Path(ty)) 609 } else if lookahead.peek(token::Bracket) { 610 let content; 611 let bracket_token = bracketed!(content in input); 612 let elem: Type = content.parse()?; 613 if content.peek(Token![;]) { 614 Ok(Type::Array(TypeArray { 615 bracket_token, 616 elem: Box::new(elem), 617 semi_token: content.parse()?, 618 len: content.parse()?, 619 })) 620 } else { 621 Ok(Type::Slice(TypeSlice { 622 bracket_token, 623 elem: Box::new(elem), 624 })) 625 } 626 } else if lookahead.peek(Token![*]) { 627 input.parse().map(Type::Ptr) 628 } else if lookahead.peek(Token![&]) { 629 input.parse().map(Type::Reference) 630 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) { 631 input.parse().map(Type::Never) 632 } else if lookahead.peek(Token![impl]) { 633 input.parse().map(Type::ImplTrait) 634 } else if lookahead.peek(Token![_]) { 635 input.parse().map(Type::Infer) 636 } else if lookahead.peek(Lifetime) { 637 input.parse().map(Type::TraitObject) 638 } else { 639 Err(lookahead.error()) 640 } 641 } 642 643 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 644 impl Parse for TypeSlice { parse(input: ParseStream) -> Result<Self>645 fn parse(input: ParseStream) -> Result<Self> { 646 let content; 647 Ok(TypeSlice { 648 bracket_token: bracketed!(content in input), 649 elem: content.parse()?, 650 }) 651 } 652 } 653 654 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 655 impl Parse for TypeArray { parse(input: ParseStream) -> Result<Self>656 fn parse(input: ParseStream) -> Result<Self> { 657 let content; 658 Ok(TypeArray { 659 bracket_token: bracketed!(content in input), 660 elem: content.parse()?, 661 semi_token: content.parse()?, 662 len: content.parse()?, 663 }) 664 } 665 } 666 667 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 668 impl Parse for TypePtr { parse(input: ParseStream) -> Result<Self>669 fn parse(input: ParseStream) -> Result<Self> { 670 let star_token: Token![*] = input.parse()?; 671 672 let lookahead = input.lookahead1(); 673 let (const_token, mutability) = if lookahead.peek(Token![const]) { 674 (Some(input.parse()?), None) 675 } else if lookahead.peek(Token![mut]) { 676 (None, Some(input.parse()?)) 677 } else { 678 return Err(lookahead.error()); 679 }; 680 681 Ok(TypePtr { 682 star_token, 683 const_token, 684 mutability, 685 elem: Box::new(input.call(Type::without_plus)?), 686 }) 687 } 688 } 689 690 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 691 impl Parse for TypeReference { parse(input: ParseStream) -> Result<Self>692 fn parse(input: ParseStream) -> Result<Self> { 693 Ok(TypeReference { 694 and_token: input.parse()?, 695 lifetime: input.parse()?, 696 mutability: input.parse()?, 697 // & binds tighter than +, so we don't allow + here. 698 elem: Box::new(input.call(Type::without_plus)?), 699 }) 700 } 701 } 702 703 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 704 impl Parse for TypeBareFn { parse(input: ParseStream) -> Result<Self>705 fn parse(input: ParseStream) -> Result<Self> { 706 let allow_mut_self = false; 707 parse_bare_fn(input, allow_mut_self).map(Option::unwrap) 708 } 709 } 710 parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>>711 fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> { 712 let args; 713 let mut variadic = None; 714 let mut has_mut_self = false; 715 716 let bare_fn = TypeBareFn { 717 lifetimes: input.parse()?, 718 unsafety: input.parse()?, 719 abi: input.parse()?, 720 fn_token: input.parse()?, 721 paren_token: parenthesized!(args in input), 722 inputs: { 723 let mut inputs = Punctuated::new(); 724 725 while !args.is_empty() { 726 let attrs = args.call(Attribute::parse_outer)?; 727 728 if inputs.empty_or_trailing() && args.peek(Token![...]) { 729 variadic = Some(Variadic { 730 attrs, 731 dots: args.parse()?, 732 }); 733 break; 734 } 735 736 if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? { 737 inputs.push_value(BareFnArg { attrs, ..arg }); 738 } else { 739 has_mut_self = true; 740 } 741 if args.is_empty() { 742 break; 743 } 744 745 inputs.push_punct(args.parse()?); 746 } 747 748 inputs 749 }, 750 variadic, 751 output: input.call(ReturnType::without_plus)?, 752 }; 753 754 if has_mut_self { 755 Ok(None) 756 } else { 757 Ok(Some(bare_fn)) 758 } 759 } 760 761 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 762 impl Parse for TypeNever { parse(input: ParseStream) -> Result<Self>763 fn parse(input: ParseStream) -> Result<Self> { 764 Ok(TypeNever { 765 bang_token: input.parse()?, 766 }) 767 } 768 } 769 770 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 771 impl Parse for TypeInfer { parse(input: ParseStream) -> Result<Self>772 fn parse(input: ParseStream) -> Result<Self> { 773 Ok(TypeInfer { 774 underscore_token: input.parse()?, 775 }) 776 } 777 } 778 779 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 780 impl Parse for TypeTuple { parse(input: ParseStream) -> Result<Self>781 fn parse(input: ParseStream) -> Result<Self> { 782 let content; 783 let paren_token = parenthesized!(content in input); 784 785 if content.is_empty() { 786 return Ok(TypeTuple { 787 paren_token, 788 elems: Punctuated::new(), 789 }); 790 } 791 792 let first: Type = content.parse()?; 793 Ok(TypeTuple { 794 paren_token, 795 elems: { 796 let mut elems = Punctuated::new(); 797 elems.push_value(first); 798 elems.push_punct(content.parse()?); 799 while !content.is_empty() { 800 elems.push_value(content.parse()?); 801 if content.is_empty() { 802 break; 803 } 804 elems.push_punct(content.parse()?); 805 } 806 elems 807 }, 808 }) 809 } 810 } 811 812 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 813 impl Parse for TypeMacro { parse(input: ParseStream) -> Result<Self>814 fn parse(input: ParseStream) -> Result<Self> { 815 Ok(TypeMacro { 816 mac: input.parse()?, 817 }) 818 } 819 } 820 821 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 822 impl Parse for TypePath { parse(input: ParseStream) -> Result<Self>823 fn parse(input: ParseStream) -> Result<Self> { 824 let (qself, mut path) = path::parsing::qpath(input, false)?; 825 826 if path.segments.last().unwrap().arguments.is_empty() && input.peek(token::Paren) { 827 let args: ParenthesizedGenericArguments = input.parse()?; 828 let parenthesized = PathArguments::Parenthesized(args); 829 path.segments.last_mut().unwrap().arguments = parenthesized; 830 } 831 832 Ok(TypePath { qself, path }) 833 } 834 } 835 836 impl ReturnType { without_plus(input: ParseStream) -> Result<Self>837 pub fn without_plus(input: ParseStream) -> Result<Self> { 838 let allow_plus = false; 839 Self::parse(input, allow_plus) 840 } 841 842 #[doc(hidden)] parse(input: ParseStream, allow_plus: bool) -> Result<Self>843 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 844 if input.peek(Token![->]) { 845 let arrow = input.parse()?; 846 let ty = ambig_ty(input, allow_plus)?; 847 Ok(ReturnType::Type(arrow, Box::new(ty))) 848 } else { 849 Ok(ReturnType::Default) 850 } 851 } 852 } 853 854 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 855 impl Parse for ReturnType { parse(input: ParseStream) -> Result<Self>856 fn parse(input: ParseStream) -> Result<Self> { 857 Self::parse(input, true) 858 } 859 } 860 861 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 862 impl Parse for TypeTraitObject { parse(input: ParseStream) -> Result<Self>863 fn parse(input: ParseStream) -> Result<Self> { 864 Self::parse(input, true) 865 } 866 } 867 at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool868 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { 869 for bound in bounds { 870 if let TypeParamBound::Trait(_) = *bound { 871 return true; 872 } 873 } 874 false 875 } 876 877 impl TypeTraitObject { without_plus(input: ParseStream) -> Result<Self>878 pub fn without_plus(input: ParseStream) -> Result<Self> { 879 let allow_plus = false; 880 Self::parse(input, allow_plus) 881 } 882 883 // Only allow multiple trait references if allow_plus is true. 884 #[doc(hidden)] parse(input: ParseStream, allow_plus: bool) -> Result<Self>885 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 886 Ok(TypeTraitObject { 887 dyn_token: input.parse()?, 888 bounds: { 889 let mut bounds = Punctuated::new(); 890 if allow_plus { 891 loop { 892 bounds.push_value(input.parse()?); 893 if !input.peek(Token![+]) { 894 break; 895 } 896 bounds.push_punct(input.parse()?); 897 if input.peek(Token![>]) { 898 break; 899 } 900 } 901 } else { 902 bounds.push_value(input.parse()?); 903 } 904 // Just lifetimes like `'a + 'b` is not a TraitObject. 905 if !at_least_one_type(&bounds) { 906 return Err(input.error("expected at least one type")); 907 } 908 bounds 909 }, 910 }) 911 } 912 } 913 914 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 915 impl Parse for TypeImplTrait { parse(input: ParseStream) -> Result<Self>916 fn parse(input: ParseStream) -> Result<Self> { 917 Ok(TypeImplTrait { 918 impl_token: input.parse()?, 919 // NOTE: rust-lang/rust#34511 includes discussion about whether 920 // or not + should be allowed in ImplTrait directly without (). 921 bounds: { 922 let mut bounds = Punctuated::new(); 923 loop { 924 bounds.push_value(input.parse()?); 925 if !input.peek(Token![+]) { 926 break; 927 } 928 bounds.push_punct(input.parse()?); 929 } 930 bounds 931 }, 932 }) 933 } 934 } 935 936 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 937 impl Parse for TypeGroup { parse(input: ParseStream) -> Result<Self>938 fn parse(input: ParseStream) -> Result<Self> { 939 let group = crate::group::parse_group(input)?; 940 Ok(TypeGroup { 941 group_token: group.token, 942 elem: group.content.parse()?, 943 }) 944 } 945 } 946 947 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 948 impl Parse for TypeParen { parse(input: ParseStream) -> Result<Self>949 fn parse(input: ParseStream) -> Result<Self> { 950 let allow_plus = false; 951 Self::parse(input, allow_plus) 952 } 953 } 954 955 impl TypeParen { parse(input: ParseStream, allow_plus: bool) -> Result<Self>956 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 957 let content; 958 Ok(TypeParen { 959 paren_token: parenthesized!(content in input), 960 elem: Box::new(ambig_ty(&content, allow_plus)?), 961 }) 962 } 963 } 964 965 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 966 impl Parse for BareFnArg { parse(input: ParseStream) -> Result<Self>967 fn parse(input: ParseStream) -> Result<Self> { 968 let allow_mut_self = false; 969 parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap) 970 } 971 } 972 parse_bare_fn_arg( input: ParseStream, mut allow_mut_self: bool, ) -> Result<Option<BareFnArg>>973 fn parse_bare_fn_arg( 974 input: ParseStream, 975 mut allow_mut_self: bool, 976 ) -> Result<Option<BareFnArg>> { 977 let mut has_mut_self = false; 978 let arg = BareFnArg { 979 attrs: input.call(Attribute::parse_outer)?, 980 name: { 981 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self])) 982 && input.peek2(Token![:]) 983 && !input.peek2(Token![::]) 984 { 985 let name = input.call(Ident::parse_any)?; 986 let colon: Token![:] = input.parse()?; 987 Some((name, colon)) 988 } else if allow_mut_self 989 && input.peek(Token![mut]) 990 && input.peek2(Token![self]) 991 && input.peek3(Token![:]) 992 && !input.peek3(Token![::]) 993 { 994 has_mut_self = true; 995 allow_mut_self = false; 996 input.parse::<Token![mut]>()?; 997 input.parse::<Token![self]>()?; 998 input.parse::<Token![:]>()?; 999 None 1000 } else { 1001 None 1002 } 1003 }, 1004 ty: if !has_mut_self && input.peek(Token![...]) { 1005 let dot3 = input.parse::<Token![...]>()?; 1006 let args = vec![ 1007 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1008 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1009 TokenTree::Punct(Punct::new('.', Spacing::Alone)), 1010 ]; 1011 let tokens: TokenStream = args 1012 .into_iter() 1013 .zip(&dot3.spans) 1014 .map(|(mut arg, span)| { 1015 arg.set_span(*span); 1016 arg 1017 }) 1018 .collect(); 1019 Type::Verbatim(tokens) 1020 } else if allow_mut_self && input.peek(Token![mut]) && input.peek2(Token![self]) { 1021 has_mut_self = true; 1022 input.parse::<Token![mut]>()?; 1023 Type::Path(TypePath { 1024 qself: None, 1025 path: input.parse::<Token![self]>()?.into(), 1026 }) 1027 } else { 1028 input.parse()? 1029 }, 1030 }; 1031 1032 if has_mut_self { 1033 Ok(None) 1034 } else { 1035 Ok(Some(arg)) 1036 } 1037 } 1038 1039 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 1040 impl Parse for Abi { parse(input: ParseStream) -> Result<Self>1041 fn parse(input: ParseStream) -> Result<Self> { 1042 Ok(Abi { 1043 extern_token: input.parse()?, 1044 name: input.parse()?, 1045 }) 1046 } 1047 } 1048 1049 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 1050 impl Parse for Option<Abi> { parse(input: ParseStream) -> Result<Self>1051 fn parse(input: ParseStream) -> Result<Self> { 1052 if input.peek(Token![extern]) { 1053 input.parse().map(Some) 1054 } else { 1055 Ok(None) 1056 } 1057 } 1058 } 1059 } 1060 1061 #[cfg(feature = "printing")] 1062 mod printing { 1063 use super::*; 1064 use crate::attr::FilterAttrs; 1065 use crate::print::TokensOrDefault; 1066 use proc_macro2::TokenStream; 1067 use quote::{ToTokens, TokenStreamExt}; 1068 1069 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1070 impl ToTokens for TypeSlice { to_tokens(&self, tokens: &mut TokenStream)1071 fn to_tokens(&self, tokens: &mut TokenStream) { 1072 self.bracket_token.surround(tokens, |tokens| { 1073 self.elem.to_tokens(tokens); 1074 }); 1075 } 1076 } 1077 1078 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1079 impl ToTokens for TypeArray { 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 self.semi_token.to_tokens(tokens); 1084 self.len.to_tokens(tokens); 1085 }); 1086 } 1087 } 1088 1089 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1090 impl ToTokens for TypePtr { to_tokens(&self, tokens: &mut TokenStream)1091 fn to_tokens(&self, tokens: &mut TokenStream) { 1092 self.star_token.to_tokens(tokens); 1093 match &self.mutability { 1094 Some(tok) => tok.to_tokens(tokens), 1095 None => { 1096 TokensOrDefault(&self.const_token).to_tokens(tokens); 1097 } 1098 } 1099 self.elem.to_tokens(tokens); 1100 } 1101 } 1102 1103 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1104 impl ToTokens for TypeReference { to_tokens(&self, tokens: &mut TokenStream)1105 fn to_tokens(&self, tokens: &mut TokenStream) { 1106 self.and_token.to_tokens(tokens); 1107 self.lifetime.to_tokens(tokens); 1108 self.mutability.to_tokens(tokens); 1109 self.elem.to_tokens(tokens); 1110 } 1111 } 1112 1113 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1114 impl ToTokens for TypeBareFn { to_tokens(&self, tokens: &mut TokenStream)1115 fn to_tokens(&self, tokens: &mut TokenStream) { 1116 self.lifetimes.to_tokens(tokens); 1117 self.unsafety.to_tokens(tokens); 1118 self.abi.to_tokens(tokens); 1119 self.fn_token.to_tokens(tokens); 1120 self.paren_token.surround(tokens, |tokens| { 1121 self.inputs.to_tokens(tokens); 1122 if let Some(variadic) = &self.variadic { 1123 if !self.inputs.empty_or_trailing() { 1124 let span = variadic.dots.spans[0]; 1125 Token![,](span).to_tokens(tokens); 1126 } 1127 variadic.to_tokens(tokens); 1128 } 1129 }); 1130 self.output.to_tokens(tokens); 1131 } 1132 } 1133 1134 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1135 impl ToTokens for TypeNever { to_tokens(&self, tokens: &mut TokenStream)1136 fn to_tokens(&self, tokens: &mut TokenStream) { 1137 self.bang_token.to_tokens(tokens); 1138 } 1139 } 1140 1141 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1142 impl ToTokens for TypeTuple { to_tokens(&self, tokens: &mut TokenStream)1143 fn to_tokens(&self, tokens: &mut TokenStream) { 1144 self.paren_token.surround(tokens, |tokens| { 1145 self.elems.to_tokens(tokens); 1146 }); 1147 } 1148 } 1149 1150 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1151 impl ToTokens for TypePath { to_tokens(&self, tokens: &mut TokenStream)1152 fn to_tokens(&self, tokens: &mut TokenStream) { 1153 private::print_path(tokens, &self.qself, &self.path); 1154 } 1155 } 1156 1157 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1158 impl ToTokens for TypeTraitObject { to_tokens(&self, tokens: &mut TokenStream)1159 fn to_tokens(&self, tokens: &mut TokenStream) { 1160 self.dyn_token.to_tokens(tokens); 1161 self.bounds.to_tokens(tokens); 1162 } 1163 } 1164 1165 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 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 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1174 impl ToTokens for TypeGroup { to_tokens(&self, tokens: &mut TokenStream)1175 fn to_tokens(&self, tokens: &mut TokenStream) { 1176 self.group_token.surround(tokens, |tokens| { 1177 self.elem.to_tokens(tokens); 1178 }); 1179 } 1180 } 1181 1182 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1183 impl ToTokens for TypeParen { to_tokens(&self, tokens: &mut TokenStream)1184 fn to_tokens(&self, tokens: &mut TokenStream) { 1185 self.paren_token.surround(tokens, |tokens| { 1186 self.elem.to_tokens(tokens); 1187 }); 1188 } 1189 } 1190 1191 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1192 impl ToTokens for TypeInfer { to_tokens(&self, tokens: &mut TokenStream)1193 fn to_tokens(&self, tokens: &mut TokenStream) { 1194 self.underscore_token.to_tokens(tokens); 1195 } 1196 } 1197 1198 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1199 impl ToTokens for TypeMacro { to_tokens(&self, tokens: &mut TokenStream)1200 fn to_tokens(&self, tokens: &mut TokenStream) { 1201 self.mac.to_tokens(tokens); 1202 } 1203 } 1204 1205 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1206 impl ToTokens for ReturnType { to_tokens(&self, tokens: &mut TokenStream)1207 fn to_tokens(&self, tokens: &mut TokenStream) { 1208 match self { 1209 ReturnType::Default => {} 1210 ReturnType::Type(arrow, ty) => { 1211 arrow.to_tokens(tokens); 1212 ty.to_tokens(tokens); 1213 } 1214 } 1215 } 1216 } 1217 1218 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1219 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut TokenStream)1220 fn to_tokens(&self, tokens: &mut TokenStream) { 1221 tokens.append_all(self.attrs.outer()); 1222 if let Some((name, colon)) = &self.name { 1223 name.to_tokens(tokens); 1224 colon.to_tokens(tokens); 1225 } 1226 self.ty.to_tokens(tokens); 1227 } 1228 } 1229 1230 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1231 impl ToTokens for Variadic { to_tokens(&self, tokens: &mut TokenStream)1232 fn to_tokens(&self, tokens: &mut TokenStream) { 1233 tokens.append_all(self.attrs.outer()); 1234 self.dots.to_tokens(tokens); 1235 } 1236 } 1237 1238 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1239 impl ToTokens for Abi { to_tokens(&self, tokens: &mut TokenStream)1240 fn to_tokens(&self, tokens: &mut TokenStream) { 1241 self.extern_token.to_tokens(tokens); 1242 self.name.to_tokens(tokens); 1243 } 1244 } 1245 } 1246