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