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