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::parse(input, allow_plus)?; 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(Ident::peek_any) 590 || input.peek(Token![::]) 591 || input.peek(Token![?]) 592 || input.peek(Lifetime) 593 || input.peek(token::Paren)) 594 { 595 break; 596 } 597 bounds.push_value(input.parse()?); 598 } 599 } 600 return Ok(Type::TraitObject(TypeTraitObject { 601 dyn_token: None, 602 bounds, 603 })); 604 } 605 606 Ok(Type::Path(ty)) 607 } else if lookahead.peek(token::Bracket) { 608 let content; 609 let bracket_token = bracketed!(content in input); 610 let elem: Type = content.parse()?; 611 if content.peek(Token![;]) { 612 Ok(Type::Array(TypeArray { 613 bracket_token, 614 elem: Box::new(elem), 615 semi_token: content.parse()?, 616 len: content.parse()?, 617 })) 618 } else { 619 Ok(Type::Slice(TypeSlice { 620 bracket_token, 621 elem: Box::new(elem), 622 })) 623 } 624 } else if lookahead.peek(Token![*]) { 625 input.parse().map(Type::Ptr) 626 } else if lookahead.peek(Token![&]) { 627 input.parse().map(Type::Reference) 628 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) { 629 input.parse().map(Type::Never) 630 } else if lookahead.peek(Token![impl]) { 631 TypeImplTrait::parse(input, allow_plus).map(Type::ImplTrait) 632 } else if lookahead.peek(Token![_]) { 633 input.parse().map(Type::Infer) 634 } else if lookahead.peek(Lifetime) { 635 input.parse().map(Type::TraitObject) 636 } else { 637 Err(lookahead.error()) 638 } 639 } 640 641 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 642 impl Parse for TypeSlice { parse(input: ParseStream) -> Result<Self>643 fn parse(input: ParseStream) -> Result<Self> { 644 let content; 645 Ok(TypeSlice { 646 bracket_token: bracketed!(content in input), 647 elem: content.parse()?, 648 }) 649 } 650 } 651 652 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 653 impl Parse for TypeArray { parse(input: ParseStream) -> Result<Self>654 fn parse(input: ParseStream) -> Result<Self> { 655 let content; 656 Ok(TypeArray { 657 bracket_token: bracketed!(content in input), 658 elem: content.parse()?, 659 semi_token: content.parse()?, 660 len: content.parse()?, 661 }) 662 } 663 } 664 665 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 666 impl Parse for TypePtr { parse(input: ParseStream) -> Result<Self>667 fn parse(input: ParseStream) -> Result<Self> { 668 let star_token: Token![*] = input.parse()?; 669 670 let lookahead = input.lookahead1(); 671 let (const_token, mutability) = if lookahead.peek(Token![const]) { 672 (Some(input.parse()?), None) 673 } else if lookahead.peek(Token![mut]) { 674 (None, Some(input.parse()?)) 675 } else { 676 return Err(lookahead.error()); 677 }; 678 679 Ok(TypePtr { 680 star_token, 681 const_token, 682 mutability, 683 elem: Box::new(input.call(Type::without_plus)?), 684 }) 685 } 686 } 687 688 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 689 impl Parse for TypeReference { parse(input: ParseStream) -> Result<Self>690 fn parse(input: ParseStream) -> Result<Self> { 691 Ok(TypeReference { 692 and_token: input.parse()?, 693 lifetime: input.parse()?, 694 mutability: input.parse()?, 695 // & binds tighter than +, so we don't allow + here. 696 elem: Box::new(input.call(Type::without_plus)?), 697 }) 698 } 699 } 700 701 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 702 impl Parse for TypeBareFn { parse(input: ParseStream) -> Result<Self>703 fn parse(input: ParseStream) -> Result<Self> { 704 let allow_mut_self = false; 705 parse_bare_fn(input, allow_mut_self).map(Option::unwrap) 706 } 707 } 708 parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>>709 fn parse_bare_fn(input: ParseStream, allow_mut_self: bool) -> Result<Option<TypeBareFn>> { 710 let args; 711 let mut variadic = None; 712 let mut has_mut_self = false; 713 714 let bare_fn = TypeBareFn { 715 lifetimes: input.parse()?, 716 unsafety: input.parse()?, 717 abi: input.parse()?, 718 fn_token: input.parse()?, 719 paren_token: parenthesized!(args in input), 720 inputs: { 721 let mut inputs = Punctuated::new(); 722 723 while !args.is_empty() { 724 let attrs = args.call(Attribute::parse_outer)?; 725 726 if inputs.empty_or_trailing() && args.peek(Token![...]) { 727 variadic = Some(Variadic { 728 attrs, 729 dots: args.parse()?, 730 }); 731 break; 732 } 733 734 if let Some(arg) = parse_bare_fn_arg(&args, allow_mut_self)? { 735 inputs.push_value(BareFnArg { attrs, ..arg }); 736 } else { 737 has_mut_self = true; 738 } 739 if args.is_empty() { 740 break; 741 } 742 743 inputs.push_punct(args.parse()?); 744 } 745 746 inputs 747 }, 748 variadic, 749 output: input.call(ReturnType::without_plus)?, 750 }; 751 752 if has_mut_self { 753 Ok(None) 754 } else { 755 Ok(Some(bare_fn)) 756 } 757 } 758 759 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 760 impl Parse for TypeNever { parse(input: ParseStream) -> Result<Self>761 fn parse(input: ParseStream) -> Result<Self> { 762 Ok(TypeNever { 763 bang_token: input.parse()?, 764 }) 765 } 766 } 767 768 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 769 impl Parse for TypeInfer { parse(input: ParseStream) -> Result<Self>770 fn parse(input: ParseStream) -> Result<Self> { 771 Ok(TypeInfer { 772 underscore_token: input.parse()?, 773 }) 774 } 775 } 776 777 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 778 impl Parse for TypeTuple { parse(input: ParseStream) -> Result<Self>779 fn parse(input: ParseStream) -> Result<Self> { 780 let content; 781 let paren_token = parenthesized!(content in input); 782 783 if content.is_empty() { 784 return Ok(TypeTuple { 785 paren_token, 786 elems: Punctuated::new(), 787 }); 788 } 789 790 let first: Type = content.parse()?; 791 Ok(TypeTuple { 792 paren_token, 793 elems: { 794 let mut elems = Punctuated::new(); 795 elems.push_value(first); 796 elems.push_punct(content.parse()?); 797 while !content.is_empty() { 798 elems.push_value(content.parse()?); 799 if content.is_empty() { 800 break; 801 } 802 elems.push_punct(content.parse()?); 803 } 804 elems 805 }, 806 }) 807 } 808 } 809 810 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 811 impl Parse for TypeMacro { parse(input: ParseStream) -> Result<Self>812 fn parse(input: ParseStream) -> Result<Self> { 813 Ok(TypeMacro { 814 mac: input.parse()?, 815 }) 816 } 817 } 818 819 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 820 impl Parse for TypePath { parse(input: ParseStream) -> Result<Self>821 fn parse(input: ParseStream) -> Result<Self> { 822 let (qself, mut path) = path::parsing::qpath(input, false)?; 823 824 if path.segments.last().unwrap().arguments.is_empty() 825 && (input.peek(token::Paren) || input.peek(Token![::]) && input.peek3(token::Paren)) 826 { 827 input.parse::<Option<Token![::]>>()?; 828 let args: ParenthesizedGenericArguments = input.parse()?; 829 let parenthesized = PathArguments::Parenthesized(args); 830 path.segments.last_mut().unwrap().arguments = parenthesized; 831 } 832 833 Ok(TypePath { qself, path }) 834 } 835 } 836 837 impl ReturnType { 838 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] without_plus(input: ParseStream) -> Result<Self>839 pub fn without_plus(input: ParseStream) -> Result<Self> { 840 let allow_plus = false; 841 Self::parse(input, allow_plus) 842 } 843 parse(input: ParseStream, allow_plus: bool) -> Result<Self>844 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 845 if input.peek(Token![->]) { 846 let arrow = input.parse()?; 847 let ty = ambig_ty(input, allow_plus)?; 848 Ok(ReturnType::Type(arrow, Box::new(ty))) 849 } else { 850 Ok(ReturnType::Default) 851 } 852 } 853 } 854 855 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 856 impl Parse for ReturnType { parse(input: ParseStream) -> Result<Self>857 fn parse(input: ParseStream) -> Result<Self> { 858 let allow_plus = true; 859 Self::parse(input, allow_plus) 860 } 861 } 862 863 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 864 impl Parse for TypeTraitObject { parse(input: ParseStream) -> Result<Self>865 fn parse(input: ParseStream) -> Result<Self> { 866 let allow_plus = true; 867 Self::parse(input, allow_plus) 868 } 869 } 870 at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool871 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { 872 for bound in bounds { 873 if let TypeParamBound::Trait(_) = *bound { 874 return true; 875 } 876 } 877 false 878 } 879 880 impl TypeTraitObject { 881 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] without_plus(input: ParseStream) -> Result<Self>882 pub fn without_plus(input: ParseStream) -> Result<Self> { 883 let allow_plus = false; 884 Self::parse(input, allow_plus) 885 } 886 887 // Only allow multiple trait references if allow_plus is true. parse(input: ParseStream, allow_plus: bool) -> Result<Self>888 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 889 Ok(TypeTraitObject { 890 dyn_token: input.parse()?, 891 bounds: Self::parse_bounds(input, allow_plus)?, 892 }) 893 } 894 parse_bounds( input: ParseStream, allow_plus: bool, ) -> Result<Punctuated<TypeParamBound, Token![+]>>895 fn parse_bounds( 896 input: ParseStream, 897 allow_plus: bool, 898 ) -> Result<Punctuated<TypeParamBound, Token![+]>> { 899 let mut bounds = Punctuated::new(); 900 loop { 901 bounds.push_value(input.parse()?); 902 if !(allow_plus && input.peek(Token![+])) { 903 break; 904 } 905 bounds.push_punct(input.parse()?); 906 if !(input.peek(Ident::peek_any) 907 || input.peek(Token![::]) 908 || input.peek(Token![?]) 909 || input.peek(Lifetime) 910 || input.peek(token::Paren)) 911 { 912 break; 913 } 914 } 915 // Just lifetimes like `'a + 'b` is not a TraitObject. 916 if !at_least_one_type(&bounds) { 917 return Err(input.error("expected at least one type")); 918 } 919 Ok(bounds) 920 } 921 } 922 923 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 924 impl Parse for TypeImplTrait { parse(input: ParseStream) -> Result<Self>925 fn parse(input: ParseStream) -> Result<Self> { 926 let allow_plus = true; 927 Self::parse(input, allow_plus) 928 } 929 } 930 931 impl TypeImplTrait { 932 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] without_plus(input: ParseStream) -> Result<Self>933 pub fn without_plus(input: ParseStream) -> Result<Self> { 934 let allow_plus = false; 935 Self::parse(input, allow_plus) 936 } 937 parse(input: ParseStream, allow_plus: bool) -> Result<Self>938 pub(crate) fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 939 Ok(TypeImplTrait { 940 impl_token: input.parse()?, 941 bounds: TypeTraitObject::parse_bounds(input, allow_plus)?, 942 }) 943 } 944 } 945 946 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 947 impl Parse for TypeGroup { parse(input: ParseStream) -> Result<Self>948 fn parse(input: ParseStream) -> Result<Self> { 949 let group = crate::group::parse_group(input)?; 950 Ok(TypeGroup { 951 group_token: group.token, 952 elem: group.content.parse()?, 953 }) 954 } 955 } 956 957 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 958 impl Parse for TypeParen { parse(input: ParseStream) -> Result<Self>959 fn parse(input: ParseStream) -> Result<Self> { 960 let allow_plus = false; 961 Self::parse(input, allow_plus) 962 } 963 } 964 965 impl TypeParen { parse(input: ParseStream, allow_plus: bool) -> Result<Self>966 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 967 let content; 968 Ok(TypeParen { 969 paren_token: parenthesized!(content in input), 970 elem: Box::new(ambig_ty(&content, allow_plus)?), 971 }) 972 } 973 } 974 975 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 976 impl Parse for BareFnArg { parse(input: ParseStream) -> Result<Self>977 fn parse(input: ParseStream) -> Result<Self> { 978 let allow_mut_self = false; 979 parse_bare_fn_arg(input, allow_mut_self).map(Option::unwrap) 980 } 981 } 982 parse_bare_fn_arg( input: ParseStream, mut allow_mut_self: bool, ) -> Result<Option<BareFnArg>>983 fn parse_bare_fn_arg( 984 input: ParseStream, 985 mut allow_mut_self: bool, 986 ) -> Result<Option<BareFnArg>> { 987 let mut has_mut_self = false; 988 let arg = BareFnArg { 989 attrs: input.call(Attribute::parse_outer)?, 990 name: { 991 if (input.peek(Ident) || input.peek(Token![_]) || input.peek(Token![self])) 992 && input.peek2(Token![:]) 993 && !input.peek2(Token![::]) 994 { 995 let name = input.call(Ident::parse_any)?; 996 let colon: Token![:] = input.parse()?; 997 Some((name, colon)) 998 } else if allow_mut_self 999 && input.peek(Token![mut]) 1000 && input.peek2(Token![self]) 1001 && input.peek3(Token![:]) 1002 && !input.peek3(Token![::]) 1003 { 1004 has_mut_self = true; 1005 allow_mut_self = false; 1006 input.parse::<Token![mut]>()?; 1007 input.parse::<Token![self]>()?; 1008 input.parse::<Token![:]>()?; 1009 None 1010 } else { 1011 None 1012 } 1013 }, 1014 ty: if !has_mut_self && input.peek(Token![...]) { 1015 let dot3 = input.parse::<Token![...]>()?; 1016 let args = vec![ 1017 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1018 TokenTree::Punct(Punct::new('.', Spacing::Joint)), 1019 TokenTree::Punct(Punct::new('.', Spacing::Alone)), 1020 ]; 1021 let tokens: TokenStream = args 1022 .into_iter() 1023 .zip(&dot3.spans) 1024 .map(|(mut arg, span)| { 1025 arg.set_span(*span); 1026 arg 1027 }) 1028 .collect(); 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 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 1050 impl Parse for Abi { parse(input: ParseStream) -> Result<Self>1051 fn parse(input: ParseStream) -> Result<Self> { 1052 Ok(Abi { 1053 extern_token: input.parse()?, 1054 name: input.parse()?, 1055 }) 1056 } 1057 } 1058 1059 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] 1060 impl Parse for Option<Abi> { parse(input: ParseStream) -> Result<Self>1061 fn parse(input: ParseStream) -> Result<Self> { 1062 if input.peek(Token![extern]) { 1063 input.parse().map(Some) 1064 } else { 1065 Ok(None) 1066 } 1067 } 1068 } 1069 } 1070 1071 #[cfg(feature = "printing")] 1072 mod printing { 1073 use super::*; 1074 use crate::attr::FilterAttrs; 1075 use crate::print::TokensOrDefault; 1076 use proc_macro2::TokenStream; 1077 use quote::{ToTokens, TokenStreamExt}; 1078 1079 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1080 impl ToTokens for TypeSlice { 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 }); 1085 } 1086 } 1087 1088 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1089 impl ToTokens for TypeArray { to_tokens(&self, tokens: &mut TokenStream)1090 fn to_tokens(&self, tokens: &mut TokenStream) { 1091 self.bracket_token.surround(tokens, |tokens| { 1092 self.elem.to_tokens(tokens); 1093 self.semi_token.to_tokens(tokens); 1094 self.len.to_tokens(tokens); 1095 }); 1096 } 1097 } 1098 1099 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1100 impl ToTokens for TypePtr { to_tokens(&self, tokens: &mut TokenStream)1101 fn to_tokens(&self, tokens: &mut TokenStream) { 1102 self.star_token.to_tokens(tokens); 1103 match &self.mutability { 1104 Some(tok) => tok.to_tokens(tokens), 1105 None => { 1106 TokensOrDefault(&self.const_token).to_tokens(tokens); 1107 } 1108 } 1109 self.elem.to_tokens(tokens); 1110 } 1111 } 1112 1113 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1114 impl ToTokens for TypeReference { to_tokens(&self, tokens: &mut TokenStream)1115 fn to_tokens(&self, tokens: &mut TokenStream) { 1116 self.and_token.to_tokens(tokens); 1117 self.lifetime.to_tokens(tokens); 1118 self.mutability.to_tokens(tokens); 1119 self.elem.to_tokens(tokens); 1120 } 1121 } 1122 1123 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1124 impl ToTokens for TypeBareFn { to_tokens(&self, tokens: &mut TokenStream)1125 fn to_tokens(&self, tokens: &mut TokenStream) { 1126 self.lifetimes.to_tokens(tokens); 1127 self.unsafety.to_tokens(tokens); 1128 self.abi.to_tokens(tokens); 1129 self.fn_token.to_tokens(tokens); 1130 self.paren_token.surround(tokens, |tokens| { 1131 self.inputs.to_tokens(tokens); 1132 if let Some(variadic) = &self.variadic { 1133 if !self.inputs.empty_or_trailing() { 1134 let span = variadic.dots.spans[0]; 1135 Token![,](span).to_tokens(tokens); 1136 } 1137 variadic.to_tokens(tokens); 1138 } 1139 }); 1140 self.output.to_tokens(tokens); 1141 } 1142 } 1143 1144 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1145 impl ToTokens for TypeNever { to_tokens(&self, tokens: &mut TokenStream)1146 fn to_tokens(&self, tokens: &mut TokenStream) { 1147 self.bang_token.to_tokens(tokens); 1148 } 1149 } 1150 1151 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1152 impl ToTokens for TypeTuple { to_tokens(&self, tokens: &mut TokenStream)1153 fn to_tokens(&self, tokens: &mut TokenStream) { 1154 self.paren_token.surround(tokens, |tokens| { 1155 self.elems.to_tokens(tokens); 1156 }); 1157 } 1158 } 1159 1160 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1161 impl ToTokens for TypePath { to_tokens(&self, tokens: &mut TokenStream)1162 fn to_tokens(&self, tokens: &mut TokenStream) { 1163 private::print_path(tokens, &self.qself, &self.path); 1164 } 1165 } 1166 1167 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1168 impl ToTokens for TypeTraitObject { to_tokens(&self, tokens: &mut TokenStream)1169 fn to_tokens(&self, tokens: &mut TokenStream) { 1170 self.dyn_token.to_tokens(tokens); 1171 self.bounds.to_tokens(tokens); 1172 } 1173 } 1174 1175 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1176 impl ToTokens for TypeImplTrait { to_tokens(&self, tokens: &mut TokenStream)1177 fn to_tokens(&self, tokens: &mut TokenStream) { 1178 self.impl_token.to_tokens(tokens); 1179 self.bounds.to_tokens(tokens); 1180 } 1181 } 1182 1183 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1184 impl ToTokens for TypeGroup { to_tokens(&self, tokens: &mut TokenStream)1185 fn to_tokens(&self, tokens: &mut TokenStream) { 1186 self.group_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 TypeParen { to_tokens(&self, tokens: &mut TokenStream)1194 fn to_tokens(&self, tokens: &mut TokenStream) { 1195 self.paren_token.surround(tokens, |tokens| { 1196 self.elem.to_tokens(tokens); 1197 }); 1198 } 1199 } 1200 1201 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1202 impl ToTokens for TypeInfer { to_tokens(&self, tokens: &mut TokenStream)1203 fn to_tokens(&self, tokens: &mut TokenStream) { 1204 self.underscore_token.to_tokens(tokens); 1205 } 1206 } 1207 1208 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1209 impl ToTokens for TypeMacro { to_tokens(&self, tokens: &mut TokenStream)1210 fn to_tokens(&self, tokens: &mut TokenStream) { 1211 self.mac.to_tokens(tokens); 1212 } 1213 } 1214 1215 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1216 impl ToTokens for ReturnType { to_tokens(&self, tokens: &mut TokenStream)1217 fn to_tokens(&self, tokens: &mut TokenStream) { 1218 match self { 1219 ReturnType::Default => {} 1220 ReturnType::Type(arrow, ty) => { 1221 arrow.to_tokens(tokens); 1222 ty.to_tokens(tokens); 1223 } 1224 } 1225 } 1226 } 1227 1228 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1229 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut TokenStream)1230 fn to_tokens(&self, tokens: &mut TokenStream) { 1231 tokens.append_all(self.attrs.outer()); 1232 if let Some((name, colon)) = &self.name { 1233 name.to_tokens(tokens); 1234 colon.to_tokens(tokens); 1235 } 1236 self.ty.to_tokens(tokens); 1237 } 1238 } 1239 1240 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1241 impl ToTokens for Variadic { to_tokens(&self, tokens: &mut TokenStream)1242 fn to_tokens(&self, tokens: &mut TokenStream) { 1243 tokens.append_all(self.attrs.outer()); 1244 self.dots.to_tokens(tokens); 1245 } 1246 } 1247 1248 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] 1249 impl ToTokens for Abi { to_tokens(&self, tokens: &mut TokenStream)1250 fn to_tokens(&self, tokens: &mut TokenStream) { 1251 self.extern_token.to_tokens(tokens); 1252 self.name.to_tokens(tokens); 1253 } 1254 } 1255 } 1256