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