1 use super::*; 2 3 /// The different kinds of types recognized by the compiler 4 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 5 pub enum Ty { 6 /// A variable-length array (`[T]`) 7 Slice(Box<Ty>), 8 /// A fixed length array (`[T; n]`) 9 Array(Box<Ty>, ConstExpr), 10 /// A raw pointer (`*const T` or `*mut T`) 11 Ptr(Box<MutTy>), 12 /// A reference (`&'a T` or `&'a mut T`) 13 Rptr(Option<Lifetime>, Box<MutTy>), 14 /// A bare function (e.g. `fn(usize) -> bool`) 15 BareFn(Box<BareFnTy>), 16 /// The never type (`!`) 17 Never, 18 /// A tuple (`(A, B, C, D, ...)`) 19 Tup(Vec<Ty>), 20 /// A path (`module::module::...::Type`), optionally 21 /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`. 22 /// 23 /// Type parameters are stored in the Path itself 24 Path(Option<QSelf>, Path), 25 /// A trait object type `Bound1 + Bound2 + Bound3` 26 /// where `Bound` is a trait or a lifetime. 27 TraitObject(Vec<TyParamBound>), 28 /// An `impl Bound1 + Bound2 + Bound3` type 29 /// where `Bound` is a trait or a lifetime. 30 ImplTrait(Vec<TyParamBound>), 31 /// No-op; kept solely so that we can pretty-print faithfully 32 Paren(Box<Ty>), 33 /// TyKind::Infer means the type should be inferred instead of it having been 34 /// specified. This can appear anywhere in a type. 35 Infer, 36 /// A macro in the type position. 37 Mac(Mac), 38 } 39 40 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 41 pub struct MutTy { 42 pub ty: Ty, 43 pub mutability: Mutability, 44 } 45 46 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 47 pub enum Mutability { 48 Mutable, 49 Immutable, 50 } 51 52 /// A "Path" is essentially Rust's notion of a name. 53 /// 54 /// It's represented as a sequence of identifiers, 55 /// along with a bunch of supporting information. 56 /// 57 /// E.g. `std::cmp::PartialEq` 58 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 59 pub struct Path { 60 /// A `::foo` path, is relative to the crate root rather than current 61 /// module (like paths in an import). 62 pub global: bool, 63 /// The segments in the path: the things separated by `::`. 64 pub segments: Vec<PathSegment>, 65 } 66 67 impl<T> From<T> for Path 68 where T: Into<PathSegment> 69 { from(segment: T) -> Self70 fn from(segment: T) -> Self { 71 Path { 72 global: false, 73 segments: vec![segment.into()], 74 } 75 } 76 } 77 78 /// A segment of a path: an identifier, an optional lifetime, and a set of types. 79 /// 80 /// E.g. `std`, `String` or `Box<T>` 81 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 82 pub struct PathSegment { 83 /// The identifier portion of this path segment. 84 pub ident: Ident, 85 /// Type/lifetime parameters attached to this path. They come in 86 /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that 87 /// this is more than just simple syntactic sugar; the use of 88 /// parens affects the region binding rules, so we preserve the 89 /// distinction. 90 pub parameters: PathParameters, 91 } 92 93 impl<T> From<T> for PathSegment 94 where T: Into<Ident> 95 { from(ident: T) -> Self96 fn from(ident: T) -> Self { 97 PathSegment { 98 ident: ident.into(), 99 parameters: PathParameters::none(), 100 } 101 } 102 } 103 104 /// Parameters of a path segment. 105 /// 106 /// E.g. `<A, B>` as in `Foo<A, B>` or `(A, B)` as in `Foo(A, B)` 107 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 108 pub enum PathParameters { 109 /// The `<'a, A, B, C>` in `foo::bar::baz::<'a, A, B, C>` 110 AngleBracketed(AngleBracketedParameterData), 111 /// The `(A, B)` and `C` in `Foo(A, B) -> C` 112 Parenthesized(ParenthesizedParameterData), 113 } 114 115 impl PathParameters { none() -> Self116 pub fn none() -> Self { 117 PathParameters::AngleBracketed(AngleBracketedParameterData::default()) 118 } 119 is_empty(&self) -> bool120 pub fn is_empty(&self) -> bool { 121 match *self { 122 PathParameters::AngleBracketed(ref bracketed) => { 123 bracketed.lifetimes.is_empty() && bracketed.types.is_empty() && 124 bracketed.bindings.is_empty() 125 } 126 PathParameters::Parenthesized(_) => false, 127 } 128 } 129 } 130 131 /// A path like `Foo<'a, T>` 132 #[derive(Debug, Clone, Eq, PartialEq, Default, Hash)] 133 pub struct AngleBracketedParameterData { 134 /// The lifetime parameters for this path segment. 135 pub lifetimes: Vec<Lifetime>, 136 /// The type parameters for this path segment, if present. 137 pub types: Vec<Ty>, 138 /// Bindings (equality constraints) on associated types, if present. 139 /// 140 /// E.g., `Foo<A=Bar>`. 141 pub bindings: Vec<TypeBinding>, 142 } 143 144 /// Bind a type to an associated type: `A=Foo`. 145 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 146 pub struct TypeBinding { 147 pub ident: Ident, 148 pub ty: Ty, 149 } 150 151 /// A path like `Foo(A,B) -> C` 152 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 153 pub struct ParenthesizedParameterData { 154 /// `(A, B)` 155 pub inputs: Vec<Ty>, 156 /// `C` 157 pub output: Option<Ty>, 158 } 159 160 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 161 pub struct PolyTraitRef { 162 /// The `'a` in `<'a> Foo<&'a T>` 163 pub bound_lifetimes: Vec<LifetimeDef>, 164 /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` 165 pub trait_ref: Path, 166 } 167 168 /// The explicit Self type in a "qualified path". The actual 169 /// path, including the trait and the associated item, is stored 170 /// separately. `position` represents the index of the associated 171 /// item qualified with this Self type. 172 /// 173 /// ```rust,ignore 174 /// <Vec<T> as a::b::Trait>::AssociatedItem 175 /// ^~~~~ ~~~~~~~~~~~~~~^ 176 /// ty position = 3 177 /// 178 /// <Vec<T>>::AssociatedItem 179 /// ^~~~~ ^ 180 /// ty position = 0 181 /// ``` 182 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 183 pub struct QSelf { 184 pub ty: Box<Ty>, 185 pub position: usize, 186 } 187 188 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 189 pub struct BareFnTy { 190 pub unsafety: Unsafety, 191 pub abi: Option<Abi>, 192 pub lifetimes: Vec<LifetimeDef>, 193 pub inputs: Vec<BareFnArg>, 194 pub output: FunctionRetTy, 195 pub variadic: bool, 196 } 197 198 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 199 pub enum Unsafety { 200 Unsafe, 201 Normal, 202 } 203 204 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 205 pub enum Abi { 206 Named(String), 207 Rust, 208 } 209 210 /// An argument in a function type. 211 /// 212 /// E.g. `bar: usize` as in `fn foo(bar: usize)` 213 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 214 pub struct BareFnArg { 215 pub name: Option<Ident>, 216 pub ty: Ty, 217 } 218 219 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 220 pub enum FunctionRetTy { 221 /// Return type is not specified. 222 /// 223 /// Functions default to `()` and 224 /// closures default to inference. Span points to where return 225 /// type would be inserted. 226 Default, 227 /// Everything else 228 Ty(Ty), 229 } 230 231 #[cfg(feature = "parsing")] 232 pub mod parsing { 233 use super::*; 234 use {TyParamBound, TraitBoundModifier}; 235 #[cfg(feature = "full")] 236 use ConstExpr; 237 #[cfg(feature = "full")] 238 use constant::parsing::const_expr; 239 #[cfg(feature = "full")] 240 use expr::parsing::expr; 241 use generics::parsing::{lifetime, lifetime_def, ty_param_bound, bound_lifetimes}; 242 use ident::parsing::ident; 243 use lit::parsing::quoted_string; 244 use mac::parsing::mac; 245 use std::str; 246 247 named!(pub ty -> Ty, alt!( 248 ty_paren // must be before ty_tup 249 | 250 ty_mac // must be before ty_path 251 | 252 ty_path // must be before ty_poly_trait_ref 253 | 254 ty_vec 255 | 256 ty_array 257 | 258 ty_ptr 259 | 260 ty_rptr 261 | 262 ty_bare_fn 263 | 264 ty_never 265 | 266 ty_tup 267 | 268 ty_poly_trait_ref 269 | 270 ty_impl_trait 271 )); 272 273 named!(ty_mac -> Ty, map!(mac, Ty::Mac)); 274 275 named!(ty_vec -> Ty, do_parse!( 276 punct!("[") >> 277 elem: ty >> 278 punct!("]") >> 279 (Ty::Slice(Box::new(elem))) 280 )); 281 282 named!(ty_array -> Ty, do_parse!( 283 punct!("[") >> 284 elem: ty >> 285 punct!(";") >> 286 len: array_len >> 287 punct!("]") >> 288 (Ty::Array(Box::new(elem), len)) 289 )); 290 291 #[cfg(not(feature = "full"))] 292 use constant::parsing::const_expr as array_len; 293 294 #[cfg(feature = "full")] 295 named!(array_len -> ConstExpr, alt!( 296 terminated!(const_expr, after_array_len) 297 | 298 terminated!(expr, after_array_len) => { ConstExpr::Other } 299 )); 300 301 #[cfg(feature = "full")] 302 named!(after_array_len -> &str, peek!(punct!("]"))); 303 304 named!(ty_ptr -> Ty, do_parse!( 305 punct!("*") >> 306 mutability: alt!( 307 keyword!("const") => { |_| Mutability::Immutable } 308 | 309 keyword!("mut") => { |_| Mutability::Mutable } 310 ) >> 311 target: ty >> 312 (Ty::Ptr(Box::new(MutTy { 313 ty: target, 314 mutability: mutability, 315 }))) 316 )); 317 318 named!(ty_rptr -> Ty, do_parse!( 319 punct!("&") >> 320 life: option!(lifetime) >> 321 mutability: mutability >> 322 target: ty >> 323 (Ty::Rptr(life, Box::new(MutTy { 324 ty: target, 325 mutability: mutability, 326 }))) 327 )); 328 329 named!(ty_bare_fn -> Ty, do_parse!( 330 lifetimes: opt_vec!(do_parse!( 331 keyword!("for") >> 332 punct!("<") >> 333 lifetimes: terminated_list!(punct!(","), lifetime_def) >> 334 punct!(">") >> 335 (lifetimes) 336 )) >> 337 unsafety: unsafety >> 338 abi: option!(abi) >> 339 keyword!("fn") >> 340 punct!("(") >> 341 inputs: separated_list!(punct!(","), fn_arg) >> 342 trailing_comma: option!(punct!(",")) >> 343 variadic: option!(cond_reduce!(trailing_comma.is_some(), punct!("..."))) >> 344 punct!(")") >> 345 output: option!(preceded!( 346 punct!("->"), 347 ty 348 )) >> 349 (Ty::BareFn(Box::new(BareFnTy { 350 unsafety: unsafety, 351 abi: abi, 352 lifetimes: lifetimes, 353 inputs: inputs, 354 output: match output { 355 Some(ty) => FunctionRetTy::Ty(ty), 356 None => FunctionRetTy::Default, 357 }, 358 variadic: variadic.is_some(), 359 }))) 360 )); 361 362 named!(ty_never -> Ty, map!(punct!("!"), |_| Ty::Never)); 363 364 named!(ty_tup -> Ty, do_parse!( 365 punct!("(") >> 366 elems: terminated_list!(punct!(","), ty) >> 367 punct!(")") >> 368 (Ty::Tup(elems)) 369 )); 370 371 named!(ty_path -> Ty, do_parse!( 372 qpath: qpath >> 373 parenthesized: cond!( 374 qpath.1.segments.last().unwrap().parameters == PathParameters::none(), 375 option!(parenthesized_parameter_data) 376 ) >> 377 bounds: many0!(preceded!(punct!("+"), ty_param_bound)) >> 378 ({ 379 let (qself, mut path) = qpath; 380 if let Some(Some(parenthesized)) = parenthesized { 381 path.segments.last_mut().unwrap().parameters = parenthesized; 382 } 383 if bounds.is_empty() { 384 Ty::Path(qself, path) 385 } else { 386 let path = TyParamBound::Trait( 387 PolyTraitRef { 388 bound_lifetimes: Vec::new(), 389 trait_ref: path, 390 }, 391 TraitBoundModifier::None, 392 ); 393 let bounds = Some(path).into_iter().chain(bounds).collect(); 394 Ty::TraitObject(bounds) 395 } 396 }) 397 )); 398 399 named!(parenthesized_parameter_data -> PathParameters, do_parse!( 400 punct!("(") >> 401 inputs: terminated_list!(punct!(","), ty) >> 402 punct!(")") >> 403 output: option!(preceded!( 404 punct!("->"), 405 ty 406 )) >> 407 (PathParameters::Parenthesized( 408 ParenthesizedParameterData { 409 inputs: inputs, 410 output: output, 411 }, 412 )) 413 )); 414 415 named!(pub qpath -> (Option<QSelf>, Path), alt!( 416 map!(path, |p| (None, p)) 417 | 418 do_parse!( 419 punct!("<") >> 420 this: map!(ty, Box::new) >> 421 path: option!(preceded!( 422 keyword!("as"), 423 path 424 )) >> 425 punct!(">") >> 426 punct!("::") >> 427 rest: separated_nonempty_list!(punct!("::"), path_segment) >> 428 ({ 429 match path { 430 Some(mut path) => { 431 let pos = path.segments.len(); 432 path.segments.extend(rest); 433 (Some(QSelf { ty: this, position: pos }), path) 434 } 435 None => { 436 (Some(QSelf { ty: this, position: 0 }), Path { 437 global: false, 438 segments: rest, 439 }) 440 } 441 } 442 }) 443 ) 444 | 445 map!(keyword!("self"), |_| (None, "self".into())) 446 )); 447 448 named!(ty_poly_trait_ref -> Ty, map!( 449 separated_nonempty_list!(punct!("+"), ty_param_bound), 450 Ty::TraitObject 451 )); 452 453 named!(ty_impl_trait -> Ty, do_parse!( 454 keyword!("impl") >> 455 elem: separated_nonempty_list!(punct!("+"), ty_param_bound) >> 456 (Ty::ImplTrait(elem)) 457 )); 458 459 named!(ty_paren -> Ty, do_parse!( 460 punct!("(") >> 461 elem: ty >> 462 punct!(")") >> 463 (Ty::Paren(Box::new(elem))) 464 )); 465 466 named!(pub mutability -> Mutability, alt!( 467 keyword!("mut") => { |_| Mutability::Mutable } 468 | 469 epsilon!() => { |_| Mutability::Immutable } 470 )); 471 472 named!(pub path -> Path, do_parse!( 473 global: option!(punct!("::")) >> 474 segments: separated_nonempty_list!(punct!("::"), path_segment) >> 475 (Path { 476 global: global.is_some(), 477 segments: segments, 478 }) 479 )); 480 481 named!(path_segment -> PathSegment, alt!( 482 do_parse!( 483 id: option!(ident) >> 484 punct!("<") >> 485 lifetimes: separated_list!(punct!(","), lifetime) >> 486 types: opt_vec!(preceded!( 487 cond!(!lifetimes.is_empty(), punct!(",")), 488 separated_nonempty_list!( 489 punct!(","), 490 terminated!(ty, not!(punct!("="))) 491 ) 492 )) >> 493 bindings: opt_vec!(preceded!( 494 cond!(!lifetimes.is_empty() || !types.is_empty(), punct!(",")), 495 separated_nonempty_list!(punct!(","), type_binding) 496 )) >> 497 cond!(!lifetimes.is_empty() || !types.is_empty() || !bindings.is_empty(), option!(punct!(","))) >> 498 punct!(">") >> 499 (PathSegment { 500 ident: id.unwrap_or_else(|| "".into()), 501 parameters: PathParameters::AngleBracketed( 502 AngleBracketedParameterData { 503 lifetimes: lifetimes, 504 types: types, 505 bindings: bindings, 506 } 507 ), 508 }) 509 ) 510 | 511 map!(ident, Into::into) 512 | 513 map!(alt!( 514 keyword!("super") 515 | 516 keyword!("self") 517 | 518 keyword!("Self") 519 ), Into::into) 520 )); 521 522 named!(type_binding -> TypeBinding, do_parse!( 523 id: ident >> 524 punct!("=") >> 525 ty: ty >> 526 (TypeBinding { 527 ident: id, 528 ty: ty, 529 }) 530 )); 531 532 named!(pub poly_trait_ref -> PolyTraitRef, do_parse!( 533 bound_lifetimes: bound_lifetimes >> 534 trait_ref: path >> 535 parenthesized: option!(cond_reduce!( 536 trait_ref.segments.last().unwrap().parameters == PathParameters::none(), 537 parenthesized_parameter_data 538 )) >> 539 ({ 540 let mut trait_ref = trait_ref; 541 if let Some(parenthesized) = parenthesized { 542 trait_ref.segments.last_mut().unwrap().parameters = parenthesized; 543 } 544 PolyTraitRef { 545 bound_lifetimes: bound_lifetimes, 546 trait_ref: trait_ref, 547 } 548 }) 549 )); 550 551 named!(pub fn_arg -> BareFnArg, do_parse!( 552 name: option!(do_parse!( 553 name: ident >> 554 punct!(":") >> 555 not!(tag!(":")) >> // not :: 556 (name) 557 )) >> 558 ty: ty >> 559 (BareFnArg { 560 name: name, 561 ty: ty, 562 }) 563 )); 564 565 named!(pub unsafety -> Unsafety, alt!( 566 keyword!("unsafe") => { |_| Unsafety::Unsafe } 567 | 568 epsilon!() => { |_| Unsafety::Normal } 569 )); 570 571 named!(pub abi -> Abi, do_parse!( 572 keyword!("extern") >> 573 name: option!(quoted_string) >> 574 (match name { 575 Some(name) => Abi::Named(name), 576 None => Abi::Rust, 577 }) 578 )); 579 } 580 581 #[cfg(feature = "printing")] 582 mod printing { 583 use super::*; 584 use quote::{Tokens, ToTokens}; 585 586 impl ToTokens for Ty { to_tokens(&self, tokens: &mut Tokens)587 fn to_tokens(&self, tokens: &mut Tokens) { 588 match *self { 589 Ty::Slice(ref inner) => { 590 tokens.append("["); 591 inner.to_tokens(tokens); 592 tokens.append("]"); 593 } 594 Ty::Array(ref inner, ref len) => { 595 tokens.append("["); 596 inner.to_tokens(tokens); 597 tokens.append(";"); 598 len.to_tokens(tokens); 599 tokens.append("]"); 600 } 601 Ty::Ptr(ref target) => { 602 tokens.append("*"); 603 match target.mutability { 604 Mutability::Mutable => tokens.append("mut"), 605 Mutability::Immutable => tokens.append("const"), 606 } 607 target.ty.to_tokens(tokens); 608 } 609 Ty::Rptr(ref lifetime, ref target) => { 610 tokens.append("&"); 611 lifetime.to_tokens(tokens); 612 target.mutability.to_tokens(tokens); 613 target.ty.to_tokens(tokens); 614 } 615 Ty::BareFn(ref func) => { 616 func.to_tokens(tokens); 617 } 618 Ty::Never => { 619 tokens.append("!"); 620 } 621 Ty::Tup(ref elems) => { 622 tokens.append("("); 623 tokens.append_separated(elems, ","); 624 if elems.len() == 1 { 625 tokens.append(","); 626 } 627 tokens.append(")"); 628 } 629 Ty::Path(None, ref path) => { 630 path.to_tokens(tokens); 631 } 632 Ty::Path(Some(ref qself), ref path) => { 633 tokens.append("<"); 634 qself.ty.to_tokens(tokens); 635 if qself.position > 0 { 636 tokens.append("as"); 637 for (i, segment) in path.segments 638 .iter() 639 .take(qself.position) 640 .enumerate() { 641 if i > 0 || path.global { 642 tokens.append("::"); 643 } 644 segment.to_tokens(tokens); 645 } 646 } 647 tokens.append(">"); 648 for segment in path.segments.iter().skip(qself.position) { 649 tokens.append("::"); 650 segment.to_tokens(tokens); 651 } 652 } 653 Ty::TraitObject(ref bounds) => { 654 tokens.append_separated(bounds, "+"); 655 } 656 Ty::ImplTrait(ref bounds) => { 657 tokens.append("impl"); 658 tokens.append_separated(bounds, "+"); 659 } 660 Ty::Paren(ref inner) => { 661 tokens.append("("); 662 inner.to_tokens(tokens); 663 tokens.append(")"); 664 } 665 Ty::Infer => { 666 tokens.append("_"); 667 } 668 Ty::Mac(ref mac) => mac.to_tokens(tokens), 669 } 670 } 671 } 672 673 impl ToTokens for Mutability { to_tokens(&self, tokens: &mut Tokens)674 fn to_tokens(&self, tokens: &mut Tokens) { 675 if let Mutability::Mutable = *self { 676 tokens.append("mut"); 677 } 678 } 679 } 680 681 impl ToTokens for Path { to_tokens(&self, tokens: &mut Tokens)682 fn to_tokens(&self, tokens: &mut Tokens) { 683 for (i, segment) in self.segments.iter().enumerate() { 684 if i > 0 || self.global { 685 tokens.append("::"); 686 } 687 segment.to_tokens(tokens); 688 } 689 } 690 } 691 692 impl ToTokens for PathSegment { to_tokens(&self, tokens: &mut Tokens)693 fn to_tokens(&self, tokens: &mut Tokens) { 694 self.ident.to_tokens(tokens); 695 if self.ident.as_ref().is_empty() && self.parameters.is_empty() { 696 tokens.append("<"); 697 tokens.append(">"); 698 } else { 699 self.parameters.to_tokens(tokens); 700 } 701 } 702 } 703 704 impl ToTokens for PathParameters { to_tokens(&self, tokens: &mut Tokens)705 fn to_tokens(&self, tokens: &mut Tokens) { 706 match *self { 707 PathParameters::AngleBracketed(ref parameters) => { 708 parameters.to_tokens(tokens); 709 } 710 PathParameters::Parenthesized(ref parameters) => { 711 parameters.to_tokens(tokens); 712 } 713 } 714 } 715 } 716 717 impl ToTokens for AngleBracketedParameterData { to_tokens(&self, tokens: &mut Tokens)718 fn to_tokens(&self, tokens: &mut Tokens) { 719 let has_lifetimes = !self.lifetimes.is_empty(); 720 let has_types = !self.types.is_empty(); 721 let has_bindings = !self.bindings.is_empty(); 722 if !has_lifetimes && !has_types && !has_bindings { 723 return; 724 } 725 726 tokens.append("<"); 727 728 let mut first = true; 729 for lifetime in &self.lifetimes { 730 if !first { 731 tokens.append(","); 732 } 733 lifetime.to_tokens(tokens); 734 first = false; 735 } 736 for ty in &self.types { 737 if !first { 738 tokens.append(","); 739 } 740 ty.to_tokens(tokens); 741 first = false; 742 } 743 for binding in &self.bindings { 744 if !first { 745 tokens.append(","); 746 } 747 binding.to_tokens(tokens); 748 first = false; 749 } 750 751 tokens.append(">"); 752 } 753 } 754 755 impl ToTokens for TypeBinding { to_tokens(&self, tokens: &mut Tokens)756 fn to_tokens(&self, tokens: &mut Tokens) { 757 self.ident.to_tokens(tokens); 758 tokens.append("="); 759 self.ty.to_tokens(tokens); 760 } 761 } 762 763 impl ToTokens for ParenthesizedParameterData { to_tokens(&self, tokens: &mut Tokens)764 fn to_tokens(&self, tokens: &mut Tokens) { 765 tokens.append("("); 766 tokens.append_separated(&self.inputs, ","); 767 tokens.append(")"); 768 if let Some(ref output) = self.output { 769 tokens.append("->"); 770 output.to_tokens(tokens); 771 } 772 } 773 } 774 775 impl ToTokens for PolyTraitRef { to_tokens(&self, tokens: &mut Tokens)776 fn to_tokens(&self, tokens: &mut Tokens) { 777 if !self.bound_lifetimes.is_empty() { 778 tokens.append("for"); 779 tokens.append("<"); 780 tokens.append_separated(&self.bound_lifetimes, ","); 781 tokens.append(">"); 782 } 783 self.trait_ref.to_tokens(tokens); 784 } 785 } 786 787 impl ToTokens for BareFnTy { to_tokens(&self, tokens: &mut Tokens)788 fn to_tokens(&self, tokens: &mut Tokens) { 789 if !self.lifetimes.is_empty() { 790 tokens.append("for"); 791 tokens.append("<"); 792 tokens.append_separated(&self.lifetimes, ","); 793 tokens.append(">"); 794 } 795 self.unsafety.to_tokens(tokens); 796 self.abi.to_tokens(tokens); 797 tokens.append("fn"); 798 tokens.append("("); 799 tokens.append_separated(&self.inputs, ","); 800 if self.variadic { 801 if !self.inputs.is_empty() { 802 tokens.append(","); 803 } 804 tokens.append("..."); 805 } 806 tokens.append(")"); 807 if let FunctionRetTy::Ty(ref ty) = self.output { 808 tokens.append("->"); 809 ty.to_tokens(tokens); 810 } 811 } 812 } 813 814 impl ToTokens for BareFnArg { to_tokens(&self, tokens: &mut Tokens)815 fn to_tokens(&self, tokens: &mut Tokens) { 816 if let Some(ref name) = self.name { 817 name.to_tokens(tokens); 818 tokens.append(":"); 819 } 820 self.ty.to_tokens(tokens); 821 } 822 } 823 824 impl ToTokens for Unsafety { to_tokens(&self, tokens: &mut Tokens)825 fn to_tokens(&self, tokens: &mut Tokens) { 826 match *self { 827 Unsafety::Unsafe => tokens.append("unsafe"), 828 Unsafety::Normal => { 829 // nothing 830 } 831 } 832 } 833 } 834 835 impl ToTokens for Abi { to_tokens(&self, tokens: &mut Tokens)836 fn to_tokens(&self, tokens: &mut Tokens) { 837 tokens.append("extern"); 838 match *self { 839 Abi::Named(ref named) => named.to_tokens(tokens), 840 Abi::Rust => {} 841 } 842 } 843 } 844 } 845