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