1 // Copyright 2018 Syn Developers 2 // 3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 6 // option. This file may not be copied, modified, or distributed 7 // except according to those terms. 8 9 use super::*; 10 use proc_macro2::TokenStream; 11 use punctuated::Punctuated; 12 #[cfg(feature = "extra-traits")] 13 use std::hash::{Hash, Hasher}; 14 #[cfg(feature = "extra-traits")] 15 use tt::TokenStreamHelper; 16 17 ast_enum_of_structs! { 18 /// The possible types that a Rust value could have. 19 /// 20 /// *This type is available if Syn is built with the `"derive"` or `"full"` 21 /// feature.* 22 /// 23 /// # Syntax tree enum 24 /// 25 /// This type is a [syntax tree enum]. 26 /// 27 /// [syntax tree enum]: enum.Expr.html#syntax-tree-enums 28 pub enum Type { 29 /// A dynamically sized slice type: `[T]`. 30 /// 31 /// *This type is available if Syn is built with the `"derive"` or 32 /// `"full"` feature.* 33 pub Slice(TypeSlice { 34 pub bracket_token: token::Bracket, 35 pub elem: Box<Type>, 36 }), 37 38 /// A fixed size array type: `[T; n]`. 39 /// 40 /// *This type is available if Syn is built with the `"derive"` or 41 /// `"full"` feature.* 42 pub Array(TypeArray { 43 pub bracket_token: token::Bracket, 44 pub elem: Box<Type>, 45 pub semi_token: Token![;], 46 pub len: Expr, 47 }), 48 49 /// A raw pointer type: `*const T` or `*mut T`. 50 /// 51 /// *This type is available if Syn is built with the `"derive"` or 52 /// `"full"` feature.* 53 pub Ptr(TypePtr { 54 pub star_token: Token![*], 55 pub const_token: Option<Token![const]>, 56 pub mutability: Option<Token![mut]>, 57 pub elem: Box<Type>, 58 }), 59 60 /// A reference type: `&'a T` or `&'a mut T`. 61 /// 62 /// *This type is available if Syn is built with the `"derive"` or 63 /// `"full"` feature.* 64 pub Reference(TypeReference { 65 pub and_token: Token![&], 66 pub lifetime: Option<Lifetime>, 67 pub mutability: Option<Token![mut]>, 68 pub elem: Box<Type>, 69 }), 70 71 /// A bare function type: `fn(usize) -> bool`. 72 /// 73 /// *This type is available if Syn is built with the `"derive"` or 74 /// `"full"` feature.* 75 pub BareFn(TypeBareFn { 76 pub unsafety: Option<Token![unsafe]>, 77 pub abi: Option<Abi>, 78 pub fn_token: Token![fn], 79 pub lifetimes: Option<BoundLifetimes>, 80 pub paren_token: token::Paren, 81 pub inputs: Punctuated<BareFnArg, Token![,]>, 82 pub variadic: Option<Token![...]>, 83 pub output: ReturnType, 84 }), 85 86 /// The never type: `!`. 87 /// 88 /// *This type is available if Syn is built with the `"derive"` or 89 /// `"full"` feature.* 90 pub Never(TypeNever { 91 pub bang_token: Token![!], 92 }), 93 94 /// A tuple type: `(A, B, C, String)`. 95 /// 96 /// *This type is available if Syn is built with the `"derive"` or 97 /// `"full"` feature.* 98 pub Tuple(TypeTuple { 99 pub paren_token: token::Paren, 100 pub elems: Punctuated<Type, Token![,]>, 101 }), 102 103 /// A path like `std::slice::Iter`, optionally qualified with a 104 /// self-type as in `<Vec<T> as SomeTrait>::Associated`. 105 /// 106 /// Type arguments are stored in the Path itself. 107 /// 108 /// *This type is available if Syn is built with the `"derive"` or 109 /// `"full"` feature.* 110 pub Path(TypePath { 111 pub qself: Option<QSelf>, 112 pub path: Path, 113 }), 114 115 /// A trait object type `Bound1 + Bound2 + Bound3` where `Bound` is a 116 /// trait or a lifetime. 117 /// 118 /// *This type is available if Syn is built with the `"derive"` or 119 /// `"full"` feature.* 120 pub TraitObject(TypeTraitObject { 121 pub dyn_token: Option<Token![dyn]>, 122 pub bounds: Punctuated<TypeParamBound, Token![+]>, 123 }), 124 125 /// An `impl Bound1 + Bound2 + Bound3` type where `Bound` is a trait or 126 /// a lifetime. 127 /// 128 /// *This type is available if Syn is built with the `"derive"` or 129 /// `"full"` feature.* 130 pub ImplTrait(TypeImplTrait { 131 pub impl_token: Token![impl], 132 pub bounds: Punctuated<TypeParamBound, Token![+]>, 133 }), 134 135 /// A parenthesized type equivalent to the inner type. 136 /// 137 /// *This type is available if Syn is built with the `"derive"` or 138 /// `"full"` feature.* 139 pub Paren(TypeParen { 140 pub paren_token: token::Paren, 141 pub elem: Box<Type>, 142 }), 143 144 /// A type contained within invisible delimiters. 145 /// 146 /// *This type is available if Syn is built with the `"derive"` or 147 /// `"full"` feature.* 148 pub Group(TypeGroup { 149 pub group_token: token::Group, 150 pub elem: Box<Type>, 151 }), 152 153 /// Indication that a type should be inferred by the compiler: `_`. 154 /// 155 /// *This type is available if Syn is built with the `"derive"` or 156 /// `"full"` feature.* 157 pub Infer(TypeInfer { 158 pub underscore_token: Token![_], 159 }), 160 161 /// A macro in the type position. 162 /// 163 /// *This type is available if Syn is built with the `"derive"` or 164 /// `"full"` feature.* 165 pub Macro(TypeMacro { 166 pub mac: Macro, 167 }), 168 169 /// Tokens in type position not interpreted by Syn. 170 /// 171 /// *This type is available if Syn is built with the `"derive"` or 172 /// `"full"` feature.* 173 pub Verbatim(TypeVerbatim #manual_extra_traits { 174 pub tts: TokenStream, 175 }), 176 } 177 } 178 179 #[cfg(feature = "extra-traits")] 180 impl Eq for TypeVerbatim {} 181 182 #[cfg(feature = "extra-traits")] 183 impl PartialEq for TypeVerbatim { eq(&self, other: &Self) -> bool184 fn eq(&self, other: &Self) -> bool { 185 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts) 186 } 187 } 188 189 #[cfg(feature = "extra-traits")] 190 impl Hash for TypeVerbatim { hash<H>(&self, state: &mut H) where H: Hasher,191 fn hash<H>(&self, state: &mut H) 192 where 193 H: Hasher, 194 { 195 TokenStreamHelper(&self.tts).hash(state); 196 } 197 } 198 199 ast_struct! { 200 /// The binary interface of a function: `extern "C"`. 201 /// 202 /// *This type is available if Syn is built with the `"derive"` or `"full"` 203 /// feature.* 204 pub struct Abi { 205 pub extern_token: Token![extern], 206 pub name: Option<LitStr>, 207 } 208 } 209 210 ast_struct! { 211 /// An argument in a function type: the `usize` in `fn(usize) -> bool`. 212 /// 213 /// *This type is available if Syn is built with the `"derive"` or `"full"` 214 /// feature.* 215 pub struct BareFnArg { 216 pub name: Option<(BareFnArgName, Token![:])>, 217 pub ty: Type, 218 } 219 } 220 221 ast_enum! { 222 /// Name of an argument in a function type: the `n` in `fn(n: usize)`. 223 /// 224 /// *This type is available if Syn is built with the `"derive"` or `"full"` 225 /// feature.* 226 pub enum BareFnArgName { 227 /// Argument given a name. 228 Named(Ident), 229 /// Argument not given a name, matched with `_`. 230 Wild(Token![_]), 231 } 232 } 233 234 ast_enum! { 235 /// Return type of a function signature. 236 /// 237 /// *This type is available if Syn is built with the `"derive"` or `"full"` 238 /// feature.* 239 pub enum ReturnType { 240 /// Return type is not specified. 241 /// 242 /// Functions default to `()` and closures default to type inference. 243 Default, 244 /// A particular type is returned. 245 Type(Token![->], Box<Type>), 246 } 247 } 248 249 #[cfg(feature = "parsing")] 250 pub mod parsing { 251 use super::*; 252 use path::parsing::qpath; 253 use synom::Synom; 254 255 impl Synom for Type { 256 named!(parse -> Self, call!(ambig_ty, true)); 257 description() -> Option<&'static str>258 fn description() -> Option<&'static str> { 259 Some("type") 260 } 261 } 262 263 impl Type { 264 /// In some positions, types may not contain the `+` character, to 265 /// disambiguate them. For example in the expression `1 as T`, T may not 266 /// contain a `+` character. 267 /// 268 /// This parser does not allow a `+`, while the default parser does. 269 named!(pub without_plus -> Self, call!(ambig_ty, false)); 270 } 271 272 named!(ambig_ty(allow_plus: bool) -> Type, alt!( 273 syn!(TypeGroup) => { Type::Group } 274 | 275 // must be before TypeTuple 276 call!(TypeParen::parse, allow_plus) => { Type::Paren } 277 | 278 // must be before TypePath 279 syn!(TypeMacro) => { Type::Macro } 280 | 281 // must be before TypeTraitObject 282 call!(TypePath::parse, allow_plus) => { Type::Path } 283 | 284 // Don't try parsing more than one trait bound if we aren't allowing it. 285 // must be before TypeTuple 286 call!(TypeTraitObject::parse, allow_plus) => { Type::TraitObject } 287 | 288 syn!(TypeSlice) => { Type::Slice } 289 | 290 syn!(TypeArray) => { Type::Array } 291 | 292 syn!(TypePtr) => { Type::Ptr } 293 | 294 syn!(TypeReference) => { Type::Reference } 295 | 296 syn!(TypeBareFn) => { Type::BareFn } 297 | 298 syn!(TypeNever) => { Type::Never } 299 | 300 syn!(TypeTuple) => { Type::Tuple } 301 | 302 syn!(TypeImplTrait) => { Type::ImplTrait } 303 | 304 syn!(TypeInfer) => { Type::Infer } 305 )); 306 307 impl Synom for TypeSlice { 308 named!(parse -> Self, map!( 309 brackets!(syn!(Type)), 310 |(b, ty)| TypeSlice { 311 elem: Box::new(ty), 312 bracket_token: b, 313 } 314 )); 315 description() -> Option<&'static str>316 fn description() -> Option<&'static str> { 317 Some("slice type") 318 } 319 } 320 321 impl Synom for TypeArray { 322 named!(parse -> Self, map!( 323 brackets!(do_parse!( 324 elem: syn!(Type) >> 325 semi: punct!(;) >> 326 len: syn!(Expr) >> 327 (elem, semi, len) 328 )), 329 |(brackets, (elem, semi, len))| { 330 TypeArray { 331 elem: Box::new(elem), 332 len: len, 333 bracket_token: brackets, 334 semi_token: semi, 335 } 336 } 337 )); 338 description() -> Option<&'static str>339 fn description() -> Option<&'static str> { 340 Some("array type") 341 } 342 } 343 344 impl Synom for TypePtr { 345 named!(parse -> Self, do_parse!( 346 star: punct!(*) >> 347 mutability: alt!( 348 keyword!(const) => { |c| (None, Some(c)) } 349 | 350 keyword!(mut) => { |m| (Some(m), None) } 351 ) >> 352 target: call!(Type::without_plus) >> 353 (TypePtr { 354 const_token: mutability.1, 355 star_token: star, 356 mutability: mutability.0, 357 elem: Box::new(target), 358 }) 359 )); 360 description() -> Option<&'static str>361 fn description() -> Option<&'static str> { 362 Some("raw pointer type") 363 } 364 } 365 366 impl Synom for TypeReference { 367 named!(parse -> Self, do_parse!( 368 amp: punct!(&) >> 369 life: option!(syn!(Lifetime)) >> 370 mutability: option!(keyword!(mut)) >> 371 // & binds tighter than +, so we don't allow + here. 372 target: call!(Type::without_plus) >> 373 (TypeReference { 374 lifetime: life, 375 mutability: mutability, 376 elem: Box::new(target), 377 and_token: amp, 378 }) 379 )); 380 description() -> Option<&'static str>381 fn description() -> Option<&'static str> { 382 Some("reference type") 383 } 384 } 385 386 impl Synom for TypeBareFn { 387 named!(parse -> Self, do_parse!( 388 lifetimes: option!(syn!(BoundLifetimes)) >> 389 unsafety: option!(keyword!(unsafe)) >> 390 abi: option!(syn!(Abi)) >> 391 fn_: keyword!(fn) >> 392 parens: parens!(do_parse!( 393 inputs: call!(Punctuated::parse_terminated) >> 394 variadic: option!(cond_reduce!(inputs.empty_or_trailing(), punct!(...))) >> 395 (inputs, variadic) 396 )) >> 397 output: syn!(ReturnType) >> 398 (TypeBareFn { 399 unsafety: unsafety, 400 abi: abi, 401 lifetimes: lifetimes, 402 output: output, 403 variadic: (parens.1).1, 404 fn_token: fn_, 405 paren_token: parens.0, 406 inputs: (parens.1).0, 407 }) 408 )); 409 description() -> Option<&'static str>410 fn description() -> Option<&'static str> { 411 Some("`fn` type") 412 } 413 } 414 415 impl Synom for TypeNever { 416 named!(parse -> Self, map!( 417 punct!(!), 418 |b| TypeNever { bang_token: b } 419 )); 420 description() -> Option<&'static str>421 fn description() -> Option<&'static str> { 422 Some("never type: `!`") 423 } 424 } 425 426 impl Synom for TypeInfer { 427 named!(parse -> Self, map!( 428 punct!(_), 429 |u| TypeInfer { underscore_token: u } 430 )); 431 description() -> Option<&'static str>432 fn description() -> Option<&'static str> { 433 Some("inferred type: `_`") 434 } 435 } 436 437 impl Synom for TypeTuple { 438 named!(parse -> Self, do_parse!( 439 data: parens!(Punctuated::parse_terminated) >> 440 (TypeTuple { 441 paren_token: data.0, 442 elems: data.1, 443 }) 444 )); 445 description() -> Option<&'static str>446 fn description() -> Option<&'static str> { 447 Some("tuple type") 448 } 449 } 450 451 impl Synom for TypeMacro { 452 named!(parse -> Self, map!(syn!(Macro), |mac| TypeMacro { mac: mac })); 453 description() -> Option<&'static str>454 fn description() -> Option<&'static str> { 455 Some("macro invocation") 456 } 457 } 458 459 impl Synom for TypePath { 460 named!(parse -> Self, call!(Self::parse, false)); 461 description() -> Option<&'static str>462 fn description() -> Option<&'static str> { 463 Some("type path") 464 } 465 } 466 467 impl TypePath { 468 named!(parse(allow_plus: bool) -> Self, do_parse!( 469 qpath: qpath >> 470 parenthesized: option!(cond_reduce!( 471 qpath.1.segments.last().unwrap().value().arguments.is_empty(), 472 syn!(ParenthesizedGenericArguments) 473 )) >> 474 cond!(allow_plus, not!(punct!(+))) >> 475 ({ 476 let (qself, mut path) = qpath; 477 if let Some(parenthesized) = parenthesized { 478 let parenthesized = PathArguments::Parenthesized(parenthesized); 479 path.segments.last_mut().unwrap().value_mut().arguments = parenthesized; 480 } 481 TypePath { qself: qself, path: path } 482 }) 483 )); 484 } 485 486 impl Synom for ReturnType { 487 named!(parse -> Self, alt!( 488 do_parse!( 489 arrow: punct!(->) >> 490 ty: syn!(Type) >> 491 (ReturnType::Type(arrow, Box::new(ty))) 492 ) 493 | 494 epsilon!() => { |_| ReturnType::Default } 495 )); 496 description() -> Option<&'static str>497 fn description() -> Option<&'static str> { 498 Some("return type") 499 } 500 } 501 502 impl Synom for TypeTraitObject { 503 named!(parse -> Self, call!(Self::parse, true)); 504 description() -> Option<&'static str>505 fn description() -> Option<&'static str> { 506 Some("trait object type") 507 } 508 } 509 at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool510 fn at_least_one_type(bounds: &Punctuated<TypeParamBound, Token![+]>) -> bool { 511 for bound in bounds { 512 if let TypeParamBound::Trait(_) = *bound { 513 return true; 514 } 515 } 516 false 517 } 518 519 impl TypeTraitObject { 520 named!(pub without_plus -> Self, call!(Self::parse, false)); 521 522 // Only allow multiple trait references if allow_plus is true. 523 named!(parse(allow_plus: bool) -> Self, do_parse!( 524 dyn_token: option!(keyword!(dyn)) >> 525 bounds: alt!( 526 cond_reduce!(allow_plus, Punctuated::parse_terminated_nonempty) 527 | 528 syn!(TypeParamBound) => {|x| { 529 let mut bounds = Punctuated::new(); 530 bounds.push_value(x); 531 bounds 532 }} 533 ) >> 534 // Just lifetimes like `'a + 'b` is not a TraitObject. 535 cond_reduce!(at_least_one_type(&bounds)) >> 536 (TypeTraitObject { 537 dyn_token: dyn_token, 538 bounds: bounds, 539 }) 540 )); 541 } 542 543 impl Synom for TypeImplTrait { 544 named!(parse -> Self, do_parse!( 545 impl_: keyword!(impl) >> 546 // NOTE: rust-lang/rust#34511 includes discussion about whether or 547 // not + should be allowed in ImplTrait directly without (). 548 elem: call!(Punctuated::parse_terminated_nonempty) >> 549 (TypeImplTrait { 550 impl_token: impl_, 551 bounds: elem, 552 }) 553 )); 554 description() -> Option<&'static str>555 fn description() -> Option<&'static str> { 556 Some("`impl Trait` type") 557 } 558 } 559 560 impl Synom for TypeGroup { 561 named!(parse -> Self, do_parse!( 562 data: grouped!(syn!(Type)) >> 563 (TypeGroup { 564 group_token: data.0, 565 elem: Box::new(data.1), 566 }) 567 )); 568 description() -> Option<&'static str>569 fn description() -> Option<&'static str> { 570 Some("type surrounded by invisible delimiters") 571 } 572 } 573 574 impl Synom for TypeParen { 575 named!(parse -> Self, call!(Self::parse, false)); 576 description() -> Option<&'static str>577 fn description() -> Option<&'static str> { 578 Some("parenthesized type") 579 } 580 } 581 582 impl TypeParen { 583 named!(parse(allow_plus: bool) -> Self, do_parse!( 584 data: parens!(syn!(Type)) >> 585 cond!(allow_plus, not!(punct!(+))) >> 586 (TypeParen { 587 paren_token: data.0, 588 elem: Box::new(data.1), 589 }) 590 )); 591 } 592 593 impl Synom for BareFnArg { 594 named!(parse -> Self, do_parse!( 595 name: option!(do_parse!( 596 name: syn!(BareFnArgName) >> 597 not!(punct!(::)) >> 598 colon: punct!(:) >> 599 (name, colon) 600 )) >> 601 ty: syn!(Type) >> 602 (BareFnArg { 603 name: name, 604 ty: ty, 605 }) 606 )); 607 description() -> Option<&'static str>608 fn description() -> Option<&'static str> { 609 Some("function type argument") 610 } 611 } 612 613 impl Synom for BareFnArgName { 614 named!(parse -> Self, alt!( 615 map!(syn!(Ident), BareFnArgName::Named) 616 | 617 map!(punct!(_), BareFnArgName::Wild) 618 )); 619 description() -> Option<&'static str>620 fn description() -> Option<&'static str> { 621 Some("function argument name") 622 } 623 } 624 625 impl Synom for Abi { 626 named!(parse -> Self, do_parse!( 627 extern_: keyword!(extern) >> 628 name: option!(syn!(LitStr)) >> 629 (Abi { 630 extern_token: extern_, 631 name: name, 632 }) 633 )); 634 description() -> Option<&'static str>635 fn description() -> Option<&'static str> { 636 Some("`extern` ABI qualifier") 637 } 638 } 639 } 640 641 #[cfg(feature = "printing")] 642 mod printing { 643 use super::*; 644 use quote::{ToTokens, Tokens}; 645 646 impl ToTokens for TypeSlice { to_tokens(&self, tokens: &mut Tokens)647 fn to_tokens(&self, tokens: &mut Tokens) { 648 self.bracket_token.surround(tokens, |tokens| { 649 self.elem.to_tokens(tokens); 650 }); 651 } 652 } 653 654 impl ToTokens for TypeArray { to_tokens(&self, tokens: &mut Tokens)655 fn to_tokens(&self, tokens: &mut Tokens) { 656 self.bracket_token.surround(tokens, |tokens| { 657 self.elem.to_tokens(tokens); 658 self.semi_token.to_tokens(tokens); 659 self.len.to_tokens(tokens); 660 }); 661 } 662 } 663 664 impl ToTokens for TypePtr { to_tokens(&self, tokens: &mut Tokens)665 fn to_tokens(&self, tokens: &mut Tokens) { 666 self.star_token.to_tokens(tokens); 667 match self.mutability { 668 Some(ref tok) => tok.to_tokens(tokens), 669 None => { 670 TokensOrDefault(&self.const_token).to_tokens(tokens); 671 } 672 } 673 self.elem.to_tokens(tokens); 674 } 675 } 676 677 impl ToTokens for TypeReference { to_tokens(&self, tokens: &mut Tokens)678 fn to_tokens(&self, tokens: &mut Tokens) { 679 self.and_token.to_tokens(tokens); 680 self.lifetime.to_tokens(tokens); 681 self.mutability.to_tokens(tokens); 682 self.elem.to_tokens(tokens); 683 } 684 } 685 686 impl ToTokens for TypeBareFn { to_tokens(&self, tokens: &mut Tokens)687 fn to_tokens(&self, tokens: &mut Tokens) { 688 self.lifetimes.to_tokens(tokens); 689 self.unsafety.to_tokens(tokens); 690 self.abi.to_tokens(tokens); 691 self.fn_token.to_tokens(tokens); 692 self.paren_token.surround(tokens, |tokens| { 693 self.inputs.to_tokens(tokens); 694 if let Some(ref variadic) = self.variadic { 695 if !self.inputs.empty_or_trailing() { 696 let span = variadic.0[0]; 697 <Token![,]>::new(span).to_tokens(tokens); 698 } 699 variadic.to_tokens(tokens); 700 } 701 }); 702 self.output.to_tokens(tokens); 703 } 704 } 705 706 impl ToTokens for TypeNever { to_tokens(&self, tokens: &mut Tokens)707 fn to_tokens(&self, tokens: &mut Tokens) { 708 self.bang_token.to_tokens(tokens); 709 } 710 } 711 712 impl ToTokens for TypeTuple { to_tokens(&self, tokens: &mut Tokens)713 fn to_tokens(&self, tokens: &mut Tokens) { 714 self.paren_token.surround(tokens, |tokens| { 715 self.elems.to_tokens(tokens); 716 }); 717 } 718 } 719 720 impl ToTokens for TypePath { to_tokens(&self, tokens: &mut Tokens)721 fn to_tokens(&self, tokens: &mut Tokens) { 722 PathTokens(&self.qself, &self.path).to_tokens(tokens); 723 } 724 } 725 726 impl ToTokens for TypeTraitObject { to_tokens(&self, tokens: &mut Tokens)727 fn to_tokens(&self, tokens: &mut Tokens) { 728 self.dyn_token.to_tokens(tokens); 729 self.bounds.to_tokens(tokens); 730 } 731 } 732 733 impl ToTokens for TypeImplTrait { to_tokens(&self, tokens: &mut Tokens)734 fn to_tokens(&self, tokens: &mut Tokens) { 735 self.impl_token.to_tokens(tokens); 736 self.bounds.to_tokens(tokens); 737 } 738 } 739 740 impl ToTokens for TypeGroup { to_tokens(&self, tokens: &mut Tokens)741 fn to_tokens(&self, tokens: &mut Tokens) { 742 self.group_token.surround(tokens, |tokens| { 743 self.elem.to_tokens(tokens); 744 }); 745 } 746 } 747 748 impl ToTokens for TypeParen { to_tokens(&self, tokens: &mut Tokens)749 fn to_tokens(&self, tokens: &mut Tokens) { 750 self.paren_token.surround(tokens, |tokens| { 751 self.elem.to_tokens(tokens); 752 }); 753 } 754 } 755 756 impl ToTokens for TypeInfer { to_tokens(&self, tokens: &mut Tokens)757 fn to_tokens(&self, tokens: &mut Tokens) { 758 self.underscore_token.to_tokens(tokens); 759 } 760 } 761 762 impl ToTokens for TypeMacro { to_tokens(&self, tokens: &mut Tokens)763 fn to_tokens(&self, tokens: &mut Tokens) { 764 self.mac.to_tokens(tokens); 765 } 766 } 767 768 impl ToTokens for TypeVerbatim { to_tokens(&self, tokens: &mut Tokens)769 fn to_tokens(&self, tokens: &mut Tokens) { 770 self.tts.to_tokens(tokens); 771 } 772 } 773 774 impl ToTokens for ReturnType { to_tokens(&self, tokens: &mut Tokens)775 fn to_tokens(&self, tokens: &mut Tokens) { 776 match *self { 777 ReturnType::Default => {} 778 ReturnType::Type(ref arrow, ref ty) => { 779 arrow.to_tokens(tokens); 780 ty.to_tokens(tokens); 781 } 782 } 783 } 784 } 785 786 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut Tokens)787 fn to_tokens(&self, tokens: &mut Tokens) { 788 if let Some((ref name, ref colon)) = self.name { 789 name.to_tokens(tokens); 790 colon.to_tokens(tokens); 791 } 792 self.ty.to_tokens(tokens); 793 } 794 } 795 796 impl ToTokens for BareFnArgName { to_tokens(&self, tokens: &mut Tokens)797 fn to_tokens(&self, tokens: &mut Tokens) { 798 match *self { 799 BareFnArgName::Named(ref t) => t.to_tokens(tokens), 800 BareFnArgName::Wild(ref t) => t.to_tokens(tokens), 801 } 802 } 803 } 804 805 impl ToTokens for Abi { to_tokens(&self, tokens: &mut Tokens)806 fn to_tokens(&self, tokens: &mut Tokens) { 807 self.extern_token.to_tokens(tokens); 808 self.name.to_tokens(tokens); 809 } 810 } 811 } 812