1 use super::*; 2 3 /// An expression. 4 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 5 pub struct Expr { 6 /// Type of the expression. 7 pub node: ExprKind, 8 9 /// Attributes tagged on the expression. 10 pub attrs: Vec<Attribute>, 11 } 12 13 impl From<ExprKind> for Expr { from(node: ExprKind) -> Expr14 fn from(node: ExprKind) -> Expr { 15 Expr { 16 node: node, 17 attrs: Vec::new(), 18 } 19 } 20 } 21 22 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 23 pub enum ExprKind { 24 /// A `box x` expression. 25 Box(Box<Expr>), 26 27 /// First expr is the place; second expr is the value. 28 /// 29 /// E.g. 'plae <- val'. 30 InPlace(Box<Expr>, Box<Expr>), 31 32 /// An array, e.g. `[a, b, c, d]`. 33 Array(Vec<Expr>), 34 35 /// A function call. 36 /// 37 /// The first field resolves to the function itself, 38 /// and the second field is the list of arguments 39 Call(Box<Expr>, Vec<Expr>), 40 41 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`) 42 /// 43 /// The `Ident` is the identifier for the method name. 44 /// The vector of `Ty`s are the ascripted type parameters for the method 45 /// (within the angle brackets). 46 /// 47 /// The first element of the vector of `Expr`s is the expression that evaluates 48 /// to the object on which the method is being called on (the receiver), 49 /// and the remaining elements are the rest of the arguments. 50 /// 51 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as 52 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. 53 MethodCall(Ident, Vec<Ty>, Vec<Expr>), 54 55 /// A tuple, e.g. `(a, b, c, d)`. 56 Tup(Vec<Expr>), 57 58 /// A binary operation, e.g. `a + b`, `a * b`. 59 Binary(BinOp, Box<Expr>, Box<Expr>), 60 61 /// A unary operation, e.g. `!x`, `*x`. 62 Unary(UnOp, Box<Expr>), 63 64 /// A literal, e.g. `1`, `"foo"`. 65 Lit(Lit), 66 67 /// A cast, e.g. `foo as f64`. 68 Cast(Box<Expr>, Box<Ty>), 69 70 /// A type ascription, e.g. `foo: f64`. 71 Type(Box<Expr>, Box<Ty>), 72 73 /// An `if` block, with an optional else block 74 /// 75 /// E.g., `if expr { block } else { expr }` 76 If(Box<Expr>, Block, Option<Box<Expr>>), 77 78 /// An `if let` expression with an optional else block 79 /// 80 /// E.g., `if let pat = expr { block } else { expr }` 81 /// 82 /// This is desugared to a `match` expression. 83 IfLet(Box<Pat>, Box<Expr>, Block, Option<Box<Expr>>), 84 85 /// A while loop, with an optional label 86 /// 87 /// E.g., `'label: while expr { block }` 88 While(Box<Expr>, Block, Option<Ident>), 89 90 /// A while-let loop, with an optional label. 91 /// 92 /// E.g., `'label: while let pat = expr { block }` 93 /// 94 /// This is desugared to a combination of `loop` and `match` expressions. 95 WhileLet(Box<Pat>, Box<Expr>, Block, Option<Ident>), 96 97 /// A for loop, with an optional label. 98 /// 99 /// E.g., `'label: for pat in expr { block }` 100 /// 101 /// This is desugared to a combination of `loop` and `match` expressions. 102 ForLoop(Box<Pat>, Box<Expr>, Block, Option<Ident>), 103 104 /// Conditionless loop with an optional label. 105 /// 106 /// E.g. `'label: loop { block }` 107 Loop(Block, Option<Ident>), 108 109 /// A `match` block. 110 Match(Box<Expr>, Vec<Arm>), 111 112 /// A closure (for example, `move |a, b, c| a + b + c`) 113 Closure(CaptureBy, Box<FnDecl>, Box<Expr>), 114 115 /// A block (`{ ... }` or `unsafe { ... }`) 116 Block(Unsafety, Block), 117 118 /// An assignment (`a = foo()`) 119 Assign(Box<Expr>, Box<Expr>), 120 121 /// An assignment with an operator 122 /// 123 /// For example, `a += 1`. 124 AssignOp(BinOp, Box<Expr>, Box<Expr>), 125 126 /// Access of a named struct field (`obj.foo`) 127 Field(Box<Expr>, Ident), 128 129 /// Access of an unnamed field of a struct or tuple-struct 130 /// 131 /// For example, `foo.0`. 132 TupField(Box<Expr>, usize), 133 134 /// An indexing operation (`foo[2]`) 135 Index(Box<Expr>, Box<Expr>), 136 137 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`) 138 Range(Option<Box<Expr>>, Option<Box<Expr>>, RangeLimits), 139 140 /// Variable reference, possibly containing `::` and/or type 141 /// parameters, e.g. foo::bar::<baz>. 142 /// 143 /// Optionally "qualified", 144 /// E.g. `<Vec<T> as SomeTrait>::SomeType`. 145 Path(Option<QSelf>, Path), 146 147 /// A referencing operation (`&a` or `&mut a`) 148 AddrOf(Mutability, Box<Expr>), 149 150 /// A `break`, with an optional label to break, and an optional expression 151 Break(Option<Ident>, Option<Box<Expr>>), 152 153 /// A `continue`, with an optional label 154 Continue(Option<Ident>), 155 156 /// A `return`, with an optional value to be returned 157 Ret(Option<Box<Expr>>), 158 159 /// A macro invocation; pre-expansion 160 Mac(Mac), 161 162 /// A struct literal expression. 163 /// 164 /// For example, `Foo {x: 1, y: 2}`, or 165 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`. 166 Struct(Path, Vec<FieldValue>, Option<Box<Expr>>), 167 168 /// An array literal constructed from one repeated element. 169 /// 170 /// For example, `[1; 5]`. The first expression is the element 171 /// to be repeated; the second is the number of times to repeat it. 172 Repeat(Box<Expr>, Box<Expr>), 173 174 /// No-op: used solely so we can pretty-print faithfully 175 Paren(Box<Expr>), 176 177 /// `expr?` 178 Try(Box<Expr>), 179 } 180 181 /// A field-value pair in a struct literal. 182 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 183 pub struct FieldValue { 184 /// Name of the field. 185 pub ident: Ident, 186 187 /// Value of the field. 188 pub expr: Expr, 189 190 /// Whether this is a shorthand field, e.g. `Struct { x }` 191 /// instead of `Struct { x: x }`. 192 pub is_shorthand: bool, 193 194 /// Attributes tagged on the field. 195 pub attrs: Vec<Attribute>, 196 } 197 198 /// A Block (`{ .. }`). 199 /// 200 /// E.g. `{ .. }` as in `fn foo() { .. }` 201 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 202 pub struct Block { 203 /// Statements in a block 204 pub stmts: Vec<Stmt>, 205 } 206 207 /// A statement, usually ending in a semicolon. 208 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 209 pub enum Stmt { 210 /// A local (let) binding. 211 Local(Box<Local>), 212 213 /// An item definition. 214 Item(Box<Item>), 215 216 /// Expr without trailing semicolon. 217 Expr(Box<Expr>), 218 219 /// Expression with trailing semicolon; 220 Semi(Box<Expr>), 221 222 /// Macro invocation. 223 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>), 224 } 225 226 /// How a macro was invoked. 227 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 228 pub enum MacStmtStyle { 229 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };` 230 /// `foo!(...);`, `foo![...];` 231 Semicolon, 232 233 /// The macro statement had braces; e.g. foo! { ... } 234 Braces, 235 236 /// The macro statement had parentheses or brackets and no semicolon; e.g. 237 /// `foo!(...)`. All of these will end up being converted into macro 238 /// expressions. 239 NoBraces, 240 } 241 242 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;` 243 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 244 pub struct Local { 245 pub pat: Box<Pat>, 246 pub ty: Option<Box<Ty>>, 247 248 /// Initializer expression to set the value, if any 249 pub init: Option<Box<Expr>>, 250 pub attrs: Vec<Attribute>, 251 } 252 253 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 254 // Clippy false positive 255 // https://github.com/Manishearth/rust-clippy/issues/1241 256 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))] 257 pub enum Pat { 258 /// Represents a wildcard pattern (`_`) 259 Wild, 260 261 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`), 262 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third 263 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens 264 /// during name resolution. 265 Ident(BindingMode, Ident, Option<Box<Pat>>), 266 267 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. 268 /// The `bool` is `true` in the presence of a `..`. 269 Struct(Path, Vec<FieldPat>, bool), 270 271 /// A tuple struct/variant pattern `Variant(x, y, .., z)`. 272 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. 273 /// 0 <= position <= subpats.len() 274 TupleStruct(Path, Vec<Pat>, Option<usize>), 275 276 /// A possibly qualified path pattern. 277 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants 278 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can 279 /// only legally refer to associated constants. 280 Path(Option<QSelf>, Path), 281 282 /// A tuple pattern `(a, b)`. 283 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position. 284 /// 0 <= position <= subpats.len() 285 Tuple(Vec<Pat>, Option<usize>), 286 /// A `box` pattern 287 Box(Box<Pat>), 288 /// A reference pattern, e.g. `&mut (a, b)` 289 Ref(Box<Pat>, Mutability), 290 /// A literal 291 Lit(Box<Expr>), 292 /// A range pattern, e.g. `1...2` 293 Range(Box<Expr>, Box<Expr>), 294 /// `[a, b, ..i, y, z]` is represented as: 295 /// `Pat::Slice(box [a, b], Some(i), box [y, z])` 296 Slice(Vec<Pat>, Option<Box<Pat>>, Vec<Pat>), 297 /// A macro pattern; pre-expansion 298 Mac(Mac), 299 } 300 301 /// An arm of a 'match'. 302 /// 303 /// E.g. `0...10 => { println!("match!") }` as in 304 /// 305 /// ```rust,ignore 306 /// match n { 307 /// 0...10 => { println!("match!") }, 308 /// // .. 309 /// } 310 /// ``` 311 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 312 pub struct Arm { 313 pub attrs: Vec<Attribute>, 314 pub pats: Vec<Pat>, 315 pub guard: Option<Box<Expr>>, 316 pub body: Box<Expr>, 317 } 318 319 /// A capture clause 320 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 321 pub enum CaptureBy { 322 Value, 323 Ref, 324 } 325 326 /// Limit types of a range (inclusive or exclusive) 327 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 328 pub enum RangeLimits { 329 /// Inclusive at the beginning, exclusive at the end 330 HalfOpen, 331 /// Inclusive at the beginning and end 332 Closed, 333 } 334 335 /// A single field in a struct pattern 336 /// 337 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` 338 /// are treated the same as `x: x, y: ref y, z: ref mut z`, 339 /// except `is_shorthand` is true 340 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 341 pub struct FieldPat { 342 /// The identifier for the field 343 pub ident: Ident, 344 /// The pattern the field is destructured to 345 pub pat: Box<Pat>, 346 pub is_shorthand: bool, 347 pub attrs: Vec<Attribute>, 348 } 349 350 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 351 pub enum BindingMode { 352 ByRef(Mutability), 353 ByValue(Mutability), 354 } 355 356 #[cfg(feature = "parsing")] 357 pub mod parsing { 358 use super::*; 359 use {BinOp, Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, Mac, 360 TokenTree, Ty, UnOp, Unsafety}; 361 use attr::parsing::outer_attr; 362 use generics::parsing::lifetime; 363 use ident::parsing::{ident, wordlike}; 364 use item::parsing::item; 365 use lit::parsing::{digits, lit}; 366 use mac::parsing::{mac, token_trees}; 367 use synom::IResult::{self, Error}; 368 use op::parsing::{assign_op, binop, unop}; 369 use ty::parsing::{mutability, path, qpath, ty, unsafety}; 370 371 // Struct literals are ambiguous in certain positions 372 // https://github.com/rust-lang/rfcs/pull/92 373 macro_rules! named_ambiguous_expr { 374 ($name:ident -> $o:ty, $allow_struct:ident, $submac:ident!( $($args:tt)* )) => { 375 fn $name(i: &str, $allow_struct: bool) -> $crate::synom::IResult<&str, $o> { 376 $submac!(i, $($args)*) 377 } 378 }; 379 } 380 381 macro_rules! ambiguous_expr { 382 ($i:expr, $allow_struct:ident) => { 383 ambiguous_expr($i, $allow_struct, true) 384 }; 385 } 386 387 named!(pub expr -> Expr, ambiguous_expr!(true)); 388 389 named!(expr_no_struct -> Expr, ambiguous_expr!(false)); 390 391 #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))] ambiguous_expr(i: &str, allow_struct: bool, allow_block: bool) -> IResult<&str, Expr>392 fn ambiguous_expr(i: &str, allow_struct: bool, allow_block: bool) -> IResult<&str, Expr> { 393 do_parse!( 394 i, 395 mut e: alt!( 396 expr_lit // must be before expr_struct 397 | 398 cond_reduce!(allow_struct, expr_struct) // must be before expr_path 399 | 400 expr_paren // must be before expr_tup 401 | 402 expr_mac // must be before expr_path 403 | 404 call!(expr_break, allow_struct) // must be before expr_path 405 | 406 expr_continue // must be before expr_path 407 | 408 call!(expr_ret, allow_struct) // must be before expr_path 409 | 410 call!(expr_box, allow_struct) 411 | 412 expr_in_place 413 | 414 expr_array 415 | 416 expr_tup 417 | 418 call!(expr_unary, allow_struct) 419 | 420 expr_if 421 | 422 expr_while 423 | 424 expr_for_loop 425 | 426 expr_loop 427 | 428 expr_match 429 | 430 call!(expr_closure, allow_struct) 431 | 432 cond_reduce!(allow_block, expr_block) 433 | 434 call!(expr_range, allow_struct) 435 | 436 expr_path 437 | 438 call!(expr_addr_of, allow_struct) 439 | 440 expr_repeat 441 ) >> 442 many0!(alt!( 443 tap!(args: and_call => { 444 e = ExprKind::Call(Box::new(e.into()), args); 445 }) 446 | 447 tap!(more: and_method_call => { 448 let (method, ascript, mut args) = more; 449 args.insert(0, e.into()); 450 e = ExprKind::MethodCall(method, ascript, args); 451 }) 452 | 453 tap!(more: call!(and_binary, allow_struct) => { 454 let (op, other) = more; 455 e = ExprKind::Binary(op, Box::new(e.into()), Box::new(other)); 456 }) 457 | 458 tap!(ty: and_cast => { 459 e = ExprKind::Cast(Box::new(e.into()), Box::new(ty)); 460 }) 461 | 462 tap!(ty: and_ascription => { 463 e = ExprKind::Type(Box::new(e.into()), Box::new(ty)); 464 }) 465 | 466 tap!(v: call!(and_assign, allow_struct) => { 467 e = ExprKind::Assign(Box::new(e.into()), Box::new(v)); 468 }) 469 | 470 tap!(more: call!(and_assign_op, allow_struct) => { 471 let (op, v) = more; 472 e = ExprKind::AssignOp(op, Box::new(e.into()), Box::new(v)); 473 }) 474 | 475 tap!(field: and_field => { 476 e = ExprKind::Field(Box::new(e.into()), field); 477 }) 478 | 479 tap!(field: and_tup_field => { 480 e = ExprKind::TupField(Box::new(e.into()), field as usize); 481 }) 482 | 483 tap!(i: and_index => { 484 e = ExprKind::Index(Box::new(e.into()), Box::new(i)); 485 }) 486 | 487 tap!(more: call!(and_range, allow_struct) => { 488 let (limits, hi) = more; 489 e = ExprKind::Range(Some(Box::new(e.into())), hi.map(Box::new), limits); 490 }) 491 | 492 tap!(_try: punct!("?") => { 493 e = ExprKind::Try(Box::new(e.into())); 494 }) 495 )) >> 496 (e.into()) 497 ) 498 } 499 500 named!(expr_mac -> ExprKind, map!(mac, ExprKind::Mac)); 501 502 named!(expr_paren -> ExprKind, do_parse!( 503 punct!("(") >> 504 e: expr >> 505 punct!(")") >> 506 (ExprKind::Paren(Box::new(e))) 507 )); 508 509 named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!( 510 keyword!("box") >> 511 inner: ambiguous_expr!(allow_struct) >> 512 (ExprKind::Box(Box::new(inner))) 513 )); 514 515 named!(expr_in_place -> ExprKind, do_parse!( 516 keyword!("in") >> 517 place: expr_no_struct >> 518 punct!("{") >> 519 value: within_block >> 520 punct!("}") >> 521 (ExprKind::InPlace( 522 Box::new(place), 523 Box::new(ExprKind::Block(Unsafety::Normal, Block { 524 stmts: value, 525 }).into()), 526 )) 527 )); 528 529 named!(expr_array -> ExprKind, do_parse!( 530 punct!("[") >> 531 elems: terminated_list!(punct!(","), expr) >> 532 punct!("]") >> 533 (ExprKind::Array(elems)) 534 )); 535 536 named!(and_call -> Vec<Expr>, do_parse!( 537 punct!("(") >> 538 args: terminated_list!(punct!(","), expr) >> 539 punct!(")") >> 540 (args) 541 )); 542 543 named!(and_method_call -> (Ident, Vec<Ty>, Vec<Expr>), do_parse!( 544 punct!(".") >> 545 method: ident >> 546 ascript: opt_vec!(preceded!( 547 punct!("::"), 548 delimited!( 549 punct!("<"), 550 terminated_list!(punct!(","), ty), 551 punct!(">") 552 ) 553 )) >> 554 punct!("(") >> 555 args: terminated_list!(punct!(","), expr) >> 556 punct!(")") >> 557 (method, ascript, args) 558 )); 559 560 named!(expr_tup -> ExprKind, do_parse!( 561 punct!("(") >> 562 elems: terminated_list!(punct!(","), expr) >> 563 punct!(")") >> 564 (ExprKind::Tup(elems)) 565 )); 566 567 named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!( 568 binop, 569 ambiguous_expr!(allow_struct) 570 )); 571 572 named_ambiguous_expr!(expr_unary -> ExprKind, allow_struct, do_parse!( 573 operator: unop >> 574 operand: ambiguous_expr!(allow_struct) >> 575 (ExprKind::Unary(operator, Box::new(operand))) 576 )); 577 578 named!(expr_lit -> ExprKind, map!(lit, ExprKind::Lit)); 579 580 named!(and_cast -> Ty, do_parse!( 581 keyword!("as") >> 582 ty: ty >> 583 (ty) 584 )); 585 586 named!(and_ascription -> Ty, preceded!(punct!(":"), ty)); 587 588 enum Cond { 589 Let(Pat, Expr), 590 Expr(Expr), 591 } 592 593 named!(cond -> Cond, alt!( 594 do_parse!( 595 keyword!("let") >> 596 pat: pat >> 597 punct!("=") >> 598 value: expr_no_struct >> 599 (Cond::Let(pat, value)) 600 ) 601 | 602 map!(expr_no_struct, Cond::Expr) 603 )); 604 605 named!(expr_if -> ExprKind, do_parse!( 606 keyword!("if") >> 607 cond: cond >> 608 punct!("{") >> 609 then_block: within_block >> 610 punct!("}") >> 611 else_block: option!(preceded!( 612 keyword!("else"), 613 alt!( 614 expr_if 615 | 616 do_parse!( 617 punct!("{") >> 618 else_block: within_block >> 619 punct!("}") >> 620 (ExprKind::Block(Unsafety::Normal, Block { 621 stmts: else_block, 622 }).into()) 623 ) 624 ) 625 )) >> 626 (match cond { 627 Cond::Let(pat, expr) => ExprKind::IfLet( 628 Box::new(pat), 629 Box::new(expr), 630 Block { 631 stmts: then_block, 632 }, 633 else_block.map(|els| Box::new(els.into())), 634 ), 635 Cond::Expr(cond) => ExprKind::If( 636 Box::new(cond), 637 Block { 638 stmts: then_block, 639 }, 640 else_block.map(|els| Box::new(els.into())), 641 ), 642 }) 643 )); 644 645 named!(expr_for_loop -> ExprKind, do_parse!( 646 lbl: option!(terminated!(label, punct!(":"))) >> 647 keyword!("for") >> 648 pat: pat >> 649 keyword!("in") >> 650 expr: expr_no_struct >> 651 loop_block: block >> 652 (ExprKind::ForLoop(Box::new(pat), Box::new(expr), loop_block, lbl)) 653 )); 654 655 named!(expr_loop -> ExprKind, do_parse!( 656 lbl: option!(terminated!(label, punct!(":"))) >> 657 keyword!("loop") >> 658 loop_block: block >> 659 (ExprKind::Loop(loop_block, lbl)) 660 )); 661 662 named!(expr_match -> ExprKind, do_parse!( 663 keyword!("match") >> 664 obj: expr_no_struct >> 665 punct!("{") >> 666 mut arms: many0!(do_parse!( 667 arm: match_arm >> 668 cond!(arm_requires_comma(&arm), punct!(",")) >> 669 cond!(!arm_requires_comma(&arm), option!(punct!(","))) >> 670 (arm) 671 )) >> 672 last_arm: option!(match_arm) >> 673 punct!("}") >> 674 (ExprKind::Match(Box::new(obj), { 675 arms.extend(last_arm); 676 arms 677 })) 678 )); 679 arm_requires_comma(arm: &Arm) -> bool680 fn arm_requires_comma(arm: &Arm) -> bool { 681 if let ExprKind::Block(Unsafety::Normal, _) = arm.body.node { 682 false 683 } else { 684 true 685 } 686 } 687 688 named!(match_arm -> Arm, do_parse!( 689 attrs: many0!(outer_attr) >> 690 pats: separated_nonempty_list!(punct!("|"), pat) >> 691 guard: option!(preceded!(keyword!("if"), expr)) >> 692 punct!("=>") >> 693 body: alt!( 694 map!(block, |blk| ExprKind::Block(Unsafety::Normal, blk).into()) 695 | 696 expr 697 ) >> 698 (Arm { 699 attrs: attrs, 700 pats: pats, 701 guard: guard.map(Box::new), 702 body: Box::new(body), 703 }) 704 )); 705 706 named_ambiguous_expr!(expr_closure -> ExprKind, allow_struct, do_parse!( 707 capture: capture_by >> 708 punct!("|") >> 709 inputs: terminated_list!(punct!(","), closure_arg) >> 710 punct!("|") >> 711 ret_and_body: alt!( 712 do_parse!( 713 punct!("->") >> 714 ty: ty >> 715 body: block >> 716 (FunctionRetTy::Ty(ty), ExprKind::Block(Unsafety::Normal, body).into()) 717 ) 718 | 719 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e)) 720 ) >> 721 (ExprKind::Closure( 722 capture, 723 Box::new(FnDecl { 724 inputs: inputs, 725 output: ret_and_body.0, 726 variadic: false, 727 }), 728 Box::new(ret_and_body.1), 729 )) 730 )); 731 732 named!(closure_arg -> FnArg, do_parse!( 733 pat: pat >> 734 ty: option!(preceded!(punct!(":"), ty)) >> 735 (FnArg::Captured(pat, ty.unwrap_or(Ty::Infer))) 736 )); 737 738 named!(expr_while -> ExprKind, do_parse!( 739 lbl: option!(terminated!(label, punct!(":"))) >> 740 keyword!("while") >> 741 cond: cond >> 742 while_block: block >> 743 (match cond { 744 Cond::Let(pat, expr) => ExprKind::WhileLet( 745 Box::new(pat), 746 Box::new(expr), 747 while_block, 748 lbl, 749 ), 750 Cond::Expr(cond) => ExprKind::While( 751 Box::new(cond), 752 while_block, 753 lbl, 754 ), 755 }) 756 )); 757 758 named!(expr_continue -> ExprKind, do_parse!( 759 keyword!("continue") >> 760 lbl: option!(label) >> 761 (ExprKind::Continue(lbl)) 762 )); 763 764 named_ambiguous_expr!(expr_break -> ExprKind, allow_struct, do_parse!( 765 keyword!("break") >> 766 lbl: option!(label) >> 767 val: option!(call!(ambiguous_expr, allow_struct, false)) >> 768 (ExprKind::Break(lbl, val.map(Box::new))) 769 )); 770 771 named_ambiguous_expr!(expr_ret -> ExprKind, allow_struct, do_parse!( 772 keyword!("return") >> 773 ret_value: option!(ambiguous_expr!(allow_struct)) >> 774 (ExprKind::Ret(ret_value.map(Box::new))) 775 )); 776 777 named!(expr_struct -> ExprKind, do_parse!( 778 path: path >> 779 punct!("{") >> 780 fields: separated_list!(punct!(","), field_value) >> 781 base: option!(do_parse!( 782 cond!(!fields.is_empty(), punct!(",")) >> 783 punct!("..") >> 784 base: expr >> 785 (base) 786 )) >> 787 cond!(!fields.is_empty() && base.is_none(), option!(punct!(","))) >> 788 punct!("}") >> 789 (ExprKind::Struct(path, fields, base.map(Box::new))) 790 )); 791 792 named!(field_value -> FieldValue, alt!( 793 do_parse!( 794 name: wordlike >> 795 punct!(":") >> 796 value: expr >> 797 (FieldValue { 798 ident: name, 799 expr: value, 800 is_shorthand: false, 801 attrs: Vec::new(), 802 }) 803 ) 804 | 805 map!(ident, |name: Ident| FieldValue { 806 ident: name.clone(), 807 expr: ExprKind::Path(None, name.into()).into(), 808 is_shorthand: true, 809 attrs: Vec::new(), 810 }) 811 )); 812 813 named!(expr_repeat -> ExprKind, do_parse!( 814 punct!("[") >> 815 value: expr >> 816 punct!(";") >> 817 times: expr >> 818 punct!("]") >> 819 (ExprKind::Repeat(Box::new(value), Box::new(times))) 820 )); 821 822 named!(expr_block -> ExprKind, do_parse!( 823 rules: unsafety >> 824 b: block >> 825 (ExprKind::Block(rules, Block { 826 stmts: b.stmts, 827 })) 828 )); 829 830 named_ambiguous_expr!(expr_range -> ExprKind, allow_struct, do_parse!( 831 limits: range_limits >> 832 hi: option!(ambiguous_expr!(allow_struct)) >> 833 (ExprKind::Range(None, hi.map(Box::new), limits)) 834 )); 835 836 named!(range_limits -> RangeLimits, alt!( 837 punct!("...") => { |_| RangeLimits::Closed } 838 | 839 punct!("..") => { |_| RangeLimits::HalfOpen } 840 )); 841 842 named!(expr_path -> ExprKind, map!(qpath, |(qself, path)| ExprKind::Path(qself, path))); 843 844 named_ambiguous_expr!(expr_addr_of -> ExprKind, allow_struct, do_parse!( 845 punct!("&") >> 846 mutability: mutability >> 847 expr: ambiguous_expr!(allow_struct) >> 848 (ExprKind::AddrOf(mutability, Box::new(expr))) 849 )); 850 851 named_ambiguous_expr!(and_assign -> Expr, allow_struct, preceded!( 852 punct!("="), 853 ambiguous_expr!(allow_struct) 854 )); 855 856 named_ambiguous_expr!(and_assign_op -> (BinOp, Expr), allow_struct, tuple!( 857 assign_op, 858 ambiguous_expr!(allow_struct) 859 )); 860 861 named!(and_field -> Ident, preceded!(punct!("."), ident)); 862 863 named!(and_tup_field -> u64, preceded!(punct!("."), digits)); 864 865 named!(and_index -> Expr, delimited!(punct!("["), expr, punct!("]"))); 866 867 named_ambiguous_expr!(and_range -> (RangeLimits, Option<Expr>), allow_struct, tuple!( 868 range_limits, 869 option!(call!(ambiguous_expr, allow_struct, false)) 870 )); 871 872 named!(pub block -> Block, do_parse!( 873 punct!("{") >> 874 stmts: within_block >> 875 punct!("}") >> 876 (Block { 877 stmts: stmts, 878 }) 879 )); 880 881 named!(pub within_block -> Vec<Stmt>, do_parse!( 882 many0!(punct!(";")) >> 883 mut standalone: many0!(terminated!(stmt, many0!(punct!(";")))) >> 884 last: option!(expr) >> 885 (match last { 886 None => standalone, 887 Some(last) => { 888 standalone.push(Stmt::Expr(Box::new(last))); 889 standalone 890 } 891 }) 892 )); 893 894 named!(pub stmt -> Stmt, alt!( 895 stmt_mac 896 | 897 stmt_local 898 | 899 stmt_item 900 | 901 stmt_expr 902 )); 903 904 named!(stmt_mac -> Stmt, do_parse!( 905 attrs: many0!(outer_attr) >> 906 what: path >> 907 punct!("!") >> 908 // Only parse braces here; paren and bracket will get parsed as 909 // expression statements 910 punct!("{") >> 911 tts: token_trees >> 912 punct!("}") >> 913 semi: option!(punct!(";")) >> 914 (Stmt::Mac(Box::new(( 915 Mac { 916 path: what, 917 tts: vec![TokenTree::Delimited(Delimited { 918 delim: DelimToken::Brace, 919 tts: tts, 920 })], 921 }, 922 if semi.is_some() { 923 MacStmtStyle::Semicolon 924 } else { 925 MacStmtStyle::Braces 926 }, 927 attrs, 928 )))) 929 )); 930 931 named!(stmt_local -> Stmt, do_parse!( 932 attrs: many0!(outer_attr) >> 933 keyword!("let") >> 934 pat: pat >> 935 ty: option!(preceded!(punct!(":"), ty)) >> 936 init: option!(preceded!(punct!("="), expr)) >> 937 punct!(";") >> 938 (Stmt::Local(Box::new(Local { 939 pat: Box::new(pat), 940 ty: ty.map(Box::new), 941 init: init.map(Box::new), 942 attrs: attrs, 943 }))) 944 )); 945 946 named!(stmt_item -> Stmt, map!(item, |i| Stmt::Item(Box::new(i)))); 947 requires_semi(e: &Expr) -> bool948 fn requires_semi(e: &Expr) -> bool { 949 match e.node { 950 ExprKind::If(_, _, _) | 951 ExprKind::IfLet(_, _, _, _) | 952 ExprKind::While(_, _, _) | 953 ExprKind::WhileLet(_, _, _, _) | 954 ExprKind::ForLoop(_, _, _, _) | 955 ExprKind::Loop(_, _) | 956 ExprKind::Match(_, _) | 957 ExprKind::Block(_, _) => false, 958 959 _ => true, 960 } 961 } 962 963 named!(stmt_expr -> Stmt, do_parse!( 964 attrs: many0!(outer_attr) >> 965 mut e: expr >> 966 semi: option!(punct!(";")) >> 967 ({ 968 e.attrs = attrs; 969 if semi.is_some() { 970 Stmt::Semi(Box::new(e)) 971 } else if requires_semi(&e) { 972 return Error; 973 } else { 974 Stmt::Expr(Box::new(e)) 975 } 976 }) 977 )); 978 979 named!(pub pat -> Pat, alt!( 980 pat_wild // must be before pat_ident 981 | 982 pat_box // must be before pat_ident 983 | 984 pat_range // must be before pat_lit 985 | 986 pat_tuple_struct // must be before pat_ident 987 | 988 pat_struct // must be before pat_ident 989 | 990 pat_mac // must be before pat_ident 991 | 992 pat_lit // must be before pat_ident 993 | 994 pat_ident // must be before pat_path 995 | 996 pat_path 997 | 998 pat_tuple 999 | 1000 pat_ref 1001 | 1002 pat_slice 1003 )); 1004 1005 named!(pat_mac -> Pat, map!(mac, Pat::Mac)); 1006 1007 named!(pat_wild -> Pat, map!(keyword!("_"), |_| Pat::Wild)); 1008 1009 named!(pat_box -> Pat, do_parse!( 1010 keyword!("box") >> 1011 pat: pat >> 1012 (Pat::Box(Box::new(pat))) 1013 )); 1014 1015 named!(pat_ident -> Pat, do_parse!( 1016 mode: option!(keyword!("ref")) >> 1017 mutability: mutability >> 1018 name: alt!( 1019 ident 1020 | 1021 keyword!("self") => { Into::into } 1022 ) >> 1023 not!(punct!("<")) >> 1024 not!(punct!("::")) >> 1025 subpat: option!(preceded!(punct!("@"), pat)) >> 1026 (Pat::Ident( 1027 if mode.is_some() { 1028 BindingMode::ByRef(mutability) 1029 } else { 1030 BindingMode::ByValue(mutability) 1031 }, 1032 name, 1033 subpat.map(Box::new), 1034 )) 1035 )); 1036 1037 named!(pat_tuple_struct -> Pat, do_parse!( 1038 path: path >> 1039 tuple: pat_tuple_helper >> 1040 (Pat::TupleStruct(path, tuple.0, tuple.1)) 1041 )); 1042 1043 named!(pat_struct -> Pat, do_parse!( 1044 path: path >> 1045 punct!("{") >> 1046 fields: separated_list!(punct!(","), field_pat) >> 1047 more: option!(preceded!( 1048 cond!(!fields.is_empty(), punct!(",")), 1049 punct!("..") 1050 )) >> 1051 cond!(!fields.is_empty() && more.is_none(), option!(punct!(","))) >> 1052 punct!("}") >> 1053 (Pat::Struct(path, fields, more.is_some())) 1054 )); 1055 1056 named!(field_pat -> FieldPat, alt!( 1057 do_parse!( 1058 ident: wordlike >> 1059 punct!(":") >> 1060 pat: pat >> 1061 (FieldPat { 1062 ident: ident, 1063 pat: Box::new(pat), 1064 is_shorthand: false, 1065 attrs: Vec::new(), 1066 }) 1067 ) 1068 | 1069 do_parse!( 1070 boxed: option!(keyword!("box")) >> 1071 mode: option!(keyword!("ref")) >> 1072 mutability: mutability >> 1073 ident: ident >> 1074 ({ 1075 let mut pat = Pat::Ident( 1076 if mode.is_some() { 1077 BindingMode::ByRef(mutability) 1078 } else { 1079 BindingMode::ByValue(mutability) 1080 }, 1081 ident.clone(), 1082 None, 1083 ); 1084 if boxed.is_some() { 1085 pat = Pat::Box(Box::new(pat)); 1086 } 1087 FieldPat { 1088 ident: ident, 1089 pat: Box::new(pat), 1090 is_shorthand: true, 1091 attrs: Vec::new(), 1092 } 1093 }) 1094 ) 1095 )); 1096 1097 named!(pat_path -> Pat, map!(qpath, |(qself, path)| Pat::Path(qself, path))); 1098 1099 named!(pat_tuple -> Pat, map!( 1100 pat_tuple_helper, 1101 |(pats, dotdot)| Pat::Tuple(pats, dotdot) 1102 )); 1103 1104 named!(pat_tuple_helper -> (Vec<Pat>, Option<usize>), do_parse!( 1105 punct!("(") >> 1106 mut elems: separated_list!(punct!(","), pat) >> 1107 dotdot: option!(do_parse!( 1108 cond!(!elems.is_empty(), punct!(",")) >> 1109 punct!("..") >> 1110 rest: many0!(preceded!(punct!(","), pat)) >> 1111 cond!(!rest.is_empty(), option!(punct!(","))) >> 1112 (rest) 1113 )) >> 1114 cond!(!elems.is_empty() && dotdot.is_none(), option!(punct!(","))) >> 1115 punct!(")") >> 1116 (match dotdot { 1117 Some(rest) => { 1118 let pos = elems.len(); 1119 elems.extend(rest); 1120 (elems, Some(pos)) 1121 } 1122 None => (elems, None), 1123 }) 1124 )); 1125 1126 named!(pat_ref -> Pat, do_parse!( 1127 punct!("&") >> 1128 mutability: mutability >> 1129 pat: pat >> 1130 (Pat::Ref(Box::new(pat), mutability)) 1131 )); 1132 1133 named!(pat_lit -> Pat, do_parse!( 1134 lit: pat_lit_expr >> 1135 (if let ExprKind::Path(_, _) = lit.node { 1136 return IResult::Error; // these need to be parsed by pat_path 1137 } else { 1138 Pat::Lit(Box::new(lit)) 1139 }) 1140 )); 1141 1142 named!(pat_range -> Pat, do_parse!( 1143 lo: pat_lit_expr >> 1144 punct!("...") >> 1145 hi: pat_lit_expr >> 1146 (Pat::Range(Box::new(lo), Box::new(hi))) 1147 )); 1148 1149 named!(pat_lit_expr -> Expr, do_parse!( 1150 neg: option!(punct!("-")) >> 1151 v: alt!( 1152 lit => { ExprKind::Lit } 1153 | 1154 path => { |p| ExprKind::Path(None, p) } 1155 ) >> 1156 (if neg.is_some() { 1157 ExprKind::Unary(UnOp::Neg, Box::new(v.into())).into() 1158 } else { 1159 v.into() 1160 }) 1161 )); 1162 1163 named!(pat_slice -> Pat, do_parse!( 1164 punct!("[") >> 1165 mut before: separated_list!(punct!(","), pat) >> 1166 after: option!(do_parse!( 1167 comma_before_dots: option!(cond_reduce!(!before.is_empty(), punct!(","))) >> 1168 punct!("..") >> 1169 after: many0!(preceded!(punct!(","), pat)) >> 1170 cond!(!after.is_empty(), option!(punct!(","))) >> 1171 (comma_before_dots.is_some(), after) 1172 )) >> 1173 cond!(after.is_none(), option!(punct!(","))) >> 1174 punct!("]") >> 1175 (match after { 1176 None => Pat::Slice(before, None, Vec::new()), 1177 Some((true, after)) => { 1178 if before.is_empty() { 1179 return IResult::Error; 1180 } 1181 Pat::Slice(before, Some(Box::new(Pat::Wild)), after) 1182 } 1183 Some((false, after)) => { 1184 let rest = before.pop().unwrap_or(Pat::Wild); 1185 Pat::Slice(before, Some(Box::new(rest)), after) 1186 } 1187 }) 1188 )); 1189 1190 named!(capture_by -> CaptureBy, alt!( 1191 keyword!("move") => { |_| CaptureBy::Value } 1192 | 1193 epsilon!() => { |_| CaptureBy::Ref } 1194 )); 1195 1196 named!(label -> Ident, map!(lifetime, |lt: Lifetime| lt.ident)); 1197 } 1198 1199 #[cfg(feature = "printing")] 1200 mod printing { 1201 use super::*; 1202 use {FnArg, FunctionRetTy, Mutability, Ty, Unsafety}; 1203 use attr::FilterAttrs; 1204 use quote::{Tokens, ToTokens}; 1205 1206 impl ToTokens for Expr { to_tokens(&self, tokens: &mut Tokens)1207 fn to_tokens(&self, tokens: &mut Tokens) { 1208 tokens.append_all(self.attrs.outer()); 1209 match self.node { 1210 ExprKind::Box(ref inner) => { 1211 tokens.append("box"); 1212 inner.to_tokens(tokens); 1213 } 1214 ExprKind::InPlace(ref place, ref value) => { 1215 tokens.append("in"); 1216 place.to_tokens(tokens); 1217 value.to_tokens(tokens); 1218 } 1219 ExprKind::Array(ref tys) => { 1220 tokens.append("["); 1221 tokens.append_separated(tys, ","); 1222 tokens.append("]"); 1223 } 1224 ExprKind::Call(ref func, ref args) => { 1225 func.to_tokens(tokens); 1226 tokens.append("("); 1227 tokens.append_separated(args, ","); 1228 tokens.append(")"); 1229 } 1230 ExprKind::MethodCall(ref ident, ref ascript, ref args) => { 1231 args[0].to_tokens(tokens); 1232 tokens.append("."); 1233 ident.to_tokens(tokens); 1234 if !ascript.is_empty() { 1235 tokens.append("::"); 1236 tokens.append("<"); 1237 tokens.append_separated(ascript, ","); 1238 tokens.append(">"); 1239 } 1240 tokens.append("("); 1241 tokens.append_separated(&args[1..], ","); 1242 tokens.append(")"); 1243 } 1244 ExprKind::Tup(ref fields) => { 1245 tokens.append("("); 1246 tokens.append_separated(fields, ","); 1247 if fields.len() == 1 { 1248 tokens.append(","); 1249 } 1250 tokens.append(")"); 1251 } 1252 ExprKind::Binary(op, ref left, ref right) => { 1253 left.to_tokens(tokens); 1254 op.to_tokens(tokens); 1255 right.to_tokens(tokens); 1256 } 1257 ExprKind::Unary(op, ref expr) => { 1258 op.to_tokens(tokens); 1259 expr.to_tokens(tokens); 1260 } 1261 ExprKind::Lit(ref lit) => lit.to_tokens(tokens), 1262 ExprKind::Cast(ref expr, ref ty) => { 1263 expr.to_tokens(tokens); 1264 tokens.append("as"); 1265 ty.to_tokens(tokens); 1266 } 1267 ExprKind::Type(ref expr, ref ty) => { 1268 expr.to_tokens(tokens); 1269 tokens.append(":"); 1270 ty.to_tokens(tokens); 1271 } 1272 ExprKind::If(ref cond, ref then_block, ref else_block) => { 1273 tokens.append("if"); 1274 cond.to_tokens(tokens); 1275 then_block.to_tokens(tokens); 1276 if let Some(ref else_block) = *else_block { 1277 tokens.append("else"); 1278 else_block.to_tokens(tokens); 1279 } 1280 } 1281 ExprKind::IfLet(ref pat, ref expr, ref then_block, ref else_block) => { 1282 tokens.append("if"); 1283 tokens.append("let"); 1284 pat.to_tokens(tokens); 1285 tokens.append("="); 1286 expr.to_tokens(tokens); 1287 then_block.to_tokens(tokens); 1288 if let Some(ref else_block) = *else_block { 1289 tokens.append("else"); 1290 else_block.to_tokens(tokens); 1291 } 1292 } 1293 ExprKind::While(ref cond, ref body, ref label) => { 1294 if let Some(ref label) = *label { 1295 label.to_tokens(tokens); 1296 tokens.append(":"); 1297 } 1298 tokens.append("while"); 1299 cond.to_tokens(tokens); 1300 body.to_tokens(tokens); 1301 } 1302 ExprKind::WhileLet(ref pat, ref expr, ref body, ref label) => { 1303 if let Some(ref label) = *label { 1304 label.to_tokens(tokens); 1305 tokens.append(":"); 1306 } 1307 tokens.append("while"); 1308 tokens.append("let"); 1309 pat.to_tokens(tokens); 1310 tokens.append("="); 1311 expr.to_tokens(tokens); 1312 body.to_tokens(tokens); 1313 } 1314 ExprKind::ForLoop(ref pat, ref expr, ref body, ref label) => { 1315 if let Some(ref label) = *label { 1316 label.to_tokens(tokens); 1317 tokens.append(":"); 1318 } 1319 tokens.append("for"); 1320 pat.to_tokens(tokens); 1321 tokens.append("in"); 1322 expr.to_tokens(tokens); 1323 body.to_tokens(tokens); 1324 } 1325 ExprKind::Loop(ref body, ref label) => { 1326 if let Some(ref label) = *label { 1327 label.to_tokens(tokens); 1328 tokens.append(":"); 1329 } 1330 tokens.append("loop"); 1331 body.to_tokens(tokens); 1332 } 1333 ExprKind::Match(ref expr, ref arms) => { 1334 tokens.append("match"); 1335 expr.to_tokens(tokens); 1336 tokens.append("{"); 1337 tokens.append_all(arms); 1338 tokens.append("}"); 1339 } 1340 ExprKind::Closure(capture, ref decl, ref expr) => { 1341 capture.to_tokens(tokens); 1342 tokens.append("|"); 1343 for (i, input) in decl.inputs.iter().enumerate() { 1344 if i > 0 { 1345 tokens.append(","); 1346 } 1347 match *input { 1348 FnArg::Captured(ref pat, Ty::Infer) => { 1349 pat.to_tokens(tokens); 1350 } 1351 _ => input.to_tokens(tokens), 1352 } 1353 } 1354 tokens.append("|"); 1355 match decl.output { 1356 FunctionRetTy::Default => { /* nothing */ } 1357 FunctionRetTy::Ty(ref ty) => { 1358 tokens.append("->"); 1359 ty.to_tokens(tokens); 1360 } 1361 } 1362 expr.to_tokens(tokens); 1363 } 1364 ExprKind::Block(rules, ref block) => { 1365 rules.to_tokens(tokens); 1366 block.to_tokens(tokens); 1367 } 1368 ExprKind::Assign(ref var, ref expr) => { 1369 var.to_tokens(tokens); 1370 tokens.append("="); 1371 expr.to_tokens(tokens); 1372 } 1373 ExprKind::AssignOp(op, ref var, ref expr) => { 1374 var.to_tokens(tokens); 1375 tokens.append(op.assign_op().unwrap()); 1376 expr.to_tokens(tokens); 1377 } 1378 ExprKind::Field(ref expr, ref field) => { 1379 expr.to_tokens(tokens); 1380 tokens.append("."); 1381 field.to_tokens(tokens); 1382 } 1383 ExprKind::TupField(ref expr, field) => { 1384 expr.to_tokens(tokens); 1385 tokens.append("."); 1386 tokens.append(&field.to_string()); 1387 } 1388 ExprKind::Index(ref expr, ref index) => { 1389 expr.to_tokens(tokens); 1390 tokens.append("["); 1391 index.to_tokens(tokens); 1392 tokens.append("]"); 1393 } 1394 ExprKind::Range(ref from, ref to, limits) => { 1395 from.to_tokens(tokens); 1396 match limits { 1397 RangeLimits::HalfOpen => tokens.append(".."), 1398 RangeLimits::Closed => tokens.append("..."), 1399 } 1400 to.to_tokens(tokens); 1401 } 1402 ExprKind::Path(None, ref path) => path.to_tokens(tokens), 1403 ExprKind::Path(Some(ref qself), ref path) => { 1404 tokens.append("<"); 1405 qself.ty.to_tokens(tokens); 1406 if qself.position > 0 { 1407 tokens.append("as"); 1408 for (i, segment) in path.segments 1409 .iter() 1410 .take(qself.position) 1411 .enumerate() { 1412 if i > 0 || path.global { 1413 tokens.append("::"); 1414 } 1415 segment.to_tokens(tokens); 1416 } 1417 } 1418 tokens.append(">"); 1419 for segment in path.segments.iter().skip(qself.position) { 1420 tokens.append("::"); 1421 segment.to_tokens(tokens); 1422 } 1423 } 1424 ExprKind::AddrOf(mutability, ref expr) => { 1425 tokens.append("&"); 1426 mutability.to_tokens(tokens); 1427 expr.to_tokens(tokens); 1428 } 1429 ExprKind::Break(ref opt_label, ref opt_val) => { 1430 tokens.append("break"); 1431 opt_label.to_tokens(tokens); 1432 opt_val.to_tokens(tokens); 1433 } 1434 ExprKind::Continue(ref opt_label) => { 1435 tokens.append("continue"); 1436 opt_label.to_tokens(tokens); 1437 } 1438 ExprKind::Ret(ref opt_expr) => { 1439 tokens.append("return"); 1440 opt_expr.to_tokens(tokens); 1441 } 1442 ExprKind::Mac(ref mac) => mac.to_tokens(tokens), 1443 ExprKind::Struct(ref path, ref fields, ref base) => { 1444 path.to_tokens(tokens); 1445 tokens.append("{"); 1446 tokens.append_separated(fields, ","); 1447 if let Some(ref base) = *base { 1448 if !fields.is_empty() { 1449 tokens.append(","); 1450 } 1451 tokens.append(".."); 1452 base.to_tokens(tokens); 1453 } 1454 tokens.append("}"); 1455 } 1456 ExprKind::Repeat(ref expr, ref times) => { 1457 tokens.append("["); 1458 expr.to_tokens(tokens); 1459 tokens.append(";"); 1460 times.to_tokens(tokens); 1461 tokens.append("]"); 1462 } 1463 ExprKind::Paren(ref expr) => { 1464 tokens.append("("); 1465 expr.to_tokens(tokens); 1466 tokens.append(")"); 1467 } 1468 ExprKind::Try(ref expr) => { 1469 expr.to_tokens(tokens); 1470 tokens.append("?"); 1471 } 1472 } 1473 } 1474 } 1475 1476 impl ToTokens for FieldValue { to_tokens(&self, tokens: &mut Tokens)1477 fn to_tokens(&self, tokens: &mut Tokens) { 1478 self.ident.to_tokens(tokens); 1479 if !self.is_shorthand { 1480 tokens.append(":"); 1481 self.expr.to_tokens(tokens); 1482 } 1483 } 1484 } 1485 1486 impl ToTokens for Arm { to_tokens(&self, tokens: &mut Tokens)1487 fn to_tokens(&self, tokens: &mut Tokens) { 1488 for attr in &self.attrs { 1489 attr.to_tokens(tokens); 1490 } 1491 tokens.append_separated(&self.pats, "|"); 1492 if let Some(ref guard) = self.guard { 1493 tokens.append("if"); 1494 guard.to_tokens(tokens); 1495 } 1496 tokens.append("=>"); 1497 self.body.to_tokens(tokens); 1498 match self.body.node { 1499 ExprKind::Block(Unsafety::Normal, _) => { 1500 // no comma 1501 } 1502 _ => tokens.append(","), 1503 } 1504 } 1505 } 1506 1507 impl ToTokens for Pat { to_tokens(&self, tokens: &mut Tokens)1508 fn to_tokens(&self, tokens: &mut Tokens) { 1509 match *self { 1510 Pat::Wild => tokens.append("_"), 1511 Pat::Ident(mode, ref ident, ref subpat) => { 1512 mode.to_tokens(tokens); 1513 ident.to_tokens(tokens); 1514 if let Some(ref subpat) = *subpat { 1515 tokens.append("@"); 1516 subpat.to_tokens(tokens); 1517 } 1518 } 1519 Pat::Struct(ref path, ref fields, dots) => { 1520 path.to_tokens(tokens); 1521 tokens.append("{"); 1522 tokens.append_separated(fields, ","); 1523 if dots { 1524 if !fields.is_empty() { 1525 tokens.append(","); 1526 } 1527 tokens.append(".."); 1528 } 1529 tokens.append("}"); 1530 } 1531 Pat::TupleStruct(ref path, ref pats, dotpos) => { 1532 path.to_tokens(tokens); 1533 tokens.append("("); 1534 match dotpos { 1535 Some(pos) => { 1536 if pos > 0 { 1537 tokens.append_separated(&pats[..pos], ","); 1538 tokens.append(","); 1539 } 1540 tokens.append(".."); 1541 if pos < pats.len() { 1542 tokens.append(","); 1543 tokens.append_separated(&pats[pos..], ","); 1544 } 1545 } 1546 None => tokens.append_separated(pats, ","), 1547 } 1548 tokens.append(")"); 1549 } 1550 Pat::Path(None, ref path) => path.to_tokens(tokens), 1551 Pat::Path(Some(ref qself), ref path) => { 1552 tokens.append("<"); 1553 qself.ty.to_tokens(tokens); 1554 if qself.position > 0 { 1555 tokens.append("as"); 1556 for (i, segment) in path.segments 1557 .iter() 1558 .take(qself.position) 1559 .enumerate() { 1560 if i > 0 || path.global { 1561 tokens.append("::"); 1562 } 1563 segment.to_tokens(tokens); 1564 } 1565 } 1566 tokens.append(">"); 1567 for segment in path.segments.iter().skip(qself.position) { 1568 tokens.append("::"); 1569 segment.to_tokens(tokens); 1570 } 1571 } 1572 Pat::Tuple(ref pats, dotpos) => { 1573 tokens.append("("); 1574 match dotpos { 1575 Some(pos) => { 1576 if pos > 0 { 1577 tokens.append_separated(&pats[..pos], ","); 1578 tokens.append(","); 1579 } 1580 tokens.append(".."); 1581 if pos < pats.len() { 1582 tokens.append(","); 1583 tokens.append_separated(&pats[pos..], ","); 1584 } 1585 } 1586 None => { 1587 tokens.append_separated(pats, ","); 1588 if pats.len() == 1 { 1589 tokens.append(","); 1590 } 1591 } 1592 } 1593 tokens.append(")"); 1594 } 1595 Pat::Box(ref inner) => { 1596 tokens.append("box"); 1597 inner.to_tokens(tokens); 1598 } 1599 Pat::Ref(ref target, mutability) => { 1600 tokens.append("&"); 1601 mutability.to_tokens(tokens); 1602 target.to_tokens(tokens); 1603 } 1604 Pat::Lit(ref lit) => lit.to_tokens(tokens), 1605 Pat::Range(ref lo, ref hi) => { 1606 lo.to_tokens(tokens); 1607 tokens.append("..."); 1608 hi.to_tokens(tokens); 1609 } 1610 Pat::Slice(ref before, ref rest, ref after) => { 1611 tokens.append("["); 1612 tokens.append_separated(before, ","); 1613 if let Some(ref rest) = *rest { 1614 if !before.is_empty() { 1615 tokens.append(","); 1616 } 1617 if **rest != Pat::Wild { 1618 rest.to_tokens(tokens); 1619 } 1620 tokens.append(".."); 1621 if !after.is_empty() { 1622 tokens.append(","); 1623 } 1624 tokens.append_separated(after, ","); 1625 } 1626 tokens.append("]"); 1627 } 1628 Pat::Mac(ref mac) => mac.to_tokens(tokens), 1629 } 1630 } 1631 } 1632 1633 impl ToTokens for FieldPat { to_tokens(&self, tokens: &mut Tokens)1634 fn to_tokens(&self, tokens: &mut Tokens) { 1635 if !self.is_shorthand { 1636 self.ident.to_tokens(tokens); 1637 tokens.append(":"); 1638 } 1639 self.pat.to_tokens(tokens); 1640 } 1641 } 1642 1643 impl ToTokens for BindingMode { to_tokens(&self, tokens: &mut Tokens)1644 fn to_tokens(&self, tokens: &mut Tokens) { 1645 match *self { 1646 BindingMode::ByRef(Mutability::Immutable) => { 1647 tokens.append("ref"); 1648 } 1649 BindingMode::ByRef(Mutability::Mutable) => { 1650 tokens.append("ref"); 1651 tokens.append("mut"); 1652 } 1653 BindingMode::ByValue(Mutability::Immutable) => {} 1654 BindingMode::ByValue(Mutability::Mutable) => { 1655 tokens.append("mut"); 1656 } 1657 } 1658 } 1659 } 1660 1661 impl ToTokens for CaptureBy { to_tokens(&self, tokens: &mut Tokens)1662 fn to_tokens(&self, tokens: &mut Tokens) { 1663 match *self { 1664 CaptureBy::Value => tokens.append("move"), 1665 CaptureBy::Ref => { 1666 // nothing 1667 } 1668 } 1669 } 1670 } 1671 1672 impl ToTokens for Block { to_tokens(&self, tokens: &mut Tokens)1673 fn to_tokens(&self, tokens: &mut Tokens) { 1674 tokens.append("{"); 1675 tokens.append_all(&self.stmts); 1676 tokens.append("}"); 1677 } 1678 } 1679 1680 impl ToTokens for Stmt { to_tokens(&self, tokens: &mut Tokens)1681 fn to_tokens(&self, tokens: &mut Tokens) { 1682 match *self { 1683 Stmt::Local(ref local) => local.to_tokens(tokens), 1684 Stmt::Item(ref item) => item.to_tokens(tokens), 1685 Stmt::Expr(ref expr) => expr.to_tokens(tokens), 1686 Stmt::Semi(ref expr) => { 1687 expr.to_tokens(tokens); 1688 tokens.append(";"); 1689 } 1690 Stmt::Mac(ref mac) => { 1691 let (ref mac, style, ref attrs) = **mac; 1692 tokens.append_all(attrs.outer()); 1693 mac.to_tokens(tokens); 1694 match style { 1695 MacStmtStyle::Semicolon => tokens.append(";"), 1696 MacStmtStyle::Braces | MacStmtStyle::NoBraces => { 1697 // no semicolon 1698 } 1699 } 1700 } 1701 } 1702 } 1703 } 1704 1705 impl ToTokens for Local { to_tokens(&self, tokens: &mut Tokens)1706 fn to_tokens(&self, tokens: &mut Tokens) { 1707 tokens.append_all(self.attrs.outer()); 1708 tokens.append("let"); 1709 self.pat.to_tokens(tokens); 1710 if let Some(ref ty) = self.ty { 1711 tokens.append(":"); 1712 ty.to_tokens(tokens); 1713 } 1714 if let Some(ref init) = self.init { 1715 tokens.append("="); 1716 init.to_tokens(tokens); 1717 } 1718 tokens.append(";"); 1719 } 1720 } 1721 } 1722