1use super::*;
2use delimited::Delimited;
3
4ast_struct! {
5 pub struct Expr {
7 pub node: ExprKind,
9
10 pub attrs: Vec<Attribute>,
12 }
13}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
24ast_enum_of_structs! {
25 pub enum ExprKind {
26 pub Box(ExprBox #full {
28 pub expr: Box<Expr>,
29 pub box_token: tokens::Box_,
30 }),
31
32 pub InPlace(ExprInPlace #full {
34 pub place: Box<Expr>,
35 pub kind: InPlaceKind,
36 pub value: Box<Expr>,
37 }),
38
39 pub Array(ExprArray #full {
41 pub exprs: Delimited<Expr, tokens::Comma>,
42 pub bracket_token: tokens::Bracket,
43 }),
44
45 pub Call(ExprCall {
47 pub func: Box<Expr>,
48 pub args: Delimited<Expr, tokens::Comma>,
49 pub paren_token: tokens::Paren,
50 }),
51
52 pub MethodCall(ExprMethodCall #full {
61 pub expr: Box<Expr>,
62 pub method: Ident,
63 pub typarams: Delimited<Ty, tokens::Comma>,
64 pub args: Delimited<Expr, tokens::Comma>,
65 pub paren_token: tokens::Paren,
66 pub dot_token: tokens::Dot,
67 pub lt_token: Option<tokens::Lt>,
68 pub colon2_token: Option<tokens::Colon2>,
69 pub gt_token: Option<tokens::Gt>,
70 }),
71
72 pub Tup(ExprTup #full {
74 pub args: Delimited<Expr, tokens::Comma>,
75 pub paren_token: tokens::Paren,
76 pub lone_comma: Option<tokens::Comma>,
77 }),
78
79 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
85
86 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
91
92 pub Lit(Lit),
94
95 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
98 pub as_token: tokens::As,
99 pub ty: Box<Ty>,
100 }),
101
102 pub Type(ExprType {
104 pub expr: Box<Expr>,
105 pub colon_token: tokens::Colon,
106 pub ty: Box<Ty>,
107 }),
108
109 pub If(ExprIf #full {
113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
116 pub if_token: tokens::If,
117 pub else_token: Option<tokens::Else>,
118 }),
119
120 pub IfLet(ExprIfLet #full {
126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
130 pub if_token: tokens::If,
131 pub let_token: tokens::Let,
132 pub eq_token: tokens::Eq,
133 pub else_token: Option<tokens::Else>,
134 }),
135
136 pub While(ExprWhile #full {
140 pub cond: Box<Expr>,
141 pub body: Block,
142 pub label: Option<Lifetime>,
143 pub colon_token: Option<tokens::Colon>,
144 pub while_token: tokens::While,
145 }),
146
147 pub WhileLet(ExprWhileLet #full {
153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
156 pub label: Option<Lifetime>,
157 pub colon_token: Option<tokens::Colon>,
158 pub while_token: tokens::While,
159 pub let_token: tokens::Let,
160 pub eq_token: tokens::Eq,
161 }),
162
163 pub ForLoop(ExprForLoop #full {
169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
172 pub label: Option<Lifetime>,
173 pub for_token: tokens::For,
174 pub colon_token: Option<tokens::Colon>,
175 pub in_token: tokens::In,
176 }),
177
178 pub Loop(ExprLoop #full {
182 pub body: Block,
183 pub label: Option<Lifetime>,
184 pub loop_token: tokens::Loop,
185 pub colon_token: Option<tokens::Colon>,
186 }),
187
188 pub Match(ExprMatch #full {
190 pub match_token: tokens::Match,
191 pub brace_token: tokens::Brace,
192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
195
196 pub Closure(ExprClosure #full {
198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
201 pub or1_token: tokens::Or,
202 pub or2_token: tokens::Or,
203 }),
204
205 pub Block(ExprBlock #full {
207 pub unsafety: Unsafety,
208 pub block: Block,
209 }),
210
211 pub Assign(ExprAssign #full {
213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
215 pub eq_token: tokens::Eq,
216 }),
217
218 pub AssignOp(ExprAssignOp #full {
222 pub op: BinOp,
223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
225 }),
226
227 pub Field(ExprField #full {
229 pub expr: Box<Expr>,
230 pub field: Ident,
231 pub dot_token: tokens::Dot,
232 }),
233
234 pub TupField(ExprTupField #full {
238 pub expr: Box<Expr>,
239 pub field: Lit,
240 pub dot_token: tokens::Dot,
241 }),
242
243 pub Index(ExprIndex {
245 pub expr: Box<Expr>,
246 pub index: Box<Expr>,
247 pub bracket_token: tokens::Bracket,
248 }),
249
250 pub Range(ExprRange #full {
252 pub from: Option<Box<Expr>>,
253 pub to: Option<Box<Expr>>,
254 pub limits: RangeLimits,
255 }),
256
257 pub Path(ExprPath {
263 pub qself: Option<QSelf>,
264 pub path: Path,
265 }),
266
267 pub AddrOf(ExprAddrOf #full {
269 pub and_token: tokens::And,
270 pub mutbl: Mutability,
271 pub expr: Box<Expr>,
272 }),
273
274 pub Break(ExprBreak #full {
276 pub label: Option<Lifetime>,
277 pub expr: Option<Box<Expr>>,
278 pub break_token: tokens::Break,
279 }),
280
281 pub Continue(ExprContinue #full {
283 pub label: Option<Lifetime>,
284 pub continue_token: tokens::Continue,
285 }),
286
287 pub Ret(ExprRet #full {
289 pub expr: Option<Box<Expr>>,
290 pub return_token: tokens::Return,
291 }),
292
293 pub Mac(Mac),
295
296 pub Struct(ExprStruct #full {
301 pub path: Path,
302 pub fields: Delimited<FieldValue, tokens::Comma>,
303 pub rest: Option<Box<Expr>>,
304 pub dot2_token: Option<tokens::Dot2>,
305 pub brace_token: tokens::Brace,
306 }),
307
308 pub Repeat(ExprRepeat #full {
313 pub bracket_token: tokens::Bracket,
314 pub semi_token: tokens::Semi,
315 pub expr: Box<Expr>,
316 pub amt: Box<Expr>,
317 }),
318
319 pub Paren(ExprParen {
321 pub expr: Box<Expr>,
322 pub paren_token: tokens::Paren,
323 }),
324
325 pub Group(ExprGroup {
331 pub expr: Box<Expr>,
332 pub group_token: tokens::Group,
333 }),
334
335 pub Try(ExprTry #full {
337 pub expr: Box<Expr>,
338 pub question_token: tokens::Question,
339 }),
340
341 pub Catch(ExprCatch #full {
345 pub do_token: tokens::Do,
346 pub catch_token: tokens::Catch,
347 pub block: Block,
348 }),
349
350 pub Yield(ExprYield #full {
354 pub yield_token: tokens::Yield,
355 pub expr: Option<Box<Expr>>,
356 }),
357 }
358}
359
360#[cfg(feature = "full")]
361ast_struct! {
362 pub struct FieldValue {
364 pub ident: Ident,
366
367 pub expr: Expr,
369
370 pub is_shorthand: bool,
373
374 pub attrs: Vec<Attribute>,
376
377 pub colon_token: Option<tokens::Colon>,
378 }
379}
380
381#[cfg(feature = "full")]
382ast_struct! {
383 pub struct Block {
387 pub brace_token: tokens::Brace,
388 pub stmts: Vec<Stmt>,
390 }
391}
392
393#[cfg(feature = "full")]
394ast_enum! {
395 pub enum Stmt {
397 Local(Box<Local>),
399
400 Item(Box<Item>),
402
403 Expr(Box<Expr>),
405
406 Semi(Box<Expr>, tokens::Semi),
408
409 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
411 }
412}
413
414#[cfg(feature = "full")]
415ast_enum! {
416 #[cfg_attr(feature = "clone-impls", derive(Copy))]
418 pub enum MacStmtStyle {
419 Semicolon(tokens::Semi),
422
423 Braces,
425
426 NoBraces,
430 }
431}
432
433#[cfg(feature = "full")]
434ast_struct! {
435 pub struct Local {
437 pub let_token: tokens::Let,
438 pub colon_token: Option<tokens::Colon>,
439 pub eq_token: Option<tokens::Eq>,
440 pub semi_token: tokens::Semi,
441
442 pub pat: Box<Pat>,
443 pub ty: Option<Box<Ty>>,
444
445 pub init: Option<Box<Expr>>,
447 pub attrs: Vec<Attribute>,
448 }
449}
450
451#[cfg(feature = "full")]
452ast_enum_of_structs! {
453 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
456 pub enum Pat {
457 pub Wild(PatWild {
459 pub underscore_token: tokens::Underscore,
460 }),
461
462 pub Ident(PatIdent {
467 pub mode: BindingMode,
468 pub ident: Ident,
469 pub subpat: Option<Box<Pat>>,
470 pub at_token: Option<tokens::At>,
471 }),
472
473 pub Struct(PatStruct {
476 pub path: Path,
477 pub fields: Delimited<FieldPat, tokens::Comma>,
478 pub brace_token: tokens::Brace,
479 pub dot2_token: Option<tokens::Dot2>,
480 }),
481
482 pub TupleStruct(PatTupleStruct {
486 pub path: Path,
487 pub pat: PatTuple,
488 }),
489
490 pub Path(PatPath {
495 pub qself: Option<QSelf>,
496 pub path: Path,
497 }),
498
499 pub Tuple(PatTuple {
503 pub pats: Delimited<Pat, tokens::Comma>,
504 pub dots_pos: Option<usize>,
505 pub paren_token: tokens::Paren,
506 pub dot2_token: Option<tokens::Dot2>,
507 pub comma_token: Option<tokens::Comma>,
508 }),
509 pub Box(PatBox {
511 pub pat: Box<Pat>,
512 pub box_token: tokens::Box_,
513 }),
514 pub Ref(PatRef {
516 pub pat: Box<Pat>,
517 pub mutbl: Mutability,
518 pub and_token: tokens::And,
519 }),
520 pub Lit(PatLit {
522 pub expr: Box<Expr>,
523 }),
524 pub Range(PatRange {
526 pub lo: Box<Expr>,
527 pub hi: Box<Expr>,
528 pub limits: RangeLimits,
529 }),
530 pub Slice(PatSlice {
532 pub front: Delimited<Pat, tokens::Comma>,
533 pub middle: Option<Box<Pat>>,
534 pub back: Delimited<Pat, tokens::Comma>,
535 pub dot2_token: Option<tokens::Dot2>,
536 pub comma_token: Option<tokens::Comma>,
537 pub bracket_token: tokens::Bracket,
538 }),
539 pub Mac(Mac),
541 }
542}
543
544#[cfg(feature = "full")]
545ast_struct! {
546 pub struct Arm {
557 pub attrs: Vec<Attribute>,
558 pub pats: Delimited<Pat, tokens::Or>,
559 pub if_token: Option<tokens::If>,
560 pub guard: Option<Box<Expr>>,
561 pub rocket_token: tokens::Rocket,
562 pub body: Box<Expr>,
563 pub comma: Option<tokens::Comma>,
564 }
565}
566
567#[cfg(feature = "full")]
568ast_enum! {
569 #[cfg_attr(feature = "clone-impls", derive(Copy))]
571 pub enum CaptureBy {
572 Value(tokens::Move),
573 Ref,
574 }
575}
576
577#[cfg(feature = "full")]
578ast_enum! {
579 #[cfg_attr(feature = "clone-impls", derive(Copy))]
581 pub enum RangeLimits {
582 HalfOpen(tokens::Dot2),
584 Closed(tokens::Dot3),
586 }
587}
588
589#[cfg(feature = "full")]
590ast_struct! {
591 pub struct FieldPat {
597 pub ident: Ident,
599 pub pat: Box<Pat>,
601 pub is_shorthand: bool,
602 pub colon_token: Option<tokens::Colon>,
603 pub attrs: Vec<Attribute>,
604 }
605}
606
607#[cfg(feature = "full")]
608ast_enum! {
609 #[cfg_attr(feature = "clone-impls", derive(Copy))]
610 pub enum BindingMode {
611 ByRef(tokens::Ref, Mutability),
612 ByValue(Mutability),
613 }
614}
615
616#[cfg(feature = "full")]
617ast_enum! {
618 #[cfg_attr(feature = "clone-impls", derive(Copy))]
619 pub enum InPlaceKind {
620 Arrow(tokens::LArrow),
621 In(tokens::In),
622 }
623}
624
625#[cfg(any(feature = "parsing", feature = "printing"))]
626#[cfg(feature = "full")]
627fn arm_expr_requires_comma(expr: &Expr) -> bool {
628 match expr.node {
631 ExprKind::Block(..) |
632 ExprKind::If(..) |
633 ExprKind::IfLet(..) |
634 ExprKind::Match(..) |
635 ExprKind::While(..) |
636 ExprKind::WhileLet(..) |
637 ExprKind::Loop(..) |
638 ExprKind::ForLoop(..) |
639 ExprKind::Catch(..) => false,
640 _ => true,
641 }
642}
643
644#[cfg(feature = "parsing")]
645pub mod parsing {
646 use super::*;
647 use ty::parsing::qpath;
648
649 #[cfg(feature = "full")]
650 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
651 use synom::{PResult, Cursor, Synom};
652 #[cfg(feature = "full")]
653 use synom::parse_error;
654 use synom::tokens::*;
655
656 macro_rules! ambiguous_expr {
662 ($i:expr, $allow_struct:ident) => {
663 ambiguous_expr($i, $allow_struct, true)
664 };
665 }
666
667 #[cfg(feature = "full")]
679 macro_rules! opt_ambiguous_expr {
680 ($i:expr, $allow_struct:ident) => {
681 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
682 };
683 }
684
685 impl Synom for Expr {
686 named!(parse -> Self, ambiguous_expr!(true));
687
688 fn description() -> Option<&'static str> {
689 Some("expression")
690 }
691 }
692
693 #[cfg(feature = "full")]
694 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
695
696 #[cfg(feature = "full")]
698 fn ambiguous_expr(i: Cursor,
699 allow_struct: bool,
700 allow_block: bool)
701 -> PResult<Expr> {
702 map!(
703 i,
704 call!(assign_expr, allow_struct, allow_block),
705 ExprKind::into
706 )
707 }
708
709 #[cfg(not(feature = "full"))]
710 fn ambiguous_expr(i: Cursor,
711 allow_struct: bool,
712 allow_block: bool)
713 -> PResult<Expr> {
714 map!(
715 i,
716 call!(or_expr, allow_struct, allow_block),
719 ExprKind::into
720 )
721 }
722
723 macro_rules! binop {
725 (
726 $name: ident,
727 $next: ident,
728 $submac: ident!( $($args:tt)* )
729 ) => {
730 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
731 mut e: call!($next, allow_struct, allow_block) >>
732 many0!(do_parse!(
733 op: $submac!($($args)*) >>
734 rhs: call!($next, allow_struct, true) >>
735 ({
736 e = ExprBinary {
737 left: Box::new(e.into()),
738 op: op,
739 right: Box::new(rhs.into()),
740 }.into();
741 })
742 )) >>
743 (e)
744 ));
745 }
746 }
747
748 #[cfg(feature = "full")]
764 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
765 mut e: call!(placement_expr, allow_struct, allow_block) >>
766 alt!(
767 do_parse!(
768 eq: syn!(Eq) >>
769 rhs: call!(assign_expr, allow_struct, true) >>
771 ({
772 e = ExprAssign {
773 left: Box::new(e.into()),
774 eq_token: eq,
775 right: Box::new(rhs.into()),
776 }.into();
777 })
778 )
779 |
780 do_parse!(
781 op: call!(BinOp::parse_assign_op) >>
782 rhs: call!(assign_expr, allow_struct, true) >>
784 ({
785 e = ExprAssignOp {
786 left: Box::new(e.into()),
787 op: op,
788 right: Box::new(rhs.into()),
789 }.into();
790 })
791 )
792 |
793 epsilon!()
794 ) >>
795 (e)
796 ));
797
798 #[cfg(feature = "full")]
807 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
808 mut e: call!(range_expr, allow_struct, allow_block) >>
809 alt!(
810 do_parse!(
811 arrow: syn!(LArrow) >>
812 rhs: call!(placement_expr, allow_struct, true) >>
814 ({
815 e = ExprInPlace {
816 place: Box::new(e.into()),
818 kind: InPlaceKind::Arrow(arrow),
819 value: Box::new(rhs.into()),
820 }.into();
821 })
822 )
823 |
824 epsilon!()
825 ) >>
826 (e)
827 ));
828
829 #[cfg(feature = "full")]
843 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
844 mut e: call!(or_expr, allow_struct, allow_block) >>
845 many0!(do_parse!(
846 limits: syn!(RangeLimits) >>
847 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
850 ({
851 e = ExprRange {
852 from: Some(Box::new(e.into())),
853 limits: limits,
854 to: hi.map(|e| Box::new(e.into())),
855 }.into();
856 })
857 )) >>
858 (e)
859 ));
860
861 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
865
866 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
870
871 binop!(compare_expr, bitor_expr, alt!(
883 syn!(EqEq) => { BinOp::Eq }
884 |
885 syn!(Ne) => { BinOp::Ne }
886 |
887 syn!(Le) => { BinOp::Le }
889 |
890 syn!(Ge) => { BinOp::Ge }
892 |
893 do_parse!(
894 not!(syn!(LArrow)) >>
896 t: syn!(Lt) >>
897 (BinOp::Lt(t))
898 )
899 |
900 syn!(Gt) => { BinOp::Gt }
901 ));
902
903 binop!(bitor_expr, bitxor_expr, do_parse!(
907 not!(syn!(OrOr)) >>
908 not!(syn!(OrEq)) >>
909 t: syn!(Or) >>
910 (BinOp::BitOr(t))
911 ));
912
913 binop!(bitxor_expr, bitand_expr, do_parse!(
917 not!(syn!(CaretEq)) >>
919 t: syn!(Caret) >>
920 (BinOp::BitXor(t))
921 ));
922
923 binop!(bitand_expr, shift_expr, do_parse!(
927 not!(syn!(AndAnd)) >>
929 not!(syn!(AndEq)) >>
930 t: syn!(And) >>
931 (BinOp::BitAnd(t))
932 ));
933
934 binop!(shift_expr, arith_expr, alt!(
939 syn!(Shl) => { BinOp::Shl }
940 |
941 syn!(Shr) => { BinOp::Shr }
942 ));
943
944 binop!(arith_expr, term_expr, alt!(
949 syn!(Add) => { BinOp::Add }
950 |
951 syn!(Sub) => { BinOp::Sub }
952 ));
953
954 binop!(term_expr, cast_expr, alt!(
960 syn!(Star) => { BinOp::Mul }
961 |
962 syn!(Div) => { BinOp::Div }
963 |
964 syn!(Rem) => { BinOp::Rem }
965 ));
966
967 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
972 mut e: call!(unary_expr, allow_struct, allow_block) >>
973 many0!(alt!(
974 do_parse!(
975 as_: syn!(As) >>
976 ty: call!(Ty::without_plus) >>
979 ({
980 e = ExprCast {
981 expr: Box::new(e.into()),
982 as_token: as_,
983 ty: Box::new(ty),
984 }.into();
985 })
986 )
987 |
988 do_parse!(
989 colon: syn!(Colon) >>
990 ty: call!(Ty::without_plus) >>
993 ({
994 e = ExprType {
995 expr: Box::new(e.into()),
996 colon_token: colon,
997 ty: Box::new(ty),
998 }.into();
999 })
1000 )
1001 )) >>
1002 (e)
1003 ));
1004
1005 #[cfg(feature = "full")]
1012 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1013 do_parse!(
1014 op: syn!(UnOp) >>
1015 expr: call!(unary_expr, allow_struct, true) >>
1016 (ExprUnary {
1017 op: op,
1018 expr: Box::new(expr.into()),
1019 }.into())
1020 )
1021 |
1022 do_parse!(
1023 and: syn!(And) >>
1024 mutability: syn!(Mutability) >>
1025 expr: call!(unary_expr, allow_struct, true) >>
1026 (ExprAddrOf {
1027 and_token: and,
1028 mutbl: mutability,
1029 expr: Box::new(expr.into()),
1030 }.into())
1031 )
1032 |
1033 do_parse!(
1034 box_: syn!(Box_) >>
1035 expr: call!(unary_expr, allow_struct, true) >>
1036 (ExprBox {
1037 box_token: box_,
1038 expr: Box::new(expr.into()),
1039 }.into())
1040 )
1041 |
1042 call!(trailer_expr, allow_struct, allow_block)
1043 ));
1044
1045 #[cfg(not(feature = "full"))]
1047 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1048 do_parse!(
1049 op: syn!(UnOp) >>
1050 expr: call!(unary_expr, allow_struct, true) >>
1051 (ExprUnary {
1052 op: op,
1053 expr: Box::new(expr.into()),
1054 }.into())
1055 )
1056 |
1057 call!(trailer_expr, allow_struct, allow_block)
1058 ));
1059
1060 #[cfg(feature = "full")]
1069 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1070 mut e: call!(atom_expr, allow_struct, allow_block) >>
1071 many0!(alt!(
1072 tap!(args: and_call => {
1073 let (args, paren) = args;
1074 e = ExprCall {
1075 func: Box::new(e.into()),
1076 args: args,
1077 paren_token: paren,
1078 }.into();
1079 })
1080 |
1081 tap!(more: and_method_call => {
1082 let mut call = more;
1083 call.expr = Box::new(e.into());
1084 e = call.into();
1085 })
1086 |
1087 tap!(field: and_field => {
1088 let (field, token) = field;
1089 e = ExprField {
1090 expr: Box::new(e.into()),
1091 field: field,
1092 dot_token: token,
1093 }.into();
1094 })
1095 |
1096 tap!(field: and_tup_field => {
1097 let (field, token) = field;
1098 e = ExprTupField {
1099 expr: Box::new(e.into()),
1100 field: field,
1101 dot_token: token,
1102 }.into();
1103 })
1104 |
1105 tap!(i: and_index => {
1106 let (i, token) = i;
1107 e = ExprIndex {
1108 expr: Box::new(e.into()),
1109 bracket_token: token,
1110 index: Box::new(i),
1111 }.into();
1112 })
1113 |
1114 tap!(question: syn!(Question) => {
1115 e = ExprTry {
1116 expr: Box::new(e.into()),
1117 question_token: question,
1118 }.into();
1119 })
1120 )) >>
1121 (e)
1122 ));
1123
1124 #[cfg(not(feature = "full"))]
1126 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1127 mut e: call!(atom_expr, allow_struct, allow_block) >>
1128 many0!(alt!(
1129 tap!(args: and_call => {
1130 let (args, paren) = args;
1131 e = ExprCall {
1132 func: Box::new(e.into()),
1133 args: args,
1134 paren_token: paren,
1135 }.into();
1136 })
1137 |
1138 tap!(i: and_index => {
1139 let (i, token) = i;
1140 e = ExprIndex {
1141 expr: Box::new(e.into()),
1142 bracket_token: token,
1143 index: Box::new(i),
1144 }.into();
1145 })
1146 )) >>
1147 (e)
1148 ));
1149
1150 #[cfg(feature = "full")]
1153 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1154 syn!(ExprGroup) => { ExprKind::Group } |
1156 syn!(Lit) => { ExprKind::Lit } |
1158 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1160 |
1161 syn!(ExprParen) => { ExprKind::Paren } |
1163 syn!(Mac) => { ExprKind::Mac } |
1165 call!(expr_break, allow_struct) |
1167 syn!(ExprContinue) => { ExprKind::Continue } |
1169 call!(expr_ret, allow_struct) |
1171 syn!(ExprInPlace) => { ExprKind::InPlace }
1173 |
1174 syn!(ExprArray) => { ExprKind::Array }
1175 |
1176 syn!(ExprTup) => { ExprKind::Tup }
1177 |
1178 syn!(ExprIf) => { ExprKind::If }
1179 |
1180 syn!(ExprIfLet) => { ExprKind::IfLet }
1181 |
1182 syn!(ExprWhile) => { ExprKind::While }
1183 |
1184 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1185 |
1186 syn!(ExprForLoop) => { ExprKind::ForLoop }
1187 |
1188 syn!(ExprLoop) => { ExprKind::Loop }
1189 |
1190 syn!(ExprMatch) => { ExprKind::Match }
1191 |
1192 syn!(ExprCatch) => { ExprKind::Catch }
1193 |
1194 syn!(ExprYield) => { ExprKind::Yield }
1195 |
1196 call!(expr_closure, allow_struct)
1197 |
1198 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1199 |
1200 call!(expr_range, allow_struct)
1202 |
1203 syn!(ExprPath) => { ExprKind::Path }
1204 |
1205 syn!(ExprRepeat) => { ExprKind::Repeat }
1206 ));
1207
1208 #[cfg(not(feature = "full"))]
1209 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1210 syn!(ExprGroup) => { ExprKind::Group } |
1212 syn!(Lit) => { ExprKind::Lit } |
1214 syn!(ExprParen) => { ExprKind::Paren } |
1216 syn!(Mac) => { ExprKind::Mac } |
1218 syn!(ExprPath) => { ExprKind::Path }
1219 ));
1220
1221
1222 #[cfg(feature = "full")]
1223 named!(expr_nosemi -> Expr, map!(alt!(
1224 syn!(ExprIf) => { ExprKind::If }
1225 |
1226 syn!(ExprIfLet) => { ExprKind::IfLet }
1227 |
1228 syn!(ExprWhile) => { ExprKind::While }
1229 |
1230 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1231 |
1232 syn!(ExprForLoop) => { ExprKind::ForLoop }
1233 |
1234 syn!(ExprLoop) => { ExprKind::Loop }
1235 |
1236 syn!(ExprMatch) => { ExprKind::Match }
1237 |
1238 syn!(ExprCatch) => { ExprKind::Catch }
1239 |
1240 syn!(ExprYield) => { ExprKind::Yield }
1241 |
1242 syn!(ExprBlock) => { ExprKind::Block }
1243 ), Expr::from));
1244
1245 impl Synom for ExprGroup {
1246 named!(parse -> Self, do_parse!(
1247 e: grouped!(syn!(Expr)) >>
1248 (ExprGroup {
1249 expr: Box::new(e.0),
1250 group_token: e.1,
1251 }.into())
1252 ));
1253 }
1254
1255 impl Synom for ExprParen {
1256 named!(parse -> Self, do_parse!(
1257 e: parens!(syn!(Expr)) >>
1258 (ExprParen {
1259 expr: Box::new(e.0),
1260 paren_token: e.1,
1261 }.into())
1262 ));
1263 }
1264
1265 #[cfg(feature = "full")]
1266 impl Synom for ExprInPlace {
1267 named!(parse -> Self, do_parse!(
1268 in_: syn!(In) >>
1269 place: expr_no_struct >>
1270 value: braces!(call!(Block::parse_within)) >>
1271 (ExprInPlace {
1272 place: Box::new(place),
1273 kind: InPlaceKind::In(in_),
1274 value: Box::new(Expr {
1275 node: ExprBlock {
1276 unsafety: Unsafety::Normal,
1277 block: Block {
1278 stmts: value.0,
1279 brace_token: value.1,
1280 },
1281 }.into(),
1282 attrs: Vec::new(),
1283 }),
1284 })
1285 ));
1286 }
1287
1288 #[cfg(feature = "full")]
1289 impl Synom for ExprArray {
1290 named!(parse -> Self, do_parse!(
1291 elems: brackets!(call!(Delimited::parse_terminated)) >>
1292 (ExprArray {
1293 exprs: elems.0,
1294 bracket_token: elems.1,
1295 })
1296 ));
1297 }
1298
1299 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1300 parens!(call!(Delimited::parse_terminated)));
1301
1302 #[cfg(feature = "full")]
1303 named!(and_method_call -> ExprMethodCall, do_parse!(
1304 dot: syn!(Dot) >>
1305 method: syn!(Ident) >>
1306 typarams: option!(do_parse!(
1307 colon2: syn!(Colon2) >>
1308 lt: syn!(Lt) >>
1309 tys: call!(Delimited::parse_terminated) >>
1310 gt: syn!(Gt) >>
1311 (colon2, lt, tys, gt)
1312 )) >>
1313 args: parens!(call!(Delimited::parse_terminated)) >>
1314 ({
1315 let (colon2, lt, tys, gt) = match typarams {
1316 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1317 None => (None, None, None, None),
1318 };
1319 ExprMethodCall {
1320 expr: Box::new(ExprKind::Lit(Lit {
1322 span: Span::default(),
1323 value: LitKind::Bool(false),
1324 }).into()),
1325
1326 method: method,
1327 args: args.0,
1328 paren_token: args.1,
1329 dot_token: dot,
1330 lt_token: lt,
1331 gt_token: gt,
1332 colon2_token: colon2,
1333 typarams: tys.unwrap_or_default(),
1334 }
1335 })
1336 ));
1337
1338 #[cfg(feature = "full")]
1339 impl Synom for ExprTup {
1340 named!(parse -> Self, do_parse!(
1341 elems: parens!(call!(Delimited::parse_terminated)) >>
1342 (ExprTup {
1343 args: elems.0,
1344 paren_token: elems.1,
1345 lone_comma: None, })
1347 ));
1348 }
1349
1350 #[cfg(feature = "full")]
1351 impl Synom for ExprIfLet {
1352 named!(parse -> Self, do_parse!(
1353 if_: syn!(If) >>
1354 let_: syn!(Let) >>
1355 pat: syn!(Pat) >>
1356 eq: syn!(Eq) >>
1357 cond: expr_no_struct >>
1358 then_block: braces!(call!(Block::parse_within)) >>
1359 else_block: option!(else_block) >>
1360 (ExprIfLet {
1361 pat: Box::new(pat),
1362 let_token: let_,
1363 eq_token: eq,
1364 expr: Box::new(cond),
1365 if_true: Block {
1366 stmts: then_block.0,
1367 brace_token: then_block.1,
1368 },
1369 if_token: if_,
1370 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1371 if_false: else_block.map(|p| Box::new(p.1.into())),
1372 })
1373 ));
1374 }
1375
1376 #[cfg(feature = "full")]
1377 impl Synom for ExprIf {
1378 named!(parse -> Self, do_parse!(
1379 if_: syn!(If) >>
1380 cond: expr_no_struct >>
1381 then_block: braces!(call!(Block::parse_within)) >>
1382 else_block: option!(else_block) >>
1383 (ExprIf {
1384 cond: Box::new(cond),
1385 if_true: Block {
1386 stmts: then_block.0,
1387 brace_token: then_block.1,
1388 },
1389 if_token: if_,
1390 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1391 if_false: else_block.map(|p| Box::new(p.1.into())),
1392 })
1393 ));
1394 }
1395
1396 #[cfg(feature = "full")]
1397 named!(else_block -> (Else, ExprKind), do_parse!(
1398 else_: syn!(Else) >>
1399 expr: alt!(
1400 syn!(ExprIf) => { ExprKind::If }
1401 |
1402 syn!(ExprIfLet) => { ExprKind::IfLet }
1403 |
1404 do_parse!(
1405 else_block: braces!(call!(Block::parse_within)) >>
1406 (ExprKind::Block(ExprBlock {
1407 unsafety: Unsafety::Normal,
1408 block: Block {
1409 stmts: else_block.0,
1410 brace_token: else_block.1,
1411 },
1412 }))
1413 )
1414 ) >>
1415 (else_, expr)
1416 ));
1417
1418
1419 #[cfg(feature = "full")]
1420 impl Synom for ExprForLoop {
1421 named!(parse -> Self, do_parse!(
1422 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
1423 for_: syn!(For) >>
1424 pat: syn!(Pat) >>
1425 in_: syn!(In) >>
1426 expr: expr_no_struct >>
1427 loop_block: syn!(Block) >>
1428 (ExprForLoop {
1429 for_token: for_,
1430 in_token: in_,
1431 pat: Box::new(pat),
1432 expr: Box::new(expr),
1433 body: loop_block,
1434 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1435 label: lbl.map(|p| p.0),
1436 })
1437 ));
1438 }
1439
1440 #[cfg(feature = "full")]
1441 impl Synom for ExprLoop {
1442 named!(parse -> Self, do_parse!(
1443 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
1444 loop_: syn!(Loop) >>
1445 loop_block: syn!(Block) >>
1446 (ExprLoop {
1447 loop_token: loop_,
1448 body: loop_block,
1449 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1450 label: lbl.map(|p| p.0),
1451 })
1452 ));
1453 }
1454
1455 #[cfg(feature = "full")]
1456 impl Synom for ExprMatch {
1457 named!(parse -> Self, do_parse!(
1458 match_: syn!(Match) >>
1459 obj: expr_no_struct >>
1460 res: braces!(many0!(syn!(Arm))) >>
1461 ({
1462 let (arms, brace) = res;
1463 ExprMatch {
1464 expr: Box::new(obj),
1465 match_token: match_,
1466 brace_token: brace,
1467 arms: arms,
1468 }
1469 })
1470 ));
1471 }
1472
1473 #[cfg(feature = "full")]
1474 impl Synom for ExprCatch {
1475 named!(parse -> Self, do_parse!(
1476 do_: syn!(Do) >>
1477 catch_: syn!(Catch) >>
1478 catch_block: syn!(Block) >>
1479 (ExprCatch {
1480 block: catch_block,
1481 do_token: do_,
1482 catch_token: catch_,
1483 }.into())
1484 ));
1485 }
1486
1487 #[cfg(feature = "full")]
1488 impl Synom for ExprYield {
1489 named!(parse -> Self, do_parse!(
1490 yield_: syn!(Yield) >>
1491 expr: option!(syn!(Expr)) >>
1492 (ExprYield {
1493 yield_token: yield_,
1494 expr: expr.map(Box::new),
1495 })
1496 ));
1497 }
1498
1499 #[cfg(feature = "full")]
1500 impl Synom for Arm {
1501 named!(parse -> Self, do_parse!(
1502 attrs: many0!(call!(Attribute::parse_outer)) >>
1503 pats: call!(Delimited::parse_separated_nonempty) >>
1504 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1505 rocket: syn!(Rocket) >>
1506 body: do_parse!(
1507 expr: alt!(expr_nosemi | syn!(Expr)) >>
1508 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1509 map!(input_end!(), |_| None)
1510 |
1511 map!(syn!(Comma), Some)
1512 )) >>
1513 comma2: cond!(!arm_expr_requires_comma(&expr), option!(syn!(Comma))) >>
1514 (expr, comma1.and_then(|x| x).or(comma2.and_then(|x| x)))
1515 ) >>
1516 (Arm {
1517 rocket_token: rocket,
1518 if_token: guard.as_ref().map(|p| If((p.0).0)),
1519 attrs: attrs,
1520 pats: pats,
1521 guard: guard.map(|p| Box::new(p.1)),
1522 body: Box::new(body.0),
1523 comma: body.1,
1524 })
1525 ));
1526 }
1527
1528 #[cfg(feature = "full")]
1529 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
1530 capture: syn!(CaptureBy) >>
1531 or1: syn!(Or) >>
1532 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1533 or2: syn!(Or) >>
1534 ret_and_body: alt!(
1535 do_parse!(
1536 arrow: syn!(RArrow) >>
1537 ty: syn!(Ty) >>
1538 body: syn!(Block) >>
1539 (FunctionRetTy::Ty(ty, arrow),
1540 ExprKind::Block(ExprBlock {
1541 unsafety: Unsafety::Normal,
1542 block: body,
1543 }).into())
1544 )
1545 |
1546 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
1547 ) >>
1548 (ExprClosure {
1549 capture: capture,
1550 or1_token: or1,
1551 or2_token: or2,
1552 decl: Box::new(FnDecl {
1553 inputs: inputs,
1554 output: ret_and_body.0,
1555 variadic: false,
1556 dot_tokens: None,
1557 fn_token: tokens::Fn_::default(),
1558 generics: Generics::default(),
1559 paren_token: tokens::Paren::default(),
1560 }),
1561 body: Box::new(ret_and_body.1),
1562 }.into())
1563 ));
1564
1565 #[cfg(feature = "full")]
1566 named!(fn_arg -> FnArg, do_parse!(
1567 pat: syn!(Pat) >>
1568 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1569 ({
1570 let (colon, ty) = ty.unwrap_or_else(|| {
1571 (Colon::default(), TyInfer {
1572 underscore_token: Underscore::default(),
1573 }.into())
1574 });
1575 ArgCaptured {
1576 pat: pat,
1577 colon_token: colon,
1578 ty: ty,
1579 }.into()
1580 })
1581 ));
1582
1583 #[cfg(feature = "full")]
1584 impl Synom for ExprWhile {
1585 named!(parse -> Self, do_parse!(
1586 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
1587 while_: syn!(While) >>
1588 cond: expr_no_struct >>
1589 while_block: syn!(Block) >>
1590 (ExprWhile {
1591 while_token: while_,
1592 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1593 cond: Box::new(cond),
1594 body: while_block,
1595 label: lbl.map(|p| p.0),
1596 })
1597 ));
1598 }
1599
1600 #[cfg(feature = "full")]
1601 impl Synom for ExprWhileLet {
1602 named!(parse -> Self, do_parse!(
1603 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
1604 while_: syn!(While) >>
1605 let_: syn!(Let) >>
1606 pat: syn!(Pat) >>
1607 eq: syn!(Eq) >>
1608 value: expr_no_struct >>
1609 while_block: syn!(Block) >>
1610 (ExprWhileLet {
1611 eq_token: eq,
1612 let_token: let_,
1613 while_token: while_,
1614 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1615 pat: Box::new(pat),
1616 expr: Box::new(value),
1617 body: while_block,
1618 label: lbl.map(|p| p.0),
1619 })
1620 ));
1621 }
1622
1623 #[cfg(feature = "full")]
1624 impl Synom for ExprContinue {
1625 named!(parse -> Self, do_parse!(
1626 cont: syn!(Continue) >>
1627 lbl: option!(syn!(Lifetime)) >>
1628 (ExprContinue {
1629 continue_token: cont,
1630 label: lbl,
1631 })
1632 ));
1633 }
1634
1635 #[cfg(feature = "full")]
1636 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
1637 break_: syn!(Break) >>
1638 lbl: option!(syn!(Lifetime)) >>
1639 val: opt_ambiguous_expr!(allow_struct) >>
1642 (ExprBreak {
1643 label: lbl,
1644 expr: val.map(Box::new),
1645 break_token: break_,
1646 }.into())
1647 ));
1648
1649 #[cfg(feature = "full")]
1650 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
1651 return_: syn!(Return) >>
1652 ret_value: option!(ambiguous_expr!(allow_struct)) >>
1658 (ExprRet {
1659 expr: ret_value.map(Box::new),
1660 return_token: return_,
1661 }.into())
1662 ));
1663
1664 #[cfg(feature = "full")]
1665 impl Synom for ExprStruct {
1666 named!(parse -> Self, do_parse!(
1667 path: syn!(Path) >>
1668 data: braces!(do_parse!(
1669 fields: call!(Delimited::parse_terminated) >>
1670 base: option!(
1671 cond!(fields.is_empty() || fields.trailing_delim(),
1672 do_parse!(
1673 dots: syn!(Dot2) >>
1674 base: syn!(Expr) >>
1675 (dots, base)
1676 )
1677 )
1678 ) >>
1679 (fields, base)
1680 )) >>
1681 ({
1682 let ((fields, base), brace) = data;
1683 let (dots, rest) = match base.and_then(|b| b) {
1684 Some((dots, base)) => (Some(dots), Some(base)),
1685 None => (None, None),
1686 };
1687 ExprStruct {
1688 brace_token: brace,
1689 path: path,
1690 fields: fields,
1691 dot2_token: dots,
1692 rest: rest.map(Box::new),
1693 }
1694 })
1695 ));
1696 }
1697
1698 #[cfg(feature = "full")]
1699 impl Synom for FieldValue {
1700 named!(parse -> Self, alt!(
1701 do_parse!(
1702 ident: field_ident >>
1703 colon: syn!(Colon) >>
1704 value: syn!(Expr) >>
1705 (FieldValue {
1706 ident: ident,
1707 expr: value,
1708 is_shorthand: false,
1709 attrs: Vec::new(),
1710 colon_token: Some(colon),
1711 })
1712 )
1713 |
1714 map!(syn!(Ident), |name| FieldValue {
1715 ident: name.clone(),
1716 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1717 is_shorthand: true,
1718 attrs: Vec::new(),
1719 colon_token: None,
1720 })
1721 ));
1722 }
1723
1724 #[cfg(feature = "full")]
1725 impl Synom for ExprRepeat {
1726 named!(parse -> Self, do_parse!(
1727 data: brackets!(do_parse!(
1728 value: syn!(Expr) >>
1729 semi: syn!(Semi) >>
1730 times: syn!(Expr) >>
1731 (value, semi, times)
1732 )) >>
1733 (ExprRepeat {
1734 expr: Box::new((data.0).0),
1735 amt: Box::new((data.0).2),
1736 bracket_token: data.1,
1737 semi_token: (data.0).1,
1738 })
1739 ));
1740 }
1741
1742 #[cfg(feature = "full")]
1743 impl Synom for ExprBlock {
1744 named!(parse -> Self, do_parse!(
1745 rules: syn!(Unsafety) >>
1746 b: syn!(Block) >>
1747 (ExprBlock {
1748 unsafety: rules,
1749 block: b,
1750 })
1751 ));
1752 }
1753
1754 #[cfg(feature = "full")]
1755 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
1756 limits: syn!(RangeLimits) >>
1757 hi: opt_ambiguous_expr!(allow_struct) >>
1758 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
1759 ));
1760
1761 #[cfg(feature = "full")]
1762 impl Synom for RangeLimits {
1763 named!(parse -> Self, alt!(
1764 syn!(Dot3) => { RangeLimits::Closed }
1766 |
1767 syn!(Dot2) => { RangeLimits::HalfOpen }
1768 ));
1769 }
1770
1771 impl Synom for ExprPath {
1772 named!(parse -> Self, do_parse!(
1773 pair: qpath >>
1774 (ExprPath {
1775 qself: pair.0,
1776 path: pair.1,
1777 })
1778 ));
1779 }
1780
1781 #[cfg(feature = "full")]
1782 named!(and_field -> (Ident, Dot),
1783 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
1784
1785 #[cfg(feature = "full")]
1786 named!(and_tup_field -> (Lit, Dot),
1787 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
1788
1789 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
1790
1791 #[cfg(feature = "full")]
1792 impl Synom for Block {
1793 named!(parse -> Self, do_parse!(
1794 stmts: braces!(call!(Block::parse_within)) >>
1795 (Block {
1796 stmts: stmts.0,
1797 brace_token: stmts.1,
1798 })
1799 ));
1800 }
1801
1802 #[cfg(feature = "full")]
1803 impl Block {
1804 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1805 many0!(syn!(Semi)) >>
1806 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1807 last: option!(do_parse!(
1808 attrs: many0!(call!(Attribute::parse_outer)) >>
1809 mut e: syn!(Expr) >>
1810 ({
1811 e.attrs = attrs;
1812 Stmt::Expr(Box::new(e))
1813 })
1814 )) >>
1815 (match last {
1816 None => standalone,
1817 Some(last) => {
1818 standalone.push(last);
1819 standalone
1820 }
1821 })
1822 ));
1823 }
1824
1825 #[cfg(feature = "full")]
1826 impl Synom for Stmt {
1827 named!(parse -> Self, alt!(
1828 stmt_mac
1829 |
1830 stmt_local
1831 |
1832 stmt_item
1833 |
1834 stmt_blockexpr
1835 |
1836 stmt_expr
1837 ));
1838 }
1839
1840 #[cfg(feature = "full")]
1841 named!(stmt_mac -> Stmt, do_parse!(
1842 attrs: many0!(call!(Attribute::parse_outer)) >>
1843 what: syn!(Path) >>
1844 bang: syn!(Bang) >>
1845 data: braces!(syn!(TokenStream)) >>
1848 semi: option!(syn!(Semi)) >>
1849 (Stmt::Mac(Box::new((
1850 Mac {
1851 path: what,
1852 bang_token: bang,
1853 ident: None,
1854 tokens: vec![TokenTree(proc_macro2::TokenTree {
1855 span: ((data.1).0).0,
1856 kind: TokenNode::Group(Delimiter::Brace, data.0),
1857 })],
1858 },
1859 match semi {
1860 Some(semi) => MacStmtStyle::Semicolon(semi),
1861 None => MacStmtStyle::Braces,
1862 },
1863 attrs,
1864 ))))
1865 ));
1866
1867 #[cfg(feature = "full")]
1868 named!(stmt_local -> Stmt, do_parse!(
1869 attrs: many0!(call!(Attribute::parse_outer)) >>
1870 let_: syn!(Let) >>
1871 pat: syn!(Pat) >>
1872 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1873 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1874 semi: syn!(Semi) >>
1875 (Stmt::Local(Box::new(Local {
1876 let_token: let_,
1877 semi_token: semi,
1878 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1879 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
1880 pat: Box::new(pat),
1881 ty: ty.map(|p| Box::new(p.1)),
1882 init: init.map(|p| Box::new(p.1)),
1883 attrs: attrs,
1884 })))
1885 ));
1886
1887 #[cfg(feature = "full")]
1888 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
1889
1890 #[cfg(feature = "full")]
1891 named!(stmt_blockexpr -> Stmt, do_parse!(
1892 attrs: many0!(call!(Attribute::parse_outer)) >>
1893 mut e: expr_nosemi >>
1894 not!(syn!(Dot)) >>
1897 not!(syn!(Question)) >>
1898 semi: option!(syn!(Semi)) >>
1899 ({
1900 e.attrs = attrs;
1901 if let Some(semi) = semi {
1902 Stmt::Semi(Box::new(e), semi)
1903 } else {
1904 Stmt::Expr(Box::new(e))
1905 }
1906 })
1907 ));
1908
1909 #[cfg(feature = "full")]
1910 named!(stmt_expr -> Stmt, do_parse!(
1911 attrs: many0!(call!(Attribute::parse_outer)) >>
1912 mut e: syn!(Expr) >>
1913 semi: syn!(Semi) >>
1914 ({
1915 e.attrs = attrs;
1916 Stmt::Semi(Box::new(e), semi)
1917 })
1918 ));
1919
1920 #[cfg(feature = "full")]
1921 impl Synom for Pat {
1922 named!(parse -> Self, alt!(
1923 syn!(PatWild) => { Pat::Wild } |
1925 syn!(PatBox) => { Pat::Box } |
1927 syn!(PatRange) => { Pat::Range } |
1929 syn!(PatTupleStruct) => { Pat::TupleStruct } |
1931 syn!(PatStruct) => { Pat::Struct } |
1933 syn!(Mac) => { Pat::Mac } |
1935 syn!(PatLit) => { Pat::Lit } |
1937 syn!(PatIdent) => { Pat::Ident } |
1939 syn!(PatPath) => { Pat::Path }
1940 |
1941 syn!(PatTuple) => { Pat::Tuple }
1942 |
1943 syn!(PatRef) => { Pat::Ref }
1944 |
1945 syn!(PatSlice) => { Pat::Slice }
1946 ));
1947 }
1948
1949 #[cfg(feature = "full")]
1950 impl Synom for PatWild {
1951 named!(parse -> Self, map!(
1952 syn!(Underscore),
1953 |u| PatWild { underscore_token: u }
1954 ));
1955 }
1956
1957 #[cfg(feature = "full")]
1958 impl Synom for PatBox {
1959 named!(parse -> Self, do_parse!(
1960 boxed: syn!(Box_) >>
1961 pat: syn!(Pat) >>
1962 (PatBox {
1963 pat: Box::new(pat),
1964 box_token: boxed,
1965 })
1966 ));
1967 }
1968
1969 #[cfg(feature = "full")]
1970 impl Synom for PatIdent {
1971 named!(parse -> Self, do_parse!(
1972 mode: option!(syn!(Ref)) >>
1973 mutability: syn!(Mutability) >>
1974 name: alt!(
1975 syn!(Ident)
1976 |
1977 syn!(Self_) => { Into::into }
1978 ) >>
1979 not!(syn!(Lt)) >>
1980 not!(syn!(Colon2)) >>
1981 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1982 (PatIdent {
1983 mode: match mode {
1984 Some(mode) => BindingMode::ByRef(mode, mutability),
1985 None => BindingMode::ByValue(mutability),
1986 },
1987 ident: name,
1988 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1989 subpat: subpat.map(|p| Box::new(p.1)),
1990 })
1991 ));
1992 }
1993
1994 #[cfg(feature = "full")]
1995 impl Synom for PatTupleStruct {
1996 named!(parse -> Self, do_parse!(
1997 path: syn!(Path) >>
1998 tuple: syn!(PatTuple) >>
1999 (PatTupleStruct {
2000 path: path,
2001 pat: tuple,
2002 })
2003 ));
2004 }
2005
2006 #[cfg(feature = "full")]
2007 impl Synom for PatStruct {
2008 named!(parse -> Self, do_parse!(
2009 path: syn!(Path) >>
2010 data: braces!(do_parse!(
2011 fields: call!(Delimited::parse_terminated) >>
2012 base: option!(
2013 cond!(fields.is_empty() || fields.trailing_delim(),
2014 syn!(Dot2))
2015 ) >>
2016 (fields, base)
2017 )) >>
2018 (PatStruct {
2019 path: path,
2020 fields: (data.0).0,
2021 brace_token: data.1,
2022 dot2_token: (data.0).1.and_then(|m| m),
2023 })
2024 ));
2025 }
2026
2027 #[cfg(feature = "full")]
2028 impl Synom for FieldPat {
2029 named!(parse -> Self, alt!(
2030 do_parse!(
2031 ident: field_ident >>
2032 colon: syn!(Colon) >>
2033 pat: syn!(Pat) >>
2034 (FieldPat {
2035 ident: ident,
2036 pat: Box::new(pat),
2037 is_shorthand: false,
2038 attrs: Vec::new(),
2039 colon_token: Some(colon),
2040 })
2041 )
2042 |
2043 do_parse!(
2044 boxed: option!(syn!(Box_)) >>
2045 mode: option!(syn!(Ref)) >>
2046 mutability: syn!(Mutability) >>
2047 ident: syn!(Ident) >>
2048 ({
2049 let mut pat: Pat = PatIdent {
2050 mode: if let Some(mode) = mode {
2051 BindingMode::ByRef(mode, mutability)
2052 } else {
2053 BindingMode::ByValue(mutability)
2054 },
2055 ident: ident.clone(),
2056 subpat: None,
2057 at_token: None,
2058 }.into();
2059 if let Some(boxed) = boxed {
2060 pat = PatBox {
2061 pat: Box::new(pat),
2062 box_token: boxed,
2063 }.into();
2064 }
2065 FieldPat {
2066 ident: ident,
2067 pat: Box::new(pat),
2068 is_shorthand: true,
2069 attrs: Vec::new(),
2070 colon_token: None,
2071 }
2072 })
2073 )
2074 ));
2075 }
2076
2077 #[cfg(feature = "full")]
2078 named!(field_ident -> Ident, alt!(
2079 syn!(Ident)
2080 |
2081 do_parse!(
2082 lit: syn!(Lit) >>
2083 ({
2084 let s = lit.to_string();
2085 if s.parse::<usize>().is_ok() {
2086 Ident::new(Term::intern(&s), lit.span)
2087 } else {
2088 return parse_error();
2089 }
2090 })
2091 )
2092 ));
2093
2094 #[cfg(feature = "full")]
2095 impl Synom for PatPath {
2096 named!(parse -> Self, map!(
2097 syn!(ExprPath),
2098 |p| PatPath { qself: p.qself, path: p.path }
2099 ));
2100 }
2101
2102 #[cfg(feature = "full")]
2103 impl Synom for PatTuple {
2104 named!(parse -> Self, do_parse!(
2105 data: parens!(do_parse!(
2106 elems: call!(Delimited::parse_terminated) >>
2107 dotdot: map!(cond!(
2108 elems.is_empty() || elems.trailing_delim(),
2109 option!(do_parse!(
2110 dots: syn!(Dot2) >>
2111 trailing: option!(syn!(Comma)) >>
2112 (dots, trailing)
2113 ))
2114 ), |x| x.and_then(|x| x)) >>
2115 rest: cond!(match dotdot {
2116 Some((_, Some(_))) => true,
2117 _ => false,
2118 },
2119 call!(Delimited::parse_terminated)) >>
2120 (elems, dotdot, rest)
2121 )) >>
2122 ({
2123 let ((mut elems, dotdot, rest), parens) = data;
2124 let (dotdot, trailing) = match dotdot {
2125 Some((a, b)) => (Some(a), Some(b)),
2126 None => (None, None),
2127 };
2128 PatTuple {
2129 paren_token: parens,
2130 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2131 dot2_token: dotdot,
2132 comma_token: trailing.and_then(|b| b),
2133 pats: {
2134 if let Some(rest) = rest {
2135 for elem in rest {
2136 elems.push(elem);
2137 }
2138 }
2139 elems
2140 },
2141 }
2142 })
2143 ));
2144 }
2145
2146 #[cfg(feature = "full")]
2147 impl Synom for PatRef {
2148 named!(parse -> Self, do_parse!(
2149 and: syn!(And) >>
2150 mutability: syn!(Mutability) >>
2151 pat: syn!(Pat) >>
2152 (PatRef {
2153 pat: Box::new(pat),
2154 mutbl: mutability,
2155 and_token: and,
2156 })
2157 ));
2158 }
2159
2160 #[cfg(feature = "full")]
2161 impl Synom for PatLit {
2162 named!(parse -> Self, do_parse!(
2163 lit: pat_lit_expr >>
2164 (if let ExprKind::Path(_) = lit.node {
2165 return parse_error(); } else {
2167 PatLit {
2168 expr: Box::new(lit),
2169 }
2170 })
2171 ));
2172 }
2173
2174 #[cfg(feature = "full")]
2175 impl Synom for PatRange {
2176 named!(parse -> Self, do_parse!(
2177 lo: pat_lit_expr >>
2178 limits: syn!(RangeLimits) >>
2179 hi: pat_lit_expr >>
2180 (PatRange {
2181 lo: Box::new(lo),
2182 hi: Box::new(hi),
2183 limits: limits,
2184 })
2185 ));
2186 }
2187
2188 #[cfg(feature = "full")]
2189 named!(pat_lit_expr -> Expr, do_parse!(
2190 neg: option!(syn!(Sub)) >>
2191 v: alt!(
2192 syn!(Lit) => { ExprKind::Lit }
2193 |
2194 syn!(ExprPath) => { ExprKind::Path }
2195 ) >>
2196 (if neg.is_some() {
2197 ExprKind::Unary(ExprUnary {
2198 op: UnOp::Neg(tokens::Sub::default()),
2199 expr: Box::new(v.into())
2200 }).into()
2201 } else {
2202 v.into()
2203 })
2204 ));
2205
2206 #[cfg(feature = "full")]
2207 impl Synom for PatSlice {
2208 named!(parse -> Self, map!(
2209 brackets!(do_parse!(
2210 before: call!(Delimited::parse_terminated) >>
2211 middle: option!(do_parse!(
2212 dots: syn!(Dot2) >>
2213 trailing: option!(syn!(Comma)) >>
2214 (dots, trailing)
2215 )) >>
2216 after: cond!(
2217 match middle {
2218 Some((_, ref trailing)) => trailing.is_some(),
2219 _ => false,
2220 },
2221 call!(Delimited::parse_terminated)
2222 ) >>
2223 (before, middle, after)
2224 )),
2225 |((before, middle, after), brackets)| {
2226 let mut before: Delimited<Pat, tokens::Comma> = before;
2227 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2228 let middle: Option<(Dot2, Option<Comma>)> = middle;
2229 PatSlice {
2230 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2231 comma_token: middle.as_ref().and_then(|m| {
2232 m.1.as_ref().map(|m| Comma(m.0))
2233 }),
2234 bracket_token: brackets,
2235 middle: middle.and_then(|_| {
2236 if !before.is_empty() && !before.trailing_delim() {
2237 Some(Box::new(before.pop().unwrap().into_item()))
2238 } else {
2239 None
2240 }
2241 }),
2242 front: before,
2243 back: after.unwrap_or_default(),
2244 }
2245 }
2246 ));
2247 }
2248
2249 #[cfg(feature = "full")]
2250 impl Synom for CaptureBy {
2251 named!(parse -> Self, alt!(
2252 syn!(Move) => { CaptureBy::Value }
2253 |
2254 epsilon!() => { |_| CaptureBy::Ref }
2255 ));
2256 }
2257}
2258
2259#[cfg(feature = "printing")]
2260mod printing {
2261 use super::*;
2262 #[cfg(feature = "full")]
2263 use attr::FilterAttrs;
2264 use quote::{Tokens, ToTokens};
2265
2266 #[cfg(feature = "full")]
2269 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2270 if let ExprKind::Struct(_) = e.node {
2271 tokens::Paren::default().surround(tokens, |tokens| {
2272 e.to_tokens(tokens);
2273 });
2274 } else {
2275 e.to_tokens(tokens);
2276 }
2277 }
2278
2279 impl ToTokens for Expr {
2280 #[cfg(feature = "full")]
2281 fn to_tokens(&self, tokens: &mut Tokens) {
2282 tokens.append_all(self.attrs.outer());
2283 self.node.to_tokens(tokens)
2284 }
2285
2286 #[cfg(not(feature = "full"))]
2287 fn to_tokens(&self, tokens: &mut Tokens) {
2288 self.node.to_tokens(tokens)
2289 }
2290 }
2291
2292 #[cfg(feature = "full")]
2293 impl ToTokens for ExprBox {
2294 fn to_tokens(&self, tokens: &mut Tokens) {
2295 self.box_token.to_tokens(tokens);
2296 self.expr.to_tokens(tokens);
2297 }
2298 }
2299
2300 #[cfg(feature = "full")]
2301 impl ToTokens for ExprInPlace {
2302 fn to_tokens(&self, tokens: &mut Tokens) {
2303 match self.kind {
2304 InPlaceKind::Arrow(ref arrow) => {
2305 self.place.to_tokens(tokens);
2306 arrow.to_tokens(tokens);
2307 self.value.to_tokens(tokens);
2308 }
2309 InPlaceKind::In(ref _in) => {
2310 _in.to_tokens(tokens);
2311 self.place.to_tokens(tokens);
2312 if let ExprKind::Block(_) = self.value.node {
2315 self.value.to_tokens(tokens);
2316 } else {
2317 tokens::Brace::default().surround(tokens, |tokens| {
2318 self.value.to_tokens(tokens);
2319 })
2320 }
2321 }
2322 }
2323 }
2324 }
2325
2326 #[cfg(feature = "full")]
2327 impl ToTokens for ExprArray {
2328 fn to_tokens(&self, tokens: &mut Tokens) {
2329 self.bracket_token.surround(tokens, |tokens| {
2330 self.exprs.to_tokens(tokens);
2331 })
2332 }
2333 }
2334
2335 impl ToTokens for ExprCall {
2336 fn to_tokens(&self, tokens: &mut Tokens) {
2337 self.func.to_tokens(tokens);
2338 self.paren_token.surround(tokens, |tokens| {
2339 self.args.to_tokens(tokens);
2340 })
2341 }
2342 }
2343
2344 #[cfg(feature = "full")]
2345 impl ToTokens for ExprMethodCall {
2346 fn to_tokens(&self, tokens: &mut Tokens) {
2347 self.expr.to_tokens(tokens);
2348 self.dot_token.to_tokens(tokens);
2349 self.method.to_tokens(tokens);
2350 if !self.typarams.is_empty() {
2351 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2352 TokensOrDefault(&self.lt_token).to_tokens(tokens);
2353 self.typarams.to_tokens(tokens);
2354 TokensOrDefault(&self.gt_token).to_tokens(tokens);
2355 }
2356 self.paren_token.surround(tokens, |tokens| {
2357 self.args.to_tokens(tokens);
2358 });
2359 }
2360 }
2361
2362 #[cfg(feature = "full")]
2363 impl ToTokens for ExprTup {
2364 fn to_tokens(&self, tokens: &mut Tokens) {
2365 self.paren_token.surround(tokens, |tokens| {
2366 self.args.to_tokens(tokens);
2367 if self.args.len() == 1 && !self.args.trailing_delim() {
2370 tokens::Comma::default().to_tokens(tokens);
2371 }
2372 self.lone_comma.to_tokens(tokens);
2377 })
2378 }
2379 }
2380
2381 impl ToTokens for ExprBinary {
2382 fn to_tokens(&self, tokens: &mut Tokens) {
2383 self.left.to_tokens(tokens);
2384 self.op.to_tokens(tokens);
2385 self.right.to_tokens(tokens);
2386 }
2387 }
2388
2389 impl ToTokens for ExprUnary {
2390 fn to_tokens(&self, tokens: &mut Tokens) {
2391 self.op.to_tokens(tokens);
2392 self.expr.to_tokens(tokens);
2393 }
2394 }
2395
2396 impl ToTokens for ExprCast {
2397 fn to_tokens(&self, tokens: &mut Tokens) {
2398 self.expr.to_tokens(tokens);
2399 self.as_token.to_tokens(tokens);
2400 self.ty.to_tokens(tokens);
2401 }
2402 }
2403
2404 impl ToTokens for ExprType {
2405 fn to_tokens(&self, tokens: &mut Tokens) {
2406 self.expr.to_tokens(tokens);
2407 self.colon_token.to_tokens(tokens);
2408 self.ty.to_tokens(tokens);
2409 }
2410 }
2411
2412 #[cfg(feature = "full")]
2413 fn maybe_wrap_else(tokens: &mut Tokens,
2414 else_token: &Option<tokens::Else>,
2415 if_false: &Option<Box<Expr>>)
2416 {
2417 if let Some(ref if_false) = *if_false {
2418 TokensOrDefault(&else_token).to_tokens(tokens);
2419
2420 match if_false.node {
2423 ExprKind::If(_) |
2424 ExprKind::IfLet(_) |
2425 ExprKind::Block(_) => {
2426 if_false.to_tokens(tokens);
2427 }
2428 _ => {
2429 tokens::Brace::default().surround(tokens, |tokens| {
2430 if_false.to_tokens(tokens);
2431 });
2432 }
2433 }
2434 }
2435 }
2436
2437 #[cfg(feature = "full")]
2438 impl ToTokens for ExprIf {
2439 fn to_tokens(&self, tokens: &mut Tokens) {
2440 self.if_token.to_tokens(tokens);
2441 wrap_bare_struct(tokens, &self.cond);
2442 self.if_true.to_tokens(tokens);
2443 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
2444 }
2445 }
2446
2447 #[cfg(feature = "full")]
2448 impl ToTokens for ExprIfLet {
2449 fn to_tokens(&self, tokens: &mut Tokens) {
2450 self.if_token.to_tokens(tokens);
2451 self.let_token.to_tokens(tokens);
2452 self.pat.to_tokens(tokens);
2453 self.eq_token.to_tokens(tokens);
2454 wrap_bare_struct(tokens, &self.expr);
2455 self.if_true.to_tokens(tokens);
2456 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
2457 }
2458 }
2459
2460 #[cfg(feature = "full")]
2461 impl ToTokens for ExprWhile {
2462 fn to_tokens(&self, tokens: &mut Tokens) {
2463 if self.label.is_some() {
2464 self.label.to_tokens(tokens);
2465 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2466 }
2467 self.while_token.to_tokens(tokens);
2468 wrap_bare_struct(tokens, &self.cond);
2469 self.body.to_tokens(tokens);
2470 }
2471 }
2472
2473 #[cfg(feature = "full")]
2474 impl ToTokens for ExprWhileLet {
2475 fn to_tokens(&self, tokens: &mut Tokens) {
2476 if self.label.is_some() {
2477 self.label.to_tokens(tokens);
2478 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2479 }
2480 self.while_token.to_tokens(tokens);
2481 self.let_token.to_tokens(tokens);
2482 self.pat.to_tokens(tokens);
2483 self.eq_token.to_tokens(tokens);
2484 wrap_bare_struct(tokens, &self.expr);
2485 self.body.to_tokens(tokens);
2486 }
2487 }
2488
2489 #[cfg(feature = "full")]
2490 impl ToTokens for ExprForLoop {
2491 fn to_tokens(&self, tokens: &mut Tokens) {
2492 if self.label.is_some() {
2493 self.label.to_tokens(tokens);
2494 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2495 }
2496 self.for_token.to_tokens(tokens);
2497 self.pat.to_tokens(tokens);
2498 self.in_token.to_tokens(tokens);
2499 wrap_bare_struct(tokens, &self.expr);
2500 self.body.to_tokens(tokens);
2501 }
2502 }
2503
2504 #[cfg(feature = "full")]
2505 impl ToTokens for ExprLoop {
2506 fn to_tokens(&self, tokens: &mut Tokens) {
2507 if self.label.is_some() {
2508 self.label.to_tokens(tokens);
2509 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2510 }
2511 self.loop_token.to_tokens(tokens);
2512 self.body.to_tokens(tokens);
2513 }
2514 }
2515
2516 #[cfg(feature = "full")]
2517 impl ToTokens for ExprMatch {
2518 fn to_tokens(&self, tokens: &mut Tokens) {
2519 self.match_token.to_tokens(tokens);
2520 wrap_bare_struct(tokens, &self.expr);
2521 self.brace_token.surround(tokens, |tokens| {
2522 for (i, arm) in self.arms.iter().enumerate() {
2523 arm.to_tokens(tokens);
2524 let is_last = i == self.arms.len() - 1;
2527 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
2528 tokens::Comma::default().to_tokens(tokens);
2529 }
2530 }
2531 });
2532 }
2533 }
2534
2535 #[cfg(feature = "full")]
2536 impl ToTokens for ExprCatch {
2537 fn to_tokens(&self, tokens: &mut Tokens) {
2538 self.do_token.to_tokens(tokens);
2539 self.catch_token.to_tokens(tokens);
2540 self.block.to_tokens(tokens);
2541 }
2542 }
2543
2544 #[cfg(feature = "full")]
2545 impl ToTokens for ExprYield {
2546 fn to_tokens(&self, tokens: &mut Tokens) {
2547 self.yield_token.to_tokens(tokens);
2548 self.expr.to_tokens(tokens);
2549 }
2550 }
2551
2552 #[cfg(feature = "full")]
2553 impl ToTokens for ExprClosure {
2554 fn to_tokens(&self, tokens: &mut Tokens) {
2555 self.capture.to_tokens(tokens);
2556 self.or1_token.to_tokens(tokens);
2557 for item in self.decl.inputs.iter() {
2558 match **item.item() {
2559 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
2560 pat.to_tokens(tokens);
2561 }
2562 _ => item.item().to_tokens(tokens),
2563 }
2564 item.delimiter().to_tokens(tokens);
2565 }
2566 self.or2_token.to_tokens(tokens);
2567 self.decl.output.to_tokens(tokens);
2568 self.body.to_tokens(tokens);
2569 }
2570 }
2571
2572 #[cfg(feature = "full")]
2573 impl ToTokens for ExprBlock {
2574 fn to_tokens(&self, tokens: &mut Tokens) {
2575 self.unsafety.to_tokens(tokens);
2576 self.block.to_tokens(tokens);
2577 }
2578 }
2579
2580 #[cfg(feature = "full")]
2581 impl ToTokens for ExprAssign {
2582 fn to_tokens(&self, tokens: &mut Tokens) {
2583 self.left.to_tokens(tokens);
2584 self.eq_token.to_tokens(tokens);
2585 self.right.to_tokens(tokens);
2586 }
2587 }
2588
2589 #[cfg(feature = "full")]
2590 impl ToTokens for ExprAssignOp {
2591 fn to_tokens(&self, tokens: &mut Tokens) {
2592 self.left.to_tokens(tokens);
2593 self.op.to_tokens(tokens);
2594 self.right.to_tokens(tokens);
2595 }
2596 }
2597
2598 #[cfg(feature = "full")]
2599 impl ToTokens for ExprField {
2600 fn to_tokens(&self, tokens: &mut Tokens) {
2601 self.expr.to_tokens(tokens);
2602 self.dot_token.to_tokens(tokens);
2603 self.field.to_tokens(tokens);
2606 }
2607 }
2608
2609 #[cfg(feature = "full")]
2610 impl ToTokens for ExprTupField {
2611 fn to_tokens(&self, tokens: &mut Tokens) {
2612 self.expr.to_tokens(tokens);
2613 self.dot_token.to_tokens(tokens);
2614 self.field.to_tokens(tokens);
2615 }
2616 }
2617
2618 impl ToTokens for ExprIndex {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
2620 self.expr.to_tokens(tokens);
2621 self.bracket_token.surround(tokens, |tokens| {
2622 self.index.to_tokens(tokens);
2623 });
2624 }
2625 }
2626
2627 #[cfg(feature = "full")]
2628 impl ToTokens for ExprRange {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
2630 self.from.to_tokens(tokens);
2631 self.limits.to_tokens(tokens);
2632 self.to.to_tokens(tokens);
2633 }
2634 }
2635
2636 impl ToTokens for ExprPath {
2637 fn to_tokens(&self, tokens: &mut Tokens) {
2638 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
2639 }
2640 }
2641
2642 #[cfg(feature = "full")]
2643 impl ToTokens for ExprAddrOf {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
2645 self.and_token.to_tokens(tokens);
2646 self.mutbl.to_tokens(tokens);
2647 self.expr.to_tokens(tokens);
2648 }
2649 }
2650
2651 #[cfg(feature = "full")]
2652 impl ToTokens for ExprBreak {
2653 fn to_tokens(&self, tokens: &mut Tokens) {
2654 self.break_token.to_tokens(tokens);
2655 self.label.to_tokens(tokens);
2656 self.expr.to_tokens(tokens);
2657 }
2658 }
2659
2660 #[cfg(feature = "full")]
2661 impl ToTokens for ExprContinue {
2662 fn to_tokens(&self, tokens: &mut Tokens) {
2663 self.continue_token.to_tokens(tokens);
2664 self.label.to_tokens(tokens);
2665 }
2666 }
2667
2668 #[cfg(feature = "full")]
2669 impl ToTokens for ExprRet {
2670 fn to_tokens(&self, tokens: &mut Tokens) {
2671 self.return_token.to_tokens(tokens);
2672 self.expr.to_tokens(tokens);
2673 }
2674 }
2675
2676 #[cfg(feature = "full")]
2677 impl ToTokens for ExprStruct {
2678 fn to_tokens(&self, tokens: &mut Tokens) {
2679 self.path.to_tokens(tokens);
2680 self.brace_token.surround(tokens, |tokens| {
2681 self.fields.to_tokens(tokens);
2682 if self.rest.is_some() {
2683 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2684 self.rest.to_tokens(tokens);
2685 }
2686 })
2687 }
2688 }
2689
2690 #[cfg(feature = "full")]
2691 impl ToTokens for ExprRepeat {
2692 fn to_tokens(&self, tokens: &mut Tokens) {
2693 self.bracket_token.surround(tokens, |tokens| {
2694 self.expr.to_tokens(tokens);
2695 self.semi_token.to_tokens(tokens);
2696 self.amt.to_tokens(tokens);
2697 })
2698 }
2699 }
2700
2701 impl ToTokens for ExprGroup {
2702 fn to_tokens(&self, tokens: &mut Tokens) {
2703 self.group_token.surround(tokens, |tokens| {
2704 self.expr.to_tokens(tokens);
2705 });
2706 }
2707 }
2708
2709 impl ToTokens for ExprParen {
2710 fn to_tokens(&self, tokens: &mut Tokens) {
2711 self.paren_token.surround(tokens, |tokens| {
2712 self.expr.to_tokens(tokens);
2713 });
2714 }
2715 }
2716
2717 #[cfg(feature = "full")]
2718 impl ToTokens for ExprTry {
2719 fn to_tokens(&self, tokens: &mut Tokens) {
2720 self.expr.to_tokens(tokens);
2721 self.question_token.to_tokens(tokens);
2722 }
2723 }
2724
2725 #[cfg(feature = "full")]
2726 impl ToTokens for FieldValue {
2727 fn to_tokens(&self, tokens: &mut Tokens) {
2728 self.ident.to_tokens(tokens);
2729 if !self.is_shorthand {
2732 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2733 self.expr.to_tokens(tokens);
2734 }
2735 }
2736 }
2737
2738 #[cfg(feature = "full")]
2739 impl ToTokens for Arm {
2740 fn to_tokens(&self, tokens: &mut Tokens) {
2741 tokens.append_all(&self.attrs);
2742 self.pats.to_tokens(tokens);
2743 if self.guard.is_some() {
2744 TokensOrDefault(&self.if_token).to_tokens(tokens);
2745 self.guard.to_tokens(tokens);
2746 }
2747 self.rocket_token.to_tokens(tokens);
2748 self.body.to_tokens(tokens);
2749 self.comma.to_tokens(tokens);
2750 }
2751 }
2752
2753 #[cfg(feature = "full")]
2754 impl ToTokens for PatWild {
2755 fn to_tokens(&self, tokens: &mut Tokens) {
2756 self.underscore_token.to_tokens(tokens);
2757 }
2758 }
2759
2760 #[cfg(feature = "full")]
2761 impl ToTokens for PatIdent {
2762 fn to_tokens(&self, tokens: &mut Tokens) {
2763 self.mode.to_tokens(tokens);
2764 self.ident.to_tokens(tokens);
2765 if self.subpat.is_some() {
2766 TokensOrDefault(&self.at_token).to_tokens(tokens);
2767 self.subpat.to_tokens(tokens);
2768 }
2769 }
2770 }
2771
2772 #[cfg(feature = "full")]
2773 impl ToTokens for PatStruct {
2774 fn to_tokens(&self, tokens: &mut Tokens) {
2775 self.path.to_tokens(tokens);
2776 self.brace_token.surround(tokens, |tokens| {
2777 self.fields.to_tokens(tokens);
2778 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
2780 tokens::Comma::default().to_tokens(tokens);
2781 }
2782 self.dot2_token.to_tokens(tokens);
2783 });
2784 }
2785 }
2786
2787 #[cfg(feature = "full")]
2788 impl ToTokens for PatTupleStruct {
2789 fn to_tokens(&self, tokens: &mut Tokens) {
2790 self.path.to_tokens(tokens);
2791 self.pat.to_tokens(tokens);
2792 }
2793 }
2794
2795 #[cfg(feature = "full")]
2796 impl ToTokens for PatPath {
2797 fn to_tokens(&self, tokens: &mut Tokens) {
2798 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2799 }
2800 }
2801
2802 #[cfg(feature = "full")]
2803 impl ToTokens for PatTuple {
2804 fn to_tokens(&self, tokens: &mut Tokens) {
2805 self.paren_token.surround(tokens, |tokens| {
2806 for (i, token) in self.pats.iter().enumerate() {
2807 if Some(i) == self.dots_pos {
2808 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2809 TokensOrDefault(&self.comma_token).to_tokens(tokens);
2810 }
2811 token.to_tokens(tokens);
2812 }
2813
2814 if Some(self.pats.len()) == self.dots_pos {
2815 if !self.pats.empty_or_trailing() {
2817 tokens::Comma::default().to_tokens(tokens);
2818 }
2819 self.dot2_token.to_tokens(tokens);
2820 }
2821 });
2822 }
2823 }
2824
2825 #[cfg(feature = "full")]
2826 impl ToTokens for PatBox {
2827 fn to_tokens(&self, tokens: &mut Tokens) {
2828 self.box_token.to_tokens(tokens);
2829 self.pat.to_tokens(tokens);
2830 }
2831 }
2832
2833 #[cfg(feature = "full")]
2834 impl ToTokens for PatRef {
2835 fn to_tokens(&self, tokens: &mut Tokens) {
2836 self.and_token.to_tokens(tokens);
2837 self.mutbl.to_tokens(tokens);
2838 self.pat.to_tokens(tokens);
2839 }
2840 }
2841
2842 #[cfg(feature = "full")]
2843 impl ToTokens for PatLit {
2844 fn to_tokens(&self, tokens: &mut Tokens) {
2845 self.expr.to_tokens(tokens);
2846 }
2847 }
2848
2849 #[cfg(feature = "full")]
2850 impl ToTokens for PatRange {
2851 fn to_tokens(&self, tokens: &mut Tokens) {
2852 self.lo.to_tokens(tokens);
2853 self.limits.to_tokens(tokens);
2854 self.hi.to_tokens(tokens);
2855 }
2856 }
2857
2858 #[cfg(feature = "full")]
2859 impl ToTokens for PatSlice {
2860 fn to_tokens(&self, tokens: &mut Tokens) {
2861 self.bracket_token.surround(tokens, |tokens| {
2864 self.front.to_tokens(tokens);
2865
2866 if !self.front.empty_or_trailing() &&
2869 (self.middle.is_some() || self.dot2_token.is_some())
2870 {
2871 tokens::Comma::default().to_tokens(tokens);
2872 }
2873
2874 if self.middle.is_some() {
2876 self.middle.to_tokens(tokens);
2877 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2878 } else if self.dot2_token.is_some() {
2879 self.dot2_token.to_tokens(tokens);
2880 }
2881
2882 if !self.back.is_empty() {
2884 TokensOrDefault(&self.comma_token).to_tokens(tokens);
2885 self.back.to_tokens(tokens);
2886 } else {
2887 self.comma_token.to_tokens(tokens);
2888 }
2889 })
2890 }
2891 }
2892
2893 #[cfg(feature = "full")]
2894 impl ToTokens for RangeLimits {
2895 fn to_tokens(&self, tokens: &mut Tokens) {
2896 match *self {
2897 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2898 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2899 }
2900 }
2901 }
2902
2903 #[cfg(feature = "full")]
2904 impl ToTokens for FieldPat {
2905 fn to_tokens(&self, tokens: &mut Tokens) {
2906 if !self.is_shorthand {
2908 self.ident.to_tokens(tokens);
2909 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2910 }
2911 self.pat.to_tokens(tokens);
2912 }
2913 }
2914
2915 #[cfg(feature = "full")]
2916 impl ToTokens for BindingMode {
2917 fn to_tokens(&self, tokens: &mut Tokens) {
2918 match *self {
2919 BindingMode::ByRef(ref t, ref m) => {
2920 t.to_tokens(tokens);
2921 m.to_tokens(tokens);
2922 }
2923 BindingMode::ByValue(ref m) => {
2924 m.to_tokens(tokens);
2925 }
2926 }
2927 }
2928 }
2929
2930 #[cfg(feature = "full")]
2931 impl ToTokens for CaptureBy {
2932 fn to_tokens(&self, tokens: &mut Tokens) {
2933 match *self {
2934 CaptureBy::Value(ref t) => t.to_tokens(tokens),
2935 CaptureBy::Ref => {
2936 }
2938 }
2939 }
2940 }
2941
2942 #[cfg(feature = "full")]
2943 impl ToTokens for Block {
2944 fn to_tokens(&self, tokens: &mut Tokens) {
2945 self.brace_token.surround(tokens, |tokens| {
2946 tokens.append_all(&self.stmts);
2947 });
2948 }
2949 }
2950
2951 #[cfg(feature = "full")]
2952 impl ToTokens for Stmt {
2953 fn to_tokens(&self, tokens: &mut Tokens) {
2954 match *self {
2955 Stmt::Local(ref local) => local.to_tokens(tokens),
2956 Stmt::Item(ref item) => item.to_tokens(tokens),
2957 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
2958 Stmt::Semi(ref expr, ref semi) => {
2959 expr.to_tokens(tokens);
2960 semi.to_tokens(tokens);
2961 }
2962 Stmt::Mac(ref mac) => {
2963 let (ref mac, ref style, ref attrs) = **mac;
2964 tokens.append_all(attrs.outer());
2965 mac.to_tokens(tokens);
2966 match *style {
2967 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
2968 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2969 }
2971 }
2972 }
2973 }
2974 }
2975 }
2976
2977 #[cfg(feature = "full")]
2978 impl ToTokens for Local {
2979 fn to_tokens(&self, tokens: &mut Tokens) {
2980 tokens.append_all(self.attrs.outer());
2981 self.let_token.to_tokens(tokens);
2982 self.pat.to_tokens(tokens);
2983 if self.ty.is_some() {
2984 TokensOrDefault(&self.colon_token).to_tokens(tokens);
2985 self.ty.to_tokens(tokens);
2986 }
2987 if self.init.is_some() {
2988 TokensOrDefault(&self.eq_token).to_tokens(tokens);
2989 self.init.to_tokens(tokens);
2990 }
2991 self.semi_token.to_tokens(tokens);
2992 }
2993 }
2994}