1 use super::*; 2 use proc_macro2::TokenStream; 3 use punctuated::Punctuated; 4 #[cfg(feature = "extra-traits")] 5 use std::hash::{Hash, Hasher}; 6 #[cfg(feature = "extra-traits")] 7 use tt::TokenStreamHelper; 8 9 ast_enum_of_structs! { 10 /// The possible types that a Rust value could have. 11 /// 12 /// *This type is available if Syn is built with the `"derive"` or `"full"` 13 /// feature.* 14 /// 15 /// # Syntax tree enum 16 /// 17 /// This type is a [syntax tree enum]. 18 /// 19 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums 20 // 21 // TODO: change syntax-tree-enum link to an intra rustdoc link, currently 22 // blocked on https://github.com/rust-lang/rust/issues/62833 23 pub enum Type { 24 /// A dynamically sized slice type: `[T]`. 25 /// 26 /// *This type is available if Syn is built with the `"derive"` or 27 /// `"full"` feature.* 28 pub Slice(TypeSlice { 29 pub bracket_token: token::Bracket, 30 pub elem: Box<Type>, 31 }), 32 33 /// A fixed size array type: `[T; n]`. 34 /// 35 /// *This type is available if Syn is built with the `"derive"` or 36 /// `"full"` feature.* 37 pub Array(TypeArray { 38 pub bracket_token: token::Bracket, 39 pub elem: Box<Type>, 40 pub semi_token: Token![;], 41 pub len: Expr, 42 }), 43 44 /// A raw pointer type: `*const T` or `*mut T`. 45 /// 46 /// *This type is available if Syn is built with the `"derive"` or 47 /// `"full"` feature.* 48 pub Ptr(TypePtr { 49 pub star_token: Token![*], 50 pub const_token: Option<Token![const]>, 51 pub mutability: Option<Token![mut]>, 52 pub elem: Box<Type>, 53 }), 54 55 /// A reference type: `&'a T` or `&'a mut T`. 56 /// 57 /// *This type is available if Syn is built with the `"derive"` or 58 /// `"full"` feature.* 59 pub Reference(TypeReference { 60 pub and_token: Token![&], 61 pub lifetime: Option<Lifetime>, 62 pub mutability: Option<Token![mut]>, 63 pub elem: Box<Type>, 64 }), 65 66 /// A bare function type: `fn(usize) -> bool`. 67 /// 68 /// *This type is available if Syn is built with the `"derive"` or 69 /// `"full"` feature.* 70 pub BareFn(TypeBareFn { 71 pub lifetimes: Option<BoundLifetimes>, 72 pub unsafety: Option<Token![unsafe]>, 73 pub abi: Option<Abi>, 74 pub fn_token: Token![fn], 75 pub paren_token: token::Paren, 76 pub inputs: Punctuated<BareFnArg, Token![,]>, 77 pub variadic: Option<Token![...]>, 78 pub output: ReturnType, 79 }), 80 81 /// The never type: `!`. 82 /// 83 /// *This type is available if Syn is built with the `"derive"` or 84 /// `"full"` feature.* 85 pub Never(TypeNever { 86 pub bang_token: Token![!], 87 }), 88 89 /// A tuple type: `(A, B, C, String)`. 90 /// 91 /// *This type is available if Syn is built with the `"derive"` or 92 /// `"full"` feature.* 93 pub Tuple(TypeTuple { 94 pub paren_token: token::Paren, 95 pub elems: Punctuated<Type, Token![,]>, 96 }), 97 98 /// A path like `std::slice::Iter`, optionally qualified with a 99 /// self-type as in `<Vec<T> as SomeTrait>::Associated`. 100 /// 101 /// Type arguments are stored in the Path itself. 102 /// 103 /// *This type is available if Syn is built with the `"derive"` or 104 /// `"full"` feature.* 105 pub Path(TypePath { 106 pub qself: Option<QSelf>, 107 pub path: Path, 108 }), 109 110 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a 111 /// trait or a lifetime. 112 /// 113 /// *This type is available if Syn is built with the `"derive"` or 114 /// `"full"` feature.* 115 pub TraitObject(TypeTraitObject { 116 pub dyn_token: Option<Token![dyn]>, 117 pub bounds: Punctuated<TypeParamBound, Token![+]>, 118 }), 119 120 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or 121 /// a lifetime. 122 /// 123 /// *This type is available if Syn is built with the `"derive"` or 124 /// `"full"` feature.* 125 pub ImplTrait(TypeImplTrait { 126 pub impl_token: Token![impl], 127 pub bounds: Punctuated<TypeParamBound, Token![+]>, 128 }), 129 130 /// A parenthesized type equivalent to the inner type. 131 /// 132 /// *This type is available if Syn is built with the `"derive"` or 133 /// `"full"` feature.* 134 pub Paren(TypeParen { 135 pub paren_token: token::Paren, 136 pub elem: Box<Type>, 137 }), 138 139 /// A type contained within invisible delimiters. 140 /// 141 /// *This type is available if Syn is built with the `"derive"` or 142 /// `"full"` feature.* 143 pub Group(TypeGroup { 144 pub group_token: token::Group, 145 pub elem: Box<Type>, 146 }), 147 148 /// Indication that a type should be inferred by the compiler: `_`. 149 /// 150 /// *This type is available if Syn is built with the `"derive"` or 151 /// `"full"` feature.* 152 pub Infer(TypeInfer { 153 pub underscore_token: Token![_], 154 }), 155 156 /// A macro in the type position. 157 /// 158 /// *This type is available if Syn is built with the `"derive"` or 159 /// `"full"` feature.* 160 pub Macro(TypeMacro { 161 pub mac: Macro, 162 }), 163 164 /// Tokens in type position not interpreted by Syn. 165 /// 166 /// *This type is available if Syn is built with the `"derive"` or 167 /// `"full"` feature.* 168 pub Verbatim(TypeVerbatim #manual_extra_traits { 169 pub tts: TokenStream, 170 }), 171 } 172 } 173 174 #[cfg(feature = "extra-traits")] 175 impl Eq for TypeVerbatim {} 176 177 #[cfg(feature = "extra-traits")] 178 impl PartialEq for TypeVerbatim { eq(&self, other: &Self) -> bool179 fn eq(&self, other: &Self) -> bool { 180 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts) 181 } 182 } 183 184 #[cfg(feature = "extra-traits")] 185 impl Hash for TypeVerbatim { hash<H>(&self, state: &mut H) where H: Hasher,186 fn hash<H>(&self, state: &mut H) 187 where 188 H: Hasher, 189 { 190 TokenStreamHelper(&self.tts).hash(state); 191 } 192 } 193 194 ast_struct! { 195 /// The binary interface of a function: `extern "C"`. 196 /// 197 /// *This type is available if Syn is built with the `"derive"` or `"full"` 198 /// feature.* 199 pub struct Abi { 200 pub extern_token: Token![extern], 201 pub name: Option<LitStr>, 202 } 203 } 204 205 ast_struct! { 206 /// An argument in a function type: the `usize` in `fn(usize) -> bool`. 207 /// 208 /// *This type is available if Syn is built with the `"derive"` or `"full"` 209 /// feature.* 210 pub struct BareFnArg { 211 pub name: Option<(BareFnArgName, Token![:])>, 212 pub ty: Type, 213 } 214 } 215 216 ast_enum! { 217 /// Name of an argument in a function type: the `n` in `fn(n: usize)`. 218 /// 219 /// *This type is available if Syn is built with the `"derive"` or `"full"` 220 /// feature.* 221 pub enum BareFnArgName { 222 /// Argument given a name. 223 Named(Ident), 224 /// Argument not given a name, matched with `_`. 225 Wild(Token![_]), 226 } 227 } 228 229 ast_enum! { 230 /// Return type of a function signature. 231 /// 232 /// *This type is available if Syn is built with the `"derive"` or `"full"` 233 /// feature.* 234 pub enum ReturnType { 235 /// Return type is not specified. 236 /// 237 /// Functions default to `()` and closures default to type inference. 238 Default, 239 /// A particular type is returned. 240 Type(Token![->], Box<Type>), 241 } 242 } 243 244 #[cfg(feature = "parsing")] 245 pub mod parsing { 246 use super::*; 247 248 use parse::{Parse, ParseStream, Result}; 249 use path; 250 251 impl Parse for Type { parse(input: ParseStream) -> Result<Self>252 fn parse(input: ParseStream) -> Result<Self> { 253 ambig_ty(input, true) 254 } 255 } 256 257 impl Type { 258 /// In some positions, types may not contain the `+` character, to 259 /// disambiguate them. For example in the expression `1 as T`, T may not 260 /// contain a `+` character. 261 /// 262 /// This parser does not allow a `+`, while the default parser does. without_plus(input: ParseStream) -> Result<Self>263 pub fn without_plus(input: ParseStream) -> Result<Self> { 264 ambig_ty(input, false) 265 } 266 } 267 ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type>268 fn ambig_ty(input: ParseStream, allow_plus: bool) -> Result<Type> { 269 if input.peek(token::Group) { 270 return input.parse().map(Type::Group); 271 } 272 273 let mut lifetimes = None::<BoundLifetimes>; 274 let mut lookahead = input.lookahead1(); 275 if lookahead.peek(Token![for]) { 276 lifetimes = input.parse()?; 277 lookahead = input.lookahead1(); 278 if !lookahead.peek(Ident) 279 && !lookahead.peek(Token![fn]) 280 && !lookahead.peek(Token![unsafe]) 281 && !lookahead.peek(Token![extern]) 282 && !lookahead.peek(Token![super]) 283 && !lookahead.peek(Token![self]) 284 && !lookahead.peek(Token![Self]) 285 && !lookahead.peek(Token![crate]) 286 { 287 return Err(lookahead.error()); 288 } 289 } 290 291 if lookahead.peek(token::Paren) { 292 let content; 293 let paren_token = parenthesized!(content in input); 294 if content.is_empty() { 295 return Ok(Type::Tuple(TypeTuple { 296 paren_token: paren_token, 297 elems: Punctuated::new(), 298 })); 299 } 300 if content.peek(Lifetime) { 301 return Ok(Type::Paren(TypeParen { 302 paren_token: paren_token, 303 elem: Box::new(Type::TraitObject(content.parse()?)), 304 })); 305 } 306 if content.peek(Token![?]) { 307 return Ok(Type::TraitObject(TypeTraitObject { 308 dyn_token: None, 309 bounds: { 310 let mut bounds = Punctuated::new(); 311 bounds.push_value(TypeParamBound::Trait(TraitBound { 312 paren_token: Some(paren_token), 313 ..content.parse()? 314 })); 315 while let Some(plus) = input.parse()? { 316 bounds.push_punct(plus); 317 bounds.push_value(input.parse()?); 318 } 319 bounds 320 }, 321 })); 322 } 323 let first: Type = content.parse()?; 324 if content.peek(Token![,]) { 325 return Ok(Type::Tuple(TypeTuple { 326 paren_token: paren_token, 327 elems: { 328 let mut elems = Punctuated::new(); 329 elems.push_value(first); 330 elems.push_punct(content.parse()?); 331 let rest: Punctuated<Type, Token![,]> = 332 content.parse_terminated(Parse::parse)?; 333 elems.extend(rest); 334 elems 335 }, 336 })); 337 } 338 if allow_plus && input.peek(Token![+]) { 339 loop { 340 let first = match first { 341 Type::Path(TypePath { qself: None, path }) => { 342 TypeParamBound::Trait(TraitBound { 343 paren_token: Some(paren_token), 344 modifier: TraitBoundModifier::None, 345 lifetimes: None, 346 path: path, 347 }) 348 } 349 Type::TraitObject(TypeTraitObject { 350 dyn_token: None, 351 ref bounds, 352 }) => { 353 if bounds.len() > 1 || bounds.trailing_punct() { 354 break; 355 } 356 match first { 357 Type::TraitObject(TypeTraitObject { bounds, .. }) => { 358 match bounds.into_iter().next().unwrap() { 359 TypeParamBound::Trait(trait_bound) => { 360 TypeParamBound::Trait(TraitBound { 361 paren_token: Some(paren_token), 362 ..trait_bound 363 }) 364 } 365 other => other, 366 } 367 } 368 _ => unreachable!(), 369 } 370 } 371 _ => break, 372 }; 373 return Ok(Type::TraitObject(TypeTraitObject { 374 dyn_token: None, 375 bounds: { 376 let mut bounds = Punctuated::new(); 377 bounds.push_value(first); 378 while let Some(plus) = input.parse()? { 379 bounds.push_punct(plus); 380 bounds.push_value(input.parse()?); 381 } 382 bounds 383 }, 384 })); 385 } 386 } 387 Ok(Type::Paren(TypeParen { 388 paren_token: paren_token, 389 elem: Box::new(first), 390 })) 391 } else if lookahead.peek(Token![fn]) 392 || lookahead.peek(Token![unsafe]) 393 || lookahead.peek(Token![extern]) && !input.peek2(Token![::]) 394 { 395 let mut bare_fn: TypeBareFn = input.parse()?; 396 bare_fn.lifetimes = lifetimes; 397 Ok(Type::BareFn(bare_fn)) 398 } else if lookahead.peek(Ident) 399 || input.peek(Token![super]) 400 || input.peek(Token![self]) 401 || input.peek(Token![Self]) 402 || input.peek(Token![crate]) 403 || input.peek(Token![extern]) 404 || lookahead.peek(Token![::]) 405 || lookahead.peek(Token![<]) 406 { 407 if input.peek(Token![dyn]) { 408 let mut trait_object: TypeTraitObject = input.parse()?; 409 if lifetimes.is_some() { 410 match *trait_object.bounds.iter_mut().next().unwrap() { 411 TypeParamBound::Trait(ref mut trait_bound) => { 412 trait_bound.lifetimes = lifetimes; 413 } 414 TypeParamBound::Lifetime(_) => unreachable!(), 415 } 416 } 417 return Ok(Type::TraitObject(trait_object)); 418 } 419 420 let ty: TypePath = input.parse()?; 421 if ty.qself.is_some() { 422 return Ok(Type::Path(ty)); 423 } 424 425 if input.peek(Token![!]) && !input.peek(Token![!=]) { 426 let mut contains_arguments = false; 427 for segment in &ty.path.segments { 428 match segment.arguments { 429 PathArguments::None => {} 430 PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => { 431 contains_arguments = true; 432 } 433 } 434 } 435 436 if !contains_arguments { 437 let bang_token: Token![!] = input.parse()?; 438 let (delimiter, tts) = mac::parse_delimiter(input)?; 439 return Ok(Type::Macro(TypeMacro { 440 mac: Macro { 441 path: ty.path, 442 bang_token: bang_token, 443 delimiter: delimiter, 444 tts: tts, 445 }, 446 })); 447 } 448 } 449 450 if lifetimes.is_some() || allow_plus && input.peek(Token![+]) { 451 let mut bounds = Punctuated::new(); 452 bounds.push_value(TypeParamBound::Trait(TraitBound { 453 paren_token: None, 454 modifier: TraitBoundModifier::None, 455 lifetimes: lifetimes, 456 path: ty.path, 457 })); 458 if allow_plus { 459 while input.peek(Token![+]) { 460 bounds.push_punct(input.parse()?); 461 if input.peek(Token![>]) { 462 break; 463 } 464 bounds.push_value(input.parse()?); 465 } 466 } 467 return Ok(Type::TraitObject(TypeTraitObject { 468 dyn_token: None, 469 bounds: bounds, 470 })); 471 } 472 473 Ok(Type::Path(ty)) 474 } else if lookahead.peek(token::Bracket) { 475 let content; 476 let bracket_token = bracketed!(content in input); 477 let elem: Type = content.parse()?; 478 if content.peek(Token![;]) { 479 Ok(Type::Array(TypeArray { 480 bracket_token: bracket_token, 481 elem: Box::new(elem), 482 semi_token: content.parse()?, 483 len: content.parse()?, 484 })) 485 } else { 486 Ok(Type::Slice(TypeSlice { 487 bracket_token: bracket_token, 488 elem: Box::new(elem), 489 })) 490 } 491 } else if lookahead.peek(Token![*]) { 492 input.parse().map(Type::Ptr) 493 } else if lookahead.peek(Token![&]) { 494 input.parse().map(Type::Reference) 495 } else if lookahead.peek(Token![!]) && !input.peek(Token![=]) { 496 input.parse().map(Type::Never) 497 } else if lookahead.peek(Token![impl]) { 498 input.parse().map(Type::ImplTrait) 499 } else if lookahead.peek(Token![_]) { 500 input.parse().map(Type::Infer) 501 } else if lookahead.peek(Lifetime) { 502 input.parse().map(Type::TraitObject) 503 } else { 504 Err(lookahead.error()) 505 } 506 } 507 508 impl Parse for TypeSlice { parse(input: ParseStream) -> Result<Self>509 fn parse(input: ParseStream) -> Result<Self> { 510 let content; 511 Ok(TypeSlice { 512 bracket_token: bracketed!(content in input), 513 elem: content.parse()?, 514 }) 515 } 516 } 517 518 impl Parse for TypeArray { parse(input: ParseStream) -> Result<Self>519 fn parse(input: ParseStream) -> Result<Self> { 520 let content; 521 Ok(TypeArray { 522 bracket_token: bracketed!(content in input), 523 elem: content.parse()?, 524 semi_token: content.parse()?, 525 len: content.parse()?, 526 }) 527 } 528 } 529 530 impl Parse for TypePtr { parse(input: ParseStream) -> Result<Self>531 fn parse(input: ParseStream) -> Result<Self> { 532 let star_token: Token![*] = input.parse()?; 533 534 let lookahead = input.lookahead1(); 535 let (const_token, mutability) = if lookahead.peek(Token![const]) { 536 (Some(input.parse()?), None) 537 } else if lookahead.peek(Token![mut]) { 538 (None, Some(input.parse()?)) 539 } else { 540 return Err(lookahead.error()); 541 }; 542 543 Ok(TypePtr { 544 star_token: star_token, 545 const_token: const_token, 546 mutability: mutability, 547 elem: Box::new(input.call(Type::without_plus)?), 548 }) 549 } 550 } 551 552 impl Parse for TypeReference { parse(input: ParseStream) -> Result<Self>553 fn parse(input: ParseStream) -> Result<Self> { 554 Ok(TypeReference { 555 and_token: input.parse()?, 556 lifetime: input.parse()?, 557 mutability: input.parse()?, 558 // & binds tighter than +, so we don't allow + here. 559 elem: Box::new(input.call(Type::without_plus)?), 560 }) 561 } 562 } 563 564 impl Parse for TypeBareFn { parse(input: ParseStream) -> Result<Self>565 fn parse(input: ParseStream) -> Result<Self> { 566 let args; 567 let allow_variadic; 568 Ok(TypeBareFn { 569 lifetimes: input.parse()?, 570 unsafety: input.parse()?, 571 abi: input.parse()?, 572 fn_token: input.parse()?, 573 paren_token: parenthesized!(args in input), 574 inputs: { 575 let mut inputs = Punctuated::new(); 576 while !args.is_empty() && !args.peek(Token![...]) { 577 inputs.push_value(args.parse()?); 578 if args.is_empty() { 579 break; 580 } 581 inputs.push_punct(args.parse()?); 582 } 583 allow_variadic = inputs.empty_or_trailing(); 584 inputs 585 }, 586 variadic: { 587 if allow_variadic && args.peek(Token![...]) { 588 Some(args.parse()?) 589 } else { 590 None 591 } 592 }, 593 output: input.call(ReturnType::without_plus)?, 594 }) 595 } 596 } 597 598 impl Parse for TypeNever { parse(input: ParseStream) -> Result<Self>599 fn parse(input: ParseStream) -> Result<Self> { 600 Ok(TypeNever { 601 bang_token: input.parse()?, 602 }) 603 } 604 } 605 606 impl Parse for TypeInfer { parse(input: ParseStream) -> Result<Self>607 fn parse(input: ParseStream) -> Result<Self> { 608 Ok(TypeInfer { 609 underscore_token: input.parse()?, 610 }) 611 } 612 } 613 614 impl Parse for TypeTuple { parse(input: ParseStream) -> Result<Self>615 fn parse(input: ParseStream) -> Result<Self> { 616 let content; 617 Ok(TypeTuple { 618 paren_token: parenthesized!(content in input), 619 elems: content.parse_terminated(Type::parse)?, 620 }) 621 } 622 } 623 624 impl Parse for TypeMacro { parse(input: ParseStream) -> Result<Self>625 fn parse(input: ParseStream) -> Result<Self> { 626 Ok(TypeMacro { 627 mac: input.parse()?, 628 }) 629 } 630 } 631 632 impl Parse for TypePath { parse(input: ParseStream) -> Result<Self>633 fn parse(input: ParseStream) -> Result<Self> { 634 let (qself, mut path) = path::parsing::qpath(input, false)?; 635 636 if path.segments.last().unwrap().value().arguments.is_empty() 637 && input.peek(token::Paren) 638 { 639 let args: ParenthesizedGenericArguments = input.parse()?; 640 let parenthesized = PathArguments::Parenthesized(args); 641 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized; 642 } 643 644 Ok(TypePath { 645 qself: qself, 646 path: path, 647 }) 648 } 649 } 650 651 impl ReturnType { without_plus(input: ParseStream) -> Result<Self>652 pub fn without_plus(input: ParseStream) -> Result<Self> { 653 Self::parse(input, false) 654 } 655 parse(input: ParseStream, allow_plus: bool) -> Result<Self>656 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 657 if input.peek(Token![->]) { 658 let arrow = input.parse()?; 659 let ty = ambig_ty(input, allow_plus)?; 660 Ok(ReturnType::Type(arrow, Box::new(ty))) 661 } else { 662 Ok(ReturnType::Default) 663 } 664 } 665 } 666 667 impl Parse for ReturnType { parse(input: ParseStream) -> Result<Self>668 fn parse(input: ParseStream) -> Result<Self> { 669 Self::parse(input, true) 670 } 671 } 672 673 impl Parse for TypeTraitObject { parse(input: ParseStream) -> Result<Self>674 fn parse(input: ParseStream) -> Result<Self> { 675 Self::parse(input, true) 676 } 677 } 678 at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool679 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { 680 for bound in bounds { 681 if let TypeParamBound::Trait(_) = *bound { 682 return true; 683 } 684 } 685 false 686 } 687 688 impl TypeTraitObject { without_plus(input: ParseStream) -> Result<Self>689 pub fn without_plus(input: ParseStream) -> Result<Self> { 690 Self::parse(input, false) 691 } 692 693 // Only allow multiple trait references if allow_plus is true. parse(input: ParseStream, allow_plus: bool) -> Result<Self>694 pub fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 695 Ok(TypeTraitObject { 696 dyn_token: input.parse()?, 697 bounds: { 698 let mut bounds = Punctuated::new(); 699 if allow_plus { 700 loop { 701 bounds.push_value(input.parse()?); 702 if !input.peek(Token![+]) { 703 break; 704 } 705 bounds.push_punct(input.parse()?); 706 if input.peek(Token![>]) { 707 break; 708 } 709 } 710 } else { 711 bounds.push_value(input.parse()?); 712 } 713 // Just lifetimes like `'a + 'b` is not a TraitObject. 714 if !at_least_one_type(&bounds) { 715 return Err(input.error("expected at least one type")); 716 } 717 bounds 718 }, 719 }) 720 } 721 } 722 723 impl Parse for TypeImplTrait { parse(input: ParseStream) -> Result<Self>724 fn parse(input: ParseStream) -> Result<Self> { 725 Ok(TypeImplTrait { 726 impl_token: input.parse()?, 727 // NOTE: rust-lang/rust#34511 includes discussion about whether 728 // or not + should be allowed in ImplTrait directly without (). 729 bounds: { 730 let mut bounds = Punctuated::new(); 731 loop { 732 bounds.push_value(input.parse()?); 733 if !input.peek(Token![+]) { 734 break; 735 } 736 bounds.push_punct(input.parse()?); 737 } 738 bounds 739 }, 740 }) 741 } 742 } 743 744 impl Parse for TypeGroup { parse(input: ParseStream) -> Result<Self>745 fn parse(input: ParseStream) -> Result<Self> { 746 let group = private::parse_group(input)?; 747 Ok(TypeGroup { 748 group_token: group.token, 749 elem: group.content.parse()?, 750 }) 751 } 752 } 753 754 impl Parse for TypeParen { parse(input: ParseStream) -> Result<Self>755 fn parse(input: ParseStream) -> Result<Self> { 756 Self::parse(input, false) 757 } 758 } 759 760 impl TypeParen { parse(input: ParseStream, allow_plus: bool) -> Result<Self>761 fn parse(input: ParseStream, allow_plus: bool) -> Result<Self> { 762 let content; 763 Ok(TypeParen { 764 paren_token: parenthesized!(content in input), 765 elem: Box::new(ambig_ty(&content, allow_plus)?), 766 }) 767 } 768 } 769 770 impl Parse for BareFnArg { parse(input: ParseStream) -> Result<Self>771 fn parse(input: ParseStream) -> Result<Self> { 772 Ok(BareFnArg { 773 name: { 774 if (input.peek(Ident) || input.peek(Token![_])) 775 && !input.peek2(Token![::]) 776 && input.peek2(Token![:]) 777 { 778 let name: BareFnArgName = input.parse()?; 779 let colon: Token![:] = input.parse()?; 780 Some((name, colon)) 781 } else { 782 None 783 } 784 }, 785 ty: input.parse()?, 786 }) 787 } 788 } 789 790 impl Parse for BareFnArgName { parse(input: ParseStream) -> Result<Self>791 fn parse(input: ParseStream) -> Result<Self> { 792 let lookahead = input.lookahead1(); 793 if lookahead.peek(Ident) { 794 input.parse().map(BareFnArgName::Named) 795 } else if lookahead.peek(Token![_]) { 796 input.parse().map(BareFnArgName::Wild) 797 } else { 798 Err(lookahead.error()) 799 } 800 } 801 } 802 803 impl Parse for Abi { parse(input: ParseStream) -> Result<Self>804 fn parse(input: ParseStream) -> Result<Self> { 805 Ok(Abi { 806 extern_token: input.parse()?, 807 name: input.parse()?, 808 }) 809 } 810 } 811 812 impl Parse for Option<Abi> { parse(input: ParseStream) -> Result<Self>813 fn parse(input: ParseStream) -> Result<Self> { 814 if input.peek(Token![extern]) { 815 input.parse().map(Some) 816 } else { 817 Ok(None) 818 } 819 } 820 } 821 } 822 823 #[cfg(feature = "printing")] 824 mod printing { 825 use super::*; 826 827 use proc_macro2::TokenStream; 828 use quote::ToTokens; 829 830 use print::TokensOrDefault; 831 832 impl ToTokens for TypeSlice { to_tokens(&self, tokens: &mut TokenStream)833 fn to_tokens(&self, tokens: &mut TokenStream) { 834 self.bracket_token.surround(tokens, |tokens| { 835 self.elem.to_tokens(tokens); 836 }); 837 } 838 } 839 840 impl ToTokens for TypeArray { to_tokens(&self, tokens: &mut TokenStream)841 fn to_tokens(&self, tokens: &mut TokenStream) { 842 self.bracket_token.surround(tokens, |tokens| { 843 self.elem.to_tokens(tokens); 844 self.semi_token.to_tokens(tokens); 845 self.len.to_tokens(tokens); 846 }); 847 } 848 } 849 850 impl ToTokens for TypePtr { to_tokens(&self, tokens: &mut TokenStream)851 fn to_tokens(&self, tokens: &mut TokenStream) { 852 self.star_token.to_tokens(tokens); 853 match self.mutability { 854 Some(ref tok) => tok.to_tokens(tokens), 855 None => { 856 TokensOrDefault(&self.const_token).to_tokens(tokens); 857 } 858 } 859 self.elem.to_tokens(tokens); 860 } 861 } 862 863 impl ToTokens for TypeReference { to_tokens(&self, tokens: &mut TokenStream)864 fn to_tokens(&self, tokens: &mut TokenStream) { 865 self.and_token.to_tokens(tokens); 866 self.lifetime.to_tokens(tokens); 867 self.mutability.to_tokens(tokens); 868 self.elem.to_tokens(tokens); 869 } 870 } 871 872 impl ToTokens for TypeBareFn { to_tokens(&self, tokens: &mut TokenStream)873 fn to_tokens(&self, tokens: &mut TokenStream) { 874 self.lifetimes.to_tokens(tokens); 875 self.unsafety.to_tokens(tokens); 876 self.abi.to_tokens(tokens); 877 self.fn_token.to_tokens(tokens); 878 self.paren_token.surround(tokens, |tokens| { 879 self.inputs.to_tokens(tokens); 880 if let Some(ref variadic) = self.variadic { 881 if !self.inputs.empty_or_trailing() { 882 let span = variadic.spans[0]; 883 Token![,](span).to_tokens(tokens); 884 } 885 variadic.to_tokens(tokens); 886 } 887 }); 888 self.output.to_tokens(tokens); 889 } 890 } 891 892 impl ToTokens for TypeNever { to_tokens(&self, tokens: &mut TokenStream)893 fn to_tokens(&self, tokens: &mut TokenStream) { 894 self.bang_token.to_tokens(tokens); 895 } 896 } 897 898 impl ToTokens for TypeTuple { to_tokens(&self, tokens: &mut TokenStream)899 fn to_tokens(&self, tokens: &mut TokenStream) { 900 self.paren_token.surround(tokens, |tokens| { 901 self.elems.to_tokens(tokens); 902 }); 903 } 904 } 905 906 impl ToTokens for TypePath { to_tokens(&self, tokens: &mut TokenStream)907 fn to_tokens(&self, tokens: &mut TokenStream) { 908 private::print_path(tokens, &self.qself, &self.path); 909 } 910 } 911 912 impl ToTokens for TypeTraitObject { to_tokens(&self, tokens: &mut TokenStream)913 fn to_tokens(&self, tokens: &mut TokenStream) { 914 self.dyn_token.to_tokens(tokens); 915 self.bounds.to_tokens(tokens); 916 } 917 } 918 919 impl ToTokens for TypeImplTrait { to_tokens(&self, tokens: &mut TokenStream)920 fn to_tokens(&self, tokens: &mut TokenStream) { 921 self.impl_token.to_tokens(tokens); 922 self.bounds.to_tokens(tokens); 923 } 924 } 925 926 impl ToTokens for TypeGroup { to_tokens(&self, tokens: &mut TokenStream)927 fn to_tokens(&self, tokens: &mut TokenStream) { 928 self.group_token.surround(tokens, |tokens| { 929 self.elem.to_tokens(tokens); 930 }); 931 } 932 } 933 934 impl ToTokens for TypeParen { to_tokens(&self, tokens: &mut TokenStream)935 fn to_tokens(&self, tokens: &mut TokenStream) { 936 self.paren_token.surround(tokens, |tokens| { 937 self.elem.to_tokens(tokens); 938 }); 939 } 940 } 941 942 impl ToTokens for TypeInfer { to_tokens(&self, tokens: &mut TokenStream)943 fn to_tokens(&self, tokens: &mut TokenStream) { 944 self.underscore_token.to_tokens(tokens); 945 } 946 } 947 948 impl ToTokens for TypeMacro { to_tokens(&self, tokens: &mut TokenStream)949 fn to_tokens(&self, tokens: &mut TokenStream) { 950 self.mac.to_tokens(tokens); 951 } 952 } 953 954 impl ToTokens for TypeVerbatim { to_tokens(&self, tokens: &mut TokenStream)955 fn to_tokens(&self, tokens: &mut TokenStream) { 956 self.tts.to_tokens(tokens); 957 } 958 } 959 960 impl ToTokens for ReturnType { to_tokens(&self, tokens: &mut TokenStream)961 fn to_tokens(&self, tokens: &mut TokenStream) { 962 match *self { 963 ReturnType::Default => {} 964 ReturnType::Type(ref arrow, ref ty) => { 965 arrow.to_tokens(tokens); 966 ty.to_tokens(tokens); 967 } 968 } 969 } 970 } 971 972 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut TokenStream)973 fn to_tokens(&self, tokens: &mut TokenStream) { 974 if let Some((ref name, ref colon)) = self.name { 975 name.to_tokens(tokens); 976 colon.to_tokens(tokens); 977 } 978 self.ty.to_tokens(tokens); 979 } 980 } 981 982 impl ToTokens for BareFnArgName { to_tokens(&self, tokens: &mut TokenStream)983 fn to_tokens(&self, tokens: &mut TokenStream) { 984 match *self { 985 BareFnArgName::Named(ref t) => t.to_tokens(tokens), 986 BareFnArgName::Wild(ref t) => t.to_tokens(tokens), 987 } 988 } 989 } 990 991 impl ToTokens for Abi { to_tokens(&self, tokens: &mut TokenStream)992 fn to_tokens(&self, tokens: &mut TokenStream) { 993 self.extern_token.to_tokens(tokens); 994 self.name.to_tokens(tokens); 995 } 996 } 997 } 998