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