blob: 8682f6a298b349b43befccf364923186016f41dd [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay85b69a42017-12-27 20:43:10 -05003#[cfg(feature = "full")]
4use proc_macro2::Span;
5#[cfg(feature = "full")]
6use std::hash::{Hash, Hasher};
David Tolnayf4bbbd92016-09-23 14:41:55 -07007
Alex Crichton62a0a592017-05-22 13:58:53 -07008ast_struct! {
9 /// An expression.
10 pub struct Expr {
Alex Crichton62a0a592017-05-22 13:58:53 -070011 /// Attributes tagged on the expression.
12 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050013
14 /// Type of the expression.
15 pub node: ExprKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070016 }
David Tolnay7184b132016-10-30 10:06:37 -070017}
18
19impl From<ExprKind> for Expr {
20 fn from(node: ExprKind) -> Expr {
21 Expr {
22 node: node,
23 attrs: Vec::new(),
24 }
25 }
26}
27
Alex Crichton62a0a592017-05-22 13:58:53 -070028ast_enum_of_structs! {
29 pub enum ExprKind {
30 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040031 pub Box(ExprBox #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080032 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -050033 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
Clar Charrd22b5702017-03-10 15:24:56 -050035
Michael Layzellb78f3b52017-06-04 19:03:03 -040036 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040037 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070038 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040039 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070040 pub value: Box<Expr>,
41 }),
Clar Charrd22b5702017-03-10 15:24:56 -050042
Alex Crichton62a0a592017-05-22 13:58:53 -070043 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040044 pub Array(ExprArray #full {
David Tolnay32954ef2017-12-26 22:43:16 -050045 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -050046 pub exprs: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070047 }),
Clar Charrd22b5702017-03-10 15:24:56 -050048
Alex Crichton62a0a592017-05-22 13:58:53 -070049 /// A function call.
50 pub Call(ExprCall {
51 pub func: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -050052 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -050053 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070054 }),
Clar Charrd22b5702017-03-10 15:24:56 -050055
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
57 ///
58 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080059 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070060 /// (within the angle brackets).
61 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070062 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
63 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040064 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080066 pub dot_token: Token![.],
David Tolnay4a3f59a2017-12-28 21:21:12 -050067 pub method: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -080068 pub colon2_token: Option<Token![::]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050069 pub lt_token: Option<Token![<]>,
70 pub typarams: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080071 pub gt_token: Option<Token![>]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050072 pub paren_token: token::Paren,
73 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 }),
Clar Charrd22b5702017-03-10 15:24:56 -050075
Alex Crichton62a0a592017-05-22 13:58:53 -070076 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050077 pub Tuple(ExprTuple #full {
David Tolnay32954ef2017-12-26 22:43:16 -050078 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -050079 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070080 }),
Clar Charrd22b5702017-03-10 15:24:56 -050081
Alex Crichton62a0a592017-05-22 13:58:53 -070082 /// A binary operation, e.g. `a + b`, `a * b`.
83 pub Binary(ExprBinary {
Alex Crichton62a0a592017-05-22 13:58:53 -070084 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050085 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -070086 pub right: Box<Expr>,
87 }),
Clar Charrd22b5702017-03-10 15:24:56 -050088
Alex Crichton62a0a592017-05-22 13:58:53 -070089 /// A unary operation, e.g. `!x`, `*x`.
90 pub Unary(ExprUnary {
91 pub op: UnOp,
92 pub expr: Box<Expr>,
93 }),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A literal, e.g. `1`, `"foo"`.
96 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050097
Alex Crichton62a0a592017-05-22 13:58:53 -070098 /// A cast, e.g. `foo as f64`.
99 pub Cast(ExprCast {
100 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800101 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800102 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500104
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 /// A type ascription, e.g. `foo: f64`.
106 pub Type(ExprType {
107 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800108 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800109 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500111
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 /// An `if` block, with an optional else block
113 ///
114 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400115 pub If(ExprIf #full {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500116 pub if_token: Token![if],
Alex Crichton62a0a592017-05-22 13:58:53 -0700117 pub cond: Box<Expr>,
118 pub if_true: Block,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800119 pub else_token: Option<Token![else]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500120 pub if_false: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700121 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500122
Alex Crichton62a0a592017-05-22 13:58:53 -0700123 /// An `if let` expression with an optional else block
124 ///
125 /// E.g., `if let pat = expr { block } else { expr }`
126 ///
127 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400128 pub IfLet(ExprIfLet #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800129 pub if_token: Token![if],
130 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500131 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800132 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500133 pub expr: Box<Expr>,
134 pub if_true: Block,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800135 pub else_token: Option<Token![else]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500136 pub if_false: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700137 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500138
Alex Crichton62a0a592017-05-22 13:58:53 -0700139 /// A while loop, with an optional label
140 ///
141 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400142 pub While(ExprWhile #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700143 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800144 pub colon_token: Option<Token![:]>,
145 pub while_token: Token![while],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500146 pub cond: Box<Expr>,
147 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700148 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500149
Alex Crichton62a0a592017-05-22 13:58:53 -0700150 /// A while-let loop, with an optional label.
151 ///
152 /// E.g., `'label: while let pat = expr { block }`
153 ///
154 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400155 pub WhileLet(ExprWhileLet #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800157 pub colon_token: Option<Token![:]>,
158 pub while_token: Token![while],
159 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500160 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800161 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500162 pub expr: Box<Expr>,
163 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700164 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500165
Alex Crichton62a0a592017-05-22 13:58:53 -0700166 /// A for loop, with an optional label.
167 ///
168 /// E.g., `'label: for pat in expr { block }`
169 ///
170 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400171 pub ForLoop(ExprForLoop #full {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500172 pub label: Option<Lifetime>,
173 pub colon_token: Option<Token![:]>,
174 pub for_token: Token![for],
Alex Crichton62a0a592017-05-22 13:58:53 -0700175 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500176 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700177 pub expr: Box<Expr>,
178 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700179 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500180
Alex Crichton62a0a592017-05-22 13:58:53 -0700181 /// Conditionless loop with an optional label.
182 ///
183 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400184 pub Loop(ExprLoop #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700185 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800186 pub colon_token: Option<Token![:]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500187 pub loop_token: Token![loop],
188 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700189 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500190
Alex Crichton62a0a592017-05-22 13:58:53 -0700191 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400192 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800193 pub match_token: Token![match],
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500195 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 pub arms: Vec<Arm>,
197 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500198
Alex Crichton62a0a592017-05-22 13:58:53 -0700199 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400200 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800202 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500203 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800204 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500205 pub output: ReturnType,
206 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500208
Nika Layzell640832a2017-12-04 13:37:09 -0500209 /// An unsafe block (`unsafe { ... }`)
210 pub Unsafe(ExprUnsafe #full {
211 pub unsafe_token: Token![unsafe],
212 pub block: Block,
213 }),
214
215 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400216 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700217 pub block: Block,
218 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700219
Alex Crichton62a0a592017-05-22 13:58:53 -0700220 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub left: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800223 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500224 pub right: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// An assignment with an operator
228 ///
229 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400230 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500232 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -0700233 pub right: Box<Expr>,
234 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500235
David Tolnay85b69a42017-12-27 20:43:10 -0500236 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
237 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400238 pub Field(ExprField #full {
David Tolnay85b69a42017-12-27 20:43:10 -0500239 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800240 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500241 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500243
Alex Crichton62a0a592017-05-22 13:58:53 -0700244 /// An indexing operation (`foo[2]`)
245 pub Index(ExprIndex {
246 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500247 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500248 pub index: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500250
David Tolnaybe55d7b2017-12-17 23:41:20 -0800251 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400252 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 pub from: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500255 pub to: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700256 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700257
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 /// Variable reference, possibly containing `::` and/or type
259 /// parameters, e.g. foo::bar::<baz>.
260 ///
261 /// Optionally "qualified",
262 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
263 pub Path(ExprPath {
264 pub qself: Option<QSelf>,
265 pub path: Path,
266 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700267
Alex Crichton62a0a592017-05-22 13:58:53 -0700268 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400269 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800270 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 pub mutbl: Mutability,
272 pub expr: Box<Expr>,
273 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500274
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400276 pub Break(ExprBreak #full {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500277 pub break_token: Token![break],
David Tolnay63e3dee2017-06-03 20:13:17 -0700278 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 pub expr: Option<Box<Expr>>,
280 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500281
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400283 pub Continue(ExprContinue #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800284 pub continue_token: Token![continue],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500285 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500287
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400289 pub Ret(ExprRet #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800290 pub return_token: Token![return],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500291 pub expr: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700293
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800295 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700296
Alex Crichton62a0a592017-05-22 13:58:53 -0700297 /// A struct literal expression.
298 ///
299 /// For example, `Foo {x: 1, y: 2}`, or
300 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400301 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700302 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500303 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500304 pub fields: Delimited<FieldValue, Token![,]>,
305 pub dot2_token: Option<Token![..]>,
306 pub rest: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700307 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700308
Alex Crichton62a0a592017-05-22 13:58:53 -0700309 /// An array literal constructed from one repeated element.
310 ///
311 /// For example, `[1; 5]`. The first expression is the element
312 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400313 pub Repeat(ExprRepeat #full {
David Tolnay32954ef2017-12-26 22:43:16 -0500314 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500316 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700317 pub amt: Box<Expr>,
318 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700319
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 /// No-op: used solely so we can pretty-print faithfully
321 pub Paren(ExprParen {
David Tolnay32954ef2017-12-26 22:43:16 -0500322 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500323 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700325
Michael Layzell93c36282017-06-04 20:43:14 -0400326 /// No-op: used solely so we can pretty-print faithfully
327 ///
328 /// A `group` represents a `None`-delimited span in the input
329 /// `TokenStream` which affects the precidence of the resulting
330 /// expression. They are used for macro hygiene.
331 pub Group(ExprGroup {
David Tolnay32954ef2017-12-26 22:43:16 -0500332 pub group_token: token::Group,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500333 pub expr: Box<Expr>,
Michael Layzell93c36282017-06-04 20:43:14 -0400334 }),
335
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400337 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700338 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800339 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700340 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700341
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 /// A catch expression.
343 ///
344 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400345 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800346 pub do_token: Token![do],
347 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700348 pub block: Block,
349 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700350
351 /// A yield expression.
352 ///
353 /// E.g. `yield expr`
354 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800355 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700356 pub expr: Option<Box<Expr>>,
357 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700358 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700359}
360
Michael Layzell734adb42017-06-07 16:58:31 -0400361#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500362ast_enum! {
363 /// A struct or tuple struct field accessed in a struct literal or field
364 /// expression.
365 pub enum Member {
366 /// A named field like `self.x`.
367 Named(Ident),
368 /// An unnamed field like `self.0`.
369 Unnamed(Index),
370 }
371}
372
373#[cfg(feature = "full")]
374ast_struct! {
375 /// The index of an unnamed tuple struct field.
376 pub struct Index #manual_extra_traits {
377 pub index: u32,
378 pub span: Span,
379 }
380}
381
382#[cfg(feature = "full")]
383impl Eq for Index {}
384
385#[cfg(feature = "full")]
386impl PartialEq for Index {
387 fn eq(&self, other: &Self) -> bool {
388 self.index == other.index
389 }
390}
391
392#[cfg(feature = "full")]
393impl Hash for Index {
394 fn hash<H: Hasher>(&self, state: &mut H) {
395 self.index.hash(state);
396 }
397}
398
399#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700400ast_struct! {
401 /// A field-value pair in a struct literal.
402 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500403 /// Attributes tagged on the field.
404 pub attrs: Vec<Attribute>,
405
406 /// Name or index of the field.
407 pub member: Member,
408
409 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// Value of the field.
412 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// Whether this is a shorthand field, e.g. `Struct { x }`
415 /// instead of `Struct { x: x }`.
416 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700417 }
David Tolnay055a7042016-10-02 19:23:54 -0700418}
419
Michael Layzell734adb42017-06-07 16:58:31 -0400420#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700421ast_struct! {
422 /// A Block (`{ .. }`).
423 ///
424 /// E.g. `{ .. }` as in `fn foo() { .. }`
425 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500426 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700427 /// Statements in a block
428 pub stmts: Vec<Stmt>,
429 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700430}
431
Michael Layzell734adb42017-06-07 16:58:31 -0400432#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700433ast_enum! {
434 /// A statement, usually ending in a semicolon.
435 pub enum Stmt {
436 /// A local (let) binding.
437 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700438
Alex Crichton62a0a592017-05-22 13:58:53 -0700439 /// An item definition.
440 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 /// Expr without trailing semicolon.
443 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800446 Semi(Box<Expr>, Token![;]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700447 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700448}
449
Michael Layzell734adb42017-06-07 16:58:31 -0400450#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700451ast_struct! {
452 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
453 pub struct Local {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500454 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800455 pub let_token: Token![let],
Alex Crichton62a0a592017-05-22 13:58:53 -0700456 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500457 pub colon_token: Option<Token![:]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800458 pub ty: Option<Box<Type>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500459 pub eq_token: Option<Token![=]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700460 /// Initializer expression to set the value, if any
461 pub init: Option<Box<Expr>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500462 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700463 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700464}
465
Michael Layzell734adb42017-06-07 16:58:31 -0400466#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700467ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700468 // Clippy false positive
469 // https://github.com/Manishearth/rust-clippy/issues/1241
470 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
471 pub enum Pat {
472 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700473 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800474 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700476
Alex Crichton62a0a592017-05-22 13:58:53 -0700477 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
478 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
479 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
480 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700481 pub Ident(PatIdent {
482 pub mode: BindingMode,
483 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800484 pub at_token: Option<Token![@]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500485 pub subpat: Option<Box<Pat>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700486 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700487
Alex Crichton62a0a592017-05-22 13:58:53 -0700488 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
489 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700490 pub Struct(PatStruct {
491 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500492 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500493 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800494 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700495 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700496
Alex Crichton62a0a592017-05-22 13:58:53 -0700497 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
498 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
499 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700500 pub TupleStruct(PatTupleStruct {
501 pub path: Path,
502 pub pat: PatTuple,
503 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700504
Alex Crichton62a0a592017-05-22 13:58:53 -0700505 /// A possibly qualified path pattern.
506 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
507 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
508 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700509 pub Path(PatPath {
510 pub qself: Option<QSelf>,
511 pub path: Path,
512 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700513
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A tuple pattern `(a, b)`.
515 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
516 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700517 pub Tuple(PatTuple {
David Tolnay32954ef2017-12-26 22:43:16 -0500518 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500519 pub pats: Delimited<Pat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800520 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500521 pub dots_pos: Option<usize>,
522 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700523 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700524 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub Box(PatBox {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800526 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500527 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700528 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700529 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 pub Ref(PatRef {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800531 pub and_token: Token![&],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500532 pub mutbl: Mutability,
533 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700534 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700535 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 pub Lit(PatLit {
537 pub expr: Box<Expr>,
538 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800539 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700540 pub Range(PatRange {
541 pub lo: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700542 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500543 pub hi: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400545 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 pub Slice(PatSlice {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500547 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800548 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700549 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800550 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500551 pub dot2_token: Option<Token![..]>,
552 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700553 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800555 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700556 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700557}
558
Michael Layzell734adb42017-06-07 16:58:31 -0400559#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700560ast_struct! {
561 /// An arm of a 'match'.
562 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800563 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500565 /// ```rust
566 /// # #![feature(dotdoteq_in_patterns)]
567 /// #
568 /// # fn main() {
569 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700570 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500571 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700572 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500573 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700574 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500575 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 /// ```
577 pub struct Arm {
578 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800579 pub pats: Delimited<Pat, Token![|]>,
580 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800582 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700583 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800584 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700585 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700586}
587
Michael Layzell734adb42017-06-07 16:58:31 -0400588#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700589ast_enum! {
590 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700591 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700592 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800593 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700594 Ref,
595 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700596}
597
Michael Layzell734adb42017-06-07 16:58:31 -0400598#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700599ast_enum! {
600 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700601 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700602 pub enum RangeLimits {
603 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800604 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800606 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700607 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700608}
609
Michael Layzell734adb42017-06-07 16:58:31 -0400610#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700611ast_struct! {
612 /// A single field in a struct pattern
613 ///
614 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
615 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
616 /// except `is_shorthand` is true
617 pub struct FieldPat {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500618 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700619 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500620 pub member: Member,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500621 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700622 /// The pattern the field is destructured to
623 pub pat: Box<Pat>,
624 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700625 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700626}
627
Michael Layzell734adb42017-06-07 16:58:31 -0400628#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700629ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700630 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700631 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800632 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700633 ByValue(Mutability),
634 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700635}
636
Michael Layzell734adb42017-06-07 16:58:31 -0400637#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400638ast_enum! {
639 #[cfg_attr(feature = "clone-impls", derive(Copy))]
640 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800641 Arrow(Token![<-]),
642 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400643 }
644}
645
Michael Layzell3936ceb2017-07-08 00:28:36 -0400646#[cfg(any(feature = "parsing", feature = "printing"))]
647#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700648fn arm_expr_requires_comma(expr: &Expr) -> bool {
649 // see https://github.com/rust-lang/rust/blob/eb8f2586e
650 // /src/libsyntax/parse/classify.rs#L17-L37
651 match expr.node {
David Tolnay51382052017-12-27 13:46:21 -0500652 ExprKind::Unsafe(..)
653 | ExprKind::Block(..)
654 | ExprKind::If(..)
655 | ExprKind::IfLet(..)
656 | ExprKind::Match(..)
657 | ExprKind::While(..)
658 | ExprKind::WhileLet(..)
659 | ExprKind::Loop(..)
660 | ExprKind::ForLoop(..)
661 | ExprKind::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700662 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400663 }
664}
665
David Tolnayb9c8e322016-09-23 20:48:37 -0700666#[cfg(feature = "parsing")]
667pub mod parsing {
668 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700669 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700670
Michael Layzell734adb42017-06-07 16:58:31 -0400671 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500672 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500673 use synom::Synom;
674 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400675 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500676 use parse_error;
David Tolnay203557a2017-12-27 23:59:33 -0500677 use synom::PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700678
David Tolnaybcf26022017-12-25 22:10:52 -0500679 // When we're parsing expressions which occur before blocks, like in an if
680 // statement's condition, we cannot parse a struct literal.
681 //
682 // Struct literals are ambiguous in certain positions
683 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700684 macro_rules! ambiguous_expr {
685 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700686 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700687 };
688 }
689
David Tolnaybcf26022017-12-25 22:10:52 -0500690 // When we are parsing an optional suffix expression, we cannot allow blocks
691 // if structs are not allowed.
692 //
693 // Example:
694 //
695 // if break {} {}
696 //
697 // is ambiguous between:
698 //
699 // if (break {}) {}
700 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400701 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400702 macro_rules! opt_ambiguous_expr {
703 ($i:expr, $allow_struct:ident) => {
704 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
705 };
706 }
707
Alex Crichton954046c2017-05-30 21:49:42 -0700708 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400709 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700710
711 fn description() -> Option<&'static str> {
712 Some("expression")
713 }
714 }
715
Michael Layzell734adb42017-06-07 16:58:31 -0400716 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700717 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
718
David Tolnaybcf26022017-12-25 22:10:52 -0500719 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400720 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500721 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400722 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700723 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400724 call!(assign_expr, allow_struct, allow_block),
725 ExprKind::into
726 )
727 }
728
Michael Layzell734adb42017-06-07 16:58:31 -0400729 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500730 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzell734adb42017-06-07 16:58:31 -0400731 map!(
732 i,
733 // NOTE: We intentionally skip assign_expr, placement_expr, and
734 // range_expr, as they are not parsed in non-full mode.
735 call!(or_expr, allow_struct, allow_block),
736 ExprKind::into
737 )
738 }
739
David Tolnaybcf26022017-12-25 22:10:52 -0500740 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400741 macro_rules! binop {
742 (
743 $name: ident,
744 $next: ident,
745 $submac: ident!( $($args:tt)* )
746 ) => {
747 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
748 mut e: call!($next, allow_struct, allow_block) >>
749 many0!(do_parse!(
750 op: $submac!($($args)*) >>
751 rhs: call!($next, allow_struct, true) >>
752 ({
753 e = ExprBinary {
754 left: Box::new(e.into()),
755 op: op,
756 right: Box::new(rhs.into()),
757 }.into();
758 })
759 )) >>
760 (e)
761 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700762 }
David Tolnay54e854d2016-10-24 12:03:30 -0700763 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700764
David Tolnaybcf26022017-12-25 22:10:52 -0500765 // <placement> = <placement> ..
766 // <placement> += <placement> ..
767 // <placement> -= <placement> ..
768 // <placement> *= <placement> ..
769 // <placement> /= <placement> ..
770 // <placement> %= <placement> ..
771 // <placement> ^= <placement> ..
772 // <placement> &= <placement> ..
773 // <placement> |= <placement> ..
774 // <placement> <<= <placement> ..
775 // <placement> >>= <placement> ..
776 //
777 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400778 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400779 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
780 mut e: call!(placement_expr, allow_struct, allow_block) >>
781 alt!(
782 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800783 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400784 // Recurse into self to parse right-associative operator.
785 rhs: call!(assign_expr, allow_struct, true) >>
786 ({
787 e = ExprAssign {
788 left: Box::new(e.into()),
789 eq_token: eq,
790 right: Box::new(rhs.into()),
791 }.into();
792 })
793 )
794 |
795 do_parse!(
796 op: call!(BinOp::parse_assign_op) >>
797 // Recurse into self to parse right-associative operator.
798 rhs: call!(assign_expr, allow_struct, true) >>
799 ({
800 e = ExprAssignOp {
801 left: Box::new(e.into()),
802 op: op,
803 right: Box::new(rhs.into()),
804 }.into();
805 })
806 )
807 |
808 epsilon!()
809 ) >>
810 (e)
811 ));
812
David Tolnaybcf26022017-12-25 22:10:52 -0500813 // <range> <- <range> ..
814 //
815 // NOTE: The `in place { expr }` version of this syntax is parsed in
816 // `atom_expr`, not here.
817 //
818 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400819 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400820 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
821 mut e: call!(range_expr, allow_struct, allow_block) >>
822 alt!(
823 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800824 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400825 // Recurse into self to parse right-associative operator.
826 rhs: call!(placement_expr, allow_struct, true) >>
827 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400828 e = ExprInPlace {
829 // op: BinOp::Place(larrow),
830 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400831 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400832 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400833 }.into();
834 })
835 )
836 |
837 epsilon!()
838 ) >>
839 (e)
840 ));
841
David Tolnaybcf26022017-12-25 22:10:52 -0500842 // <or> ... <or> ..
843 // <or> .. <or> ..
844 // <or> ..
845 //
846 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
847 // rules are for parsing these expressions are, but this is not correct.
848 // For example, `a .. b .. c` is not a legal expression. It should not
849 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
850 //
851 // NOTE: The form of ranges which don't include a preceding expression are
852 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400853 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400854 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
855 mut e: call!(or_expr, allow_struct, allow_block) >>
856 many0!(do_parse!(
857 limits: syn!(RangeLimits) >>
858 // We don't want to allow blocks here if we don't allow structs. See
859 // the reasoning for `opt_ambiguous_expr!` above.
860 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
861 ({
862 e = ExprRange {
863 from: Some(Box::new(e.into())),
864 limits: limits,
865 to: hi.map(|e| Box::new(e.into())),
866 }.into();
867 })
868 )) >>
869 (e)
870 ));
871
David Tolnaybcf26022017-12-25 22:10:52 -0500872 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800873 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400874
David Tolnaybcf26022017-12-25 22:10:52 -0500875 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800876 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400877
David Tolnaybcf26022017-12-25 22:10:52 -0500878 // <bitor> == <bitor> ...
879 // <bitor> != <bitor> ...
880 // <bitor> >= <bitor> ...
881 // <bitor> <= <bitor> ...
882 // <bitor> > <bitor> ...
883 // <bitor> < <bitor> ...
884 //
885 // NOTE: This operator appears to be parsed as left-associative, but errors
886 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500887 binop!(
888 compare_expr,
889 bitor_expr,
890 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800891 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400892 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800893 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400894 |
895 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800896 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400897 |
898 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800899 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400900 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400901 do_parse!(
902 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800903 not!(punct!(<-)) >>
904 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400905 (BinOp::Lt(t))
906 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400907 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800908 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500909 )
910 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400911
David Tolnaybcf26022017-12-25 22:10:52 -0500912 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500913 binop!(
914 bitor_expr,
915 bitxor_expr,
916 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
917 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400918
David Tolnaybcf26022017-12-25 22:10:52 -0500919 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500920 binop!(
921 bitxor_expr,
922 bitand_expr,
923 do_parse!(
924 // NOTE: Make sure we aren't looking at ^=.
925 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
926 )
927 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400928
David Tolnaybcf26022017-12-25 22:10:52 -0500929 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -0500930 binop!(
931 bitand_expr,
932 shift_expr,
933 do_parse!(
934 // NOTE: Make sure we aren't looking at && or &=.
935 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
936 )
937 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400938
David Tolnaybcf26022017-12-25 22:10:52 -0500939 // <arith> << <arith> ...
940 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -0500941 binop!(
942 shift_expr,
943 arith_expr,
944 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800945 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400946 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800947 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -0500948 )
949 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400950
David Tolnaybcf26022017-12-25 22:10:52 -0500951 // <term> + <term> ...
952 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -0500953 binop!(
954 arith_expr,
955 term_expr,
956 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800957 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400958 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800959 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -0500960 )
961 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400962
David Tolnaybcf26022017-12-25 22:10:52 -0500963 // <cast> * <cast> ...
964 // <cast> / <cast> ...
965 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -0500966 binop!(
967 term_expr,
968 cast_expr,
969 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800970 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400971 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800972 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400973 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800974 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -0500975 )
976 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400977
David Tolnaybcf26022017-12-25 22:10:52 -0500978 // <unary> as <ty>
979 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400980 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
981 mut e: call!(unary_expr, allow_struct, allow_block) >>
982 many0!(alt!(
983 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800984 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400985 // We can't accept `A + B` in cast expressions, as it's
986 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800987 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400988 ({
989 e = ExprCast {
990 expr: Box::new(e.into()),
991 as_token: as_,
992 ty: Box::new(ty),
993 }.into();
994 })
995 )
996 |
997 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800998 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400999 // We can't accept `A + B` in cast expressions, as it's
1000 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001001 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001002 ({
1003 e = ExprType {
1004 expr: Box::new(e.into()),
1005 colon_token: colon,
1006 ty: Box::new(ty),
1007 }.into();
1008 })
1009 )
1010 )) >>
1011 (e)
1012 ));
1013
David Tolnaybcf26022017-12-25 22:10:52 -05001014 // <UnOp> <trailer>
1015 // & <trailer>
1016 // &mut <trailer>
1017 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001018 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001019 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1020 do_parse!(
1021 op: syn!(UnOp) >>
1022 expr: call!(unary_expr, allow_struct, true) >>
1023 (ExprUnary {
1024 op: op,
1025 expr: Box::new(expr.into()),
1026 }.into())
1027 )
1028 |
1029 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001030 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001031 mutability: syn!(Mutability) >>
1032 expr: call!(unary_expr, allow_struct, true) >>
1033 (ExprAddrOf {
1034 and_token: and,
1035 mutbl: mutability,
1036 expr: Box::new(expr.into()),
1037 }.into())
1038 )
1039 |
1040 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001041 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001042 expr: call!(unary_expr, allow_struct, true) >>
1043 (ExprBox {
1044 box_token: box_,
1045 expr: Box::new(expr.into()),
1046 }.into())
1047 )
1048 |
1049 call!(trailer_expr, allow_struct, allow_block)
1050 ));
1051
Michael Layzell734adb42017-06-07 16:58:31 -04001052 // XXX: This duplication is ugly
1053 #[cfg(not(feature = "full"))]
1054 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1055 do_parse!(
1056 op: syn!(UnOp) >>
1057 expr: call!(unary_expr, allow_struct, true) >>
1058 (ExprUnary {
1059 op: op,
1060 expr: Box::new(expr.into()),
1061 }.into())
1062 )
1063 |
1064 call!(trailer_expr, allow_struct, allow_block)
1065 ));
1066
David Tolnaybcf26022017-12-25 22:10:52 -05001067 // <atom> (..<args>) ...
1068 // <atom> . <ident> (..<args>) ...
1069 // <atom> . <ident> ...
1070 // <atom> . <lit> ...
1071 // <atom> [ <expr> ] ...
1072 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001073 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001074 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1075 mut e: call!(atom_expr, allow_struct, allow_block) >>
1076 many0!(alt!(
1077 tap!(args: and_call => {
1078 let (args, paren) = args;
1079 e = ExprCall {
1080 func: Box::new(e.into()),
1081 args: args,
1082 paren_token: paren,
1083 }.into();
1084 })
1085 |
1086 tap!(more: and_method_call => {
1087 let mut call = more;
1088 call.expr = Box::new(e.into());
1089 e = call.into();
1090 })
1091 |
1092 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001093 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001094 e = ExprField {
David Tolnay85b69a42017-12-27 20:43:10 -05001095 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001096 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001097 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001098 }.into();
1099 })
1100 |
1101 tap!(i: and_index => {
1102 let (i, token) = i;
1103 e = ExprIndex {
1104 expr: Box::new(e.into()),
1105 bracket_token: token,
1106 index: Box::new(i),
1107 }.into();
1108 })
1109 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001110 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001111 e = ExprTry {
1112 expr: Box::new(e.into()),
1113 question_token: question,
1114 }.into();
1115 })
1116 )) >>
1117 (e)
1118 ));
1119
Michael Layzell734adb42017-06-07 16:58:31 -04001120 // XXX: Duplication == ugly
1121 #[cfg(not(feature = "full"))]
1122 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1123 mut e: call!(atom_expr, allow_struct, allow_block) >>
1124 many0!(alt!(
1125 tap!(args: and_call => {
1126 let (args, paren) = args;
1127 e = ExprCall {
1128 func: Box::new(e.into()),
1129 args: args,
1130 paren_token: paren,
1131 }.into();
1132 })
1133 |
1134 tap!(i: and_index => {
1135 let (i, token) = i;
1136 e = ExprIndex {
1137 expr: Box::new(e.into()),
1138 bracket_token: token,
1139 index: Box::new(i),
1140 }.into();
1141 })
1142 )) >>
1143 (e)
1144 ));
1145
David Tolnaybcf26022017-12-25 22:10:52 -05001146 // Parse all atomic expressions which don't have to worry about precidence
1147 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001148 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001149 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001150 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1151 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001152 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1153 |
1154 // must be before expr_path
1155 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1156 |
1157 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1158 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001159 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001160 |
1161 call!(expr_break, allow_struct) // must be before expr_path
1162 |
1163 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1164 |
1165 call!(expr_ret, allow_struct) // must be before expr_path
1166 |
1167 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1168 syn!(ExprInPlace) => { ExprKind::InPlace }
1169 |
1170 syn!(ExprArray) => { ExprKind::Array }
1171 |
David Tolnay05362582017-12-26 01:33:57 -05001172 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001173 |
1174 syn!(ExprIf) => { ExprKind::If }
1175 |
1176 syn!(ExprIfLet) => { ExprKind::IfLet }
1177 |
1178 syn!(ExprWhile) => { ExprKind::While }
1179 |
1180 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1181 |
1182 syn!(ExprForLoop) => { ExprKind::ForLoop }
1183 |
1184 syn!(ExprLoop) => { ExprKind::Loop }
1185 |
1186 syn!(ExprMatch) => { ExprKind::Match }
1187 |
1188 syn!(ExprCatch) => { ExprKind::Catch }
1189 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001190 syn!(ExprYield) => { ExprKind::Yield }
1191 |
Nika Layzell640832a2017-12-04 13:37:09 -05001192 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1193 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001194 call!(expr_closure, allow_struct)
1195 |
1196 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1197 |
1198 // NOTE: This is the prefix-form of range
1199 call!(expr_range, allow_struct)
1200 |
1201 syn!(ExprPath) => { ExprKind::Path }
1202 |
1203 syn!(ExprRepeat) => { ExprKind::Repeat }
1204 ));
1205
Michael Layzell734adb42017-06-07 16:58:31 -04001206 #[cfg(not(feature = "full"))]
1207 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1208 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1209 |
1210 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1211 |
1212 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1213 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001214 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001215 |
1216 syn!(ExprPath) => { ExprKind::Path }
1217 ));
1218
Michael Layzell734adb42017-06-07 16:58:31 -04001219 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001220 named!(expr_nosemi -> Expr, map!(alt!(
1221 syn!(ExprIf) => { ExprKind::If }
1222 |
1223 syn!(ExprIfLet) => { ExprKind::IfLet }
1224 |
1225 syn!(ExprWhile) => { ExprKind::While }
1226 |
1227 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1228 |
1229 syn!(ExprForLoop) => { ExprKind::ForLoop }
1230 |
1231 syn!(ExprLoop) => { ExprKind::Loop }
1232 |
1233 syn!(ExprMatch) => { ExprKind::Match }
1234 |
1235 syn!(ExprCatch) => { ExprKind::Catch }
1236 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001237 syn!(ExprYield) => { ExprKind::Yield }
1238 |
Nika Layzell640832a2017-12-04 13:37:09 -05001239 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1240 |
Michael Layzell35418782017-06-07 09:20:25 -04001241 syn!(ExprBlock) => { ExprKind::Block }
1242 ), Expr::from));
1243
Michael Layzell93c36282017-06-04 20:43:14 -04001244 impl Synom for ExprGroup {
1245 named!(parse -> Self, do_parse!(
1246 e: grouped!(syn!(Expr)) >>
1247 (ExprGroup {
1248 expr: Box::new(e.0),
1249 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001250 })
Michael Layzell93c36282017-06-04 20:43:14 -04001251 ));
1252 }
1253
Alex Crichton954046c2017-05-30 21:49:42 -07001254 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001255 named!(parse -> Self, do_parse!(
1256 e: parens!(syn!(Expr)) >>
1257 (ExprParen {
1258 expr: Box::new(e.0),
1259 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001260 })
Michael Layzell92639a52017-06-01 00:07:44 -04001261 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001262 }
David Tolnay89e05672016-10-02 14:39:42 -07001263
Michael Layzell734adb42017-06-07 16:58:31 -04001264 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001265 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001266 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001267 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001268 place: expr_no_struct >>
1269 value: braces!(call!(Block::parse_within)) >>
1270 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001271 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001272 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001273 value: Box::new(Expr {
1274 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001275 block: Block {
1276 stmts: value.0,
1277 brace_token: value.1,
1278 },
1279 }.into(),
1280 attrs: Vec::new(),
1281 }),
1282 })
1283 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001284 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001285
Michael Layzell734adb42017-06-07 16:58:31 -04001286 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001287 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001288 named!(parse -> Self, do_parse!(
1289 elems: brackets!(call!(Delimited::parse_terminated)) >>
1290 (ExprArray {
1291 exprs: elems.0,
1292 bracket_token: elems.1,
1293 })
1294 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001295 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001296
David Tolnay32954ef2017-12-26 22:43:16 -05001297 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001298 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001299
Michael Layzell734adb42017-06-07 16:58:31 -04001300 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001301 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001302 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001303 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001304 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001305 colon2: punct!(::) >>
1306 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001307 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001308 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001309 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001310 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001311 args: parens!(call!(Delimited::parse_terminated)) >>
1312 ({
1313 let (colon2, lt, tys, gt) = match typarams {
1314 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1315 None => (None, None, None, None),
1316 };
1317 ExprMethodCall {
1318 // this expr will get overwritten after being returned
1319 expr: Box::new(ExprKind::Lit(Lit {
1320 span: Span::default(),
1321 value: LitKind::Bool(false),
1322 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001323
Alex Crichton954046c2017-05-30 21:49:42 -07001324 method: method,
1325 args: args.0,
1326 paren_token: args.1,
1327 dot_token: dot,
1328 lt_token: lt,
1329 gt_token: gt,
1330 colon2_token: colon2,
1331 typarams: tys.unwrap_or_default(),
1332 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001333 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001334 ));
1335
Michael Layzell734adb42017-06-07 16:58:31 -04001336 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001337 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001338 named!(parse -> Self, do_parse!(
1339 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001340 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001341 args: elems.0,
1342 paren_token: elems.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001343 })
1344 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001345 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001346
Michael Layzell734adb42017-06-07 16:58:31 -04001347 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001348 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001349 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001350 if_: keyword!(if) >>
1351 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001352 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001353 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001354 cond: expr_no_struct >>
1355 then_block: braces!(call!(Block::parse_within)) >>
1356 else_block: option!(else_block) >>
1357 (ExprIfLet {
1358 pat: Box::new(pat),
1359 let_token: let_,
1360 eq_token: eq,
1361 expr: Box::new(cond),
1362 if_true: Block {
1363 stmts: then_block.0,
1364 brace_token: then_block.1,
1365 },
1366 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001367 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001368 if_false: else_block.map(|p| Box::new(p.1.into())),
1369 })
1370 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001371 }
1372
Michael Layzell734adb42017-06-07 16:58:31 -04001373 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001374 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001375 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001376 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001377 cond: expr_no_struct >>
1378 then_block: braces!(call!(Block::parse_within)) >>
1379 else_block: option!(else_block) >>
1380 (ExprIf {
1381 cond: Box::new(cond),
1382 if_true: Block {
1383 stmts: then_block.0,
1384 brace_token: then_block.1,
1385 },
1386 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001387 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001388 if_false: else_block.map(|p| Box::new(p.1.into())),
1389 })
1390 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001391 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001392
Michael Layzell734adb42017-06-07 16:58:31 -04001393 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001394 named!(else_block -> (Token![else], ExprKind), do_parse!(
1395 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001396 expr: alt!(
1397 syn!(ExprIf) => { ExprKind::If }
1398 |
1399 syn!(ExprIfLet) => { ExprKind::IfLet }
1400 |
1401 do_parse!(
1402 else_block: braces!(call!(Block::parse_within)) >>
1403 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001404 block: Block {
1405 stmts: else_block.0,
1406 brace_token: else_block.1,
1407 },
1408 }))
David Tolnay939766a2016-09-23 23:48:12 -07001409 )
Alex Crichton954046c2017-05-30 21:49:42 -07001410 ) >>
1411 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001412 ));
1413
Michael Layzell734adb42017-06-07 16:58:31 -04001414 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001415 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001416 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001417 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1418 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001419 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001420 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001421 expr: expr_no_struct >>
1422 loop_block: syn!(Block) >>
1423 (ExprForLoop {
1424 for_token: for_,
1425 in_token: in_,
1426 pat: Box::new(pat),
1427 expr: Box::new(expr),
1428 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001429 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001430 label: lbl.map(|p| p.0),
1431 })
1432 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001433 }
Gregory Katze5f35682016-09-27 14:20:55 -04001434
Michael Layzell734adb42017-06-07 16:58:31 -04001435 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001436 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001437 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001438 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1439 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001440 loop_block: syn!(Block) >>
1441 (ExprLoop {
1442 loop_token: loop_,
1443 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001444 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001445 label: lbl.map(|p| p.0),
1446 })
1447 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001448 }
1449
Michael Layzell734adb42017-06-07 16:58:31 -04001450 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001451 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001452 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001453 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001454 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001455 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001456 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001457 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001458 ExprMatch {
1459 expr: Box::new(obj),
1460 match_token: match_,
1461 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001462 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001463 }
1464 })
1465 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001466 }
David Tolnay1978c672016-10-27 22:05:52 -07001467
Michael Layzell734adb42017-06-07 16:58:31 -04001468 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001469 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001470 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001471 do_: keyword!(do) >>
1472 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001473 catch_block: syn!(Block) >>
1474 (ExprCatch {
1475 block: catch_block,
1476 do_token: do_,
1477 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001478 })
Michael Layzell92639a52017-06-01 00:07:44 -04001479 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001480 }
Arnavion02ef13f2017-04-25 00:54:31 -07001481
Michael Layzell734adb42017-06-07 16:58:31 -04001482 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001483 impl Synom for ExprYield {
1484 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001485 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001486 expr: option!(syn!(Expr)) >>
1487 (ExprYield {
1488 yield_token: yield_,
1489 expr: expr.map(Box::new),
1490 })
1491 ));
1492 }
1493
1494 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001495 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001496 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001497 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001498 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001499 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1500 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001501 body: do_parse!(
1502 expr: alt!(expr_nosemi | syn!(Expr)) >>
1503 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1504 map!(input_end!(), |_| None)
1505 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001506 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001507 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001508 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001509 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001510 ) >>
1511 (Arm {
1512 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001513 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001514 attrs: attrs,
1515 pats: pats,
1516 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001517 body: Box::new(body.0),
1518 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001519 })
1520 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001521 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001522
Michael Layzell734adb42017-06-07 16:58:31 -04001523 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001524 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001525 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001526 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001527 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001528 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001529 ret_and_body: alt!(
1530 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001531 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001532 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001533 body: syn!(Block) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -05001534 (ReturnType::Type(arrow, Box::new(ty)),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001535 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001536 block: body,
1537 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001538 )
1539 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001540 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001541 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001542 (ExprClosure {
1543 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001544 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001545 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001546 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001547 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001548 body: Box::new(ret_and_body.1),
1549 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001550 ));
1551
Michael Layzell734adb42017-06-07 16:58:31 -04001552 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001553 named!(fn_arg -> FnArg, do_parse!(
1554 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001555 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001556 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001557 if let Some((colon, ty)) = ty {
1558 FnArg::Captured(ArgCaptured {
1559 pat: pat,
1560 colon_token: colon,
1561 ty: ty,
1562 })
1563 } else {
1564 FnArg::Inferred(pat)
1565 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001566 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001567 ));
1568
Michael Layzell734adb42017-06-07 16:58:31 -04001569 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001570 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001571 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001572 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1573 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001574 cond: expr_no_struct >>
1575 while_block: syn!(Block) >>
1576 (ExprWhile {
1577 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001578 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001579 cond: Box::new(cond),
1580 body: while_block,
1581 label: lbl.map(|p| p.0),
1582 })
1583 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001584 }
1585
Michael Layzell734adb42017-06-07 16:58:31 -04001586 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001587 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001588 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001589 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1590 while_: keyword!(while) >>
1591 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001592 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001593 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001594 value: expr_no_struct >>
1595 while_block: syn!(Block) >>
1596 (ExprWhileLet {
1597 eq_token: eq,
1598 let_token: let_,
1599 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001600 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001601 pat: Box::new(pat),
1602 expr: Box::new(value),
1603 body: while_block,
1604 label: lbl.map(|p| p.0),
1605 })
1606 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001607 }
1608
Michael Layzell734adb42017-06-07 16:58:31 -04001609 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001610 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001611 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001612 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001613 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001614 (ExprContinue {
1615 continue_token: cont,
1616 label: lbl,
1617 })
1618 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001619 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001620
Michael Layzell734adb42017-06-07 16:58:31 -04001621 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001622 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001623 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001624 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001625 // We can't allow blocks after a `break` expression when we wouldn't
1626 // allow structs, as this expression is ambiguous.
1627 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001628 (ExprBreak {
1629 label: lbl,
1630 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001631 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001632 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001633 ));
1634
Michael Layzell734adb42017-06-07 16:58:31 -04001635 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001636 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001637 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001638 // NOTE: return is greedy and eats blocks after it even when in a
1639 // position where structs are not allowed, such as in if statement
1640 // conditions. For example:
1641 //
David Tolnaybcf26022017-12-25 22:10:52 -05001642 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001643 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001644 (ExprRet {
1645 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001646 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001647 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001648 ));
1649
Michael Layzell734adb42017-06-07 16:58:31 -04001650 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001651 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001652 named!(parse -> Self, do_parse!(
1653 path: syn!(Path) >>
1654 data: braces!(do_parse!(
1655 fields: call!(Delimited::parse_terminated) >>
1656 base: option!(
1657 cond!(fields.is_empty() || fields.trailing_delim(),
1658 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001659 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001660 base: syn!(Expr) >>
1661 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001662 )
Michael Layzell92639a52017-06-01 00:07:44 -04001663 )
1664 ) >>
1665 (fields, base)
1666 )) >>
1667 ({
1668 let ((fields, base), brace) = data;
1669 let (dots, rest) = match base.and_then(|b| b) {
1670 Some((dots, base)) => (Some(dots), Some(base)),
1671 None => (None, None),
1672 };
1673 ExprStruct {
1674 brace_token: brace,
1675 path: path,
1676 fields: fields,
1677 dot2_token: dots,
1678 rest: rest.map(Box::new),
1679 }
1680 })
1681 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001682 }
1683
Michael Layzell734adb42017-06-07 16:58:31 -04001684 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001685 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001686 named!(parse -> Self, alt!(
1687 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001688 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001689 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001690 value: syn!(Expr) >>
1691 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001692 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001693 expr: value,
1694 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001695 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001696 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001697 })
Michael Layzell92639a52017-06-01 00:07:44 -04001698 )
1699 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001700 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001701 member: Member::Named(name),
Michael Layzell92639a52017-06-01 00:07:44 -04001702 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1703 is_shorthand: true,
1704 attrs: Vec::new(),
1705 colon_token: None,
1706 })
1707 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001708 }
David Tolnay055a7042016-10-02 19:23:54 -07001709
Michael Layzell734adb42017-06-07 16:58:31 -04001710 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001711 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001712 named!(parse -> Self, do_parse!(
1713 data: brackets!(do_parse!(
1714 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001715 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001716 times: syn!(Expr) >>
1717 (value, semi, times)
1718 )) >>
1719 (ExprRepeat {
1720 expr: Box::new((data.0).0),
1721 amt: Box::new((data.0).2),
1722 bracket_token: data.1,
1723 semi_token: (data.0).1,
1724 })
1725 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001726 }
David Tolnay055a7042016-10-02 19:23:54 -07001727
Michael Layzell734adb42017-06-07 16:58:31 -04001728 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001729 impl Synom for ExprUnsafe {
1730 named!(parse -> Self, do_parse!(
1731 unsafe_: keyword!(unsafe) >>
1732 b: syn!(Block) >>
1733 (ExprUnsafe {
1734 unsafe_token: unsafe_,
1735 block: b,
1736 })
1737 ));
1738 }
1739
1740 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001741 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001742 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001743 b: syn!(Block) >>
1744 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001745 block: b,
1746 })
1747 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001748 }
David Tolnay89e05672016-10-02 14:39:42 -07001749
Michael Layzell734adb42017-06-07 16:58:31 -04001750 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001751 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001752 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001753 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001754 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001755 ));
1756
Michael Layzell734adb42017-06-07 16:58:31 -04001757 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001758 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001759 named!(parse -> Self, alt!(
1760 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001761 punct!(..=) => { RangeLimits::Closed }
1762 |
1763 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001764 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001765 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001766 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001767 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001768 }
David Tolnay438c9052016-10-07 23:24:48 -07001769
Alex Crichton954046c2017-05-30 21:49:42 -07001770 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001771 named!(parse -> Self, do_parse!(
1772 pair: qpath >>
1773 (ExprPath {
1774 qself: pair.0,
1775 path: pair.1,
1776 })
1777 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001778 }
David Tolnay42602292016-10-01 22:25:45 -07001779
Michael Layzell734adb42017-06-07 16:58:31 -04001780 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001781 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001782
David Tolnay32954ef2017-12-26 22:43:16 -05001783 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001784
Michael Layzell734adb42017-06-07 16:58:31 -04001785 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001786 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001787 named!(parse -> Self, do_parse!(
1788 stmts: braces!(call!(Block::parse_within)) >>
1789 (Block {
1790 stmts: stmts.0,
1791 brace_token: stmts.1,
1792 })
1793 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001794 }
David Tolnay939766a2016-09-23 23:48:12 -07001795
Michael Layzell734adb42017-06-07 16:58:31 -04001796 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001797 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001798 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001799 many0!(punct!(;)) >>
1800 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001801 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001802 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001803 mut e: syn!(Expr) >>
1804 ({
1805 e.attrs = attrs;
1806 Stmt::Expr(Box::new(e))
1807 })
1808 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001809 (match last {
1810 None => standalone,
1811 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001812 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001813 standalone
1814 }
1815 })
1816 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001817 }
1818
Michael Layzell734adb42017-06-07 16:58:31 -04001819 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001820 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001821 named!(parse -> Self, alt!(
1822 stmt_mac
1823 |
1824 stmt_local
1825 |
1826 stmt_item
1827 |
Michael Layzell35418782017-06-07 09:20:25 -04001828 stmt_blockexpr
1829 |
Michael Layzell92639a52017-06-01 00:07:44 -04001830 stmt_expr
1831 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001832 }
David Tolnay939766a2016-09-23 23:48:12 -07001833
Michael Layzell734adb42017-06-07 16:58:31 -04001834 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001835 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001836 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001837 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001838 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001839 // Only parse braces here; paren and bracket will get parsed as
1840 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001841 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001842 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05001843 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
1844 attrs: attrs,
1845 ident: None,
1846 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001847 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001848 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001849 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001850 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001851 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001852 },
David Tolnayeea28d62016-10-25 20:44:08 -07001853 },
David Tolnay57b52bc2017-12-28 18:06:38 -05001854 semi_token: semi,
1855 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07001856 ));
1857
Michael Layzell734adb42017-06-07 16:58:31 -04001858 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001859 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001860 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001861 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001862 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001863 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001864 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1865 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001866 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001867 let_token: let_,
1868 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001869 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1870 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001871 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001872 ty: ty.map(|p| Box::new(p.1)),
1873 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001874 attrs: attrs,
1875 })))
1876 ));
1877
Michael Layzell734adb42017-06-07 16:58:31 -04001878 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001879 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001880
Michael Layzell734adb42017-06-07 16:58:31 -04001881 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001882 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001883 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04001884 mut e: expr_nosemi >>
1885 // If the next token is a `.` or a `?` it is special-cased to parse as
1886 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001887 not!(punct!(.)) >>
1888 not!(punct!(?)) >>
1889 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001890 ({
1891 e.attrs = attrs;
1892 if let Some(semi) = semi {
1893 Stmt::Semi(Box::new(e), semi)
1894 } else {
1895 Stmt::Expr(Box::new(e))
1896 }
1897 })
1898 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001899
Michael Layzell734adb42017-06-07 16:58:31 -04001900 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001901 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001902 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001903 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001904 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001905 ({
1906 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001907 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001908 })
David Tolnay939766a2016-09-23 23:48:12 -07001909 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001910
Michael Layzell734adb42017-06-07 16:58:31 -04001911 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001912 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001913 named!(parse -> Self, alt!(
1914 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1915 |
1916 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1917 |
1918 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1919 |
1920 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1921 |
1922 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1923 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001924 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001925 |
1926 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1927 |
1928 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1929 |
1930 syn!(PatPath) => { Pat::Path }
1931 |
1932 syn!(PatTuple) => { Pat::Tuple }
1933 |
1934 syn!(PatRef) => { Pat::Ref }
1935 |
1936 syn!(PatSlice) => { Pat::Slice }
1937 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001938 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001939
Michael Layzell734adb42017-06-07 16:58:31 -04001940 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001941 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001942 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001943 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001944 |u| PatWild { underscore_token: u }
1945 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001946 }
David Tolnay84aa0752016-10-02 23:01:13 -07001947
Michael Layzell734adb42017-06-07 16:58:31 -04001948 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001949 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001950 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001951 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001952 pat: syn!(Pat) >>
1953 (PatBox {
1954 pat: Box::new(pat),
1955 box_token: boxed,
1956 })
1957 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001958 }
1959
Michael Layzell734adb42017-06-07 16:58:31 -04001960 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001961 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001962 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001963 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001964 mutability: syn!(Mutability) >>
1965 name: alt!(
1966 syn!(Ident)
1967 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001968 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001969 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001970 not!(punct!(<)) >>
1971 not!(punct!(::)) >>
1972 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001973 (PatIdent {
1974 mode: match mode {
1975 Some(mode) => BindingMode::ByRef(mode, mutability),
1976 None => BindingMode::ByValue(mutability),
1977 },
1978 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001979 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001980 subpat: subpat.map(|p| Box::new(p.1)),
1981 })
1982 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001983 }
1984
Michael Layzell734adb42017-06-07 16:58:31 -04001985 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001986 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001987 named!(parse -> Self, do_parse!(
1988 path: syn!(Path) >>
1989 tuple: syn!(PatTuple) >>
1990 (PatTupleStruct {
1991 path: path,
1992 pat: tuple,
1993 })
1994 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001995 }
1996
Michael Layzell734adb42017-06-07 16:58:31 -04001997 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001998 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001999 named!(parse -> Self, do_parse!(
2000 path: syn!(Path) >>
2001 data: braces!(do_parse!(
2002 fields: call!(Delimited::parse_terminated) >>
2003 base: option!(
2004 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002005 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002006 ) >>
2007 (fields, base)
2008 )) >>
2009 (PatStruct {
2010 path: path,
2011 fields: (data.0).0,
2012 brace_token: data.1,
2013 dot2_token: (data.0).1.and_then(|m| m),
2014 })
2015 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002016 }
2017
Michael Layzell734adb42017-06-07 16:58:31 -04002018 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002019 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002020 named!(parse -> Self, alt!(
2021 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002022 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002023 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002024 pat: syn!(Pat) >>
2025 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002026 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002027 pat: Box::new(pat),
2028 is_shorthand: false,
2029 attrs: Vec::new(),
2030 colon_token: Some(colon),
2031 })
2032 )
2033 |
2034 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002035 boxed: option!(keyword!(box)) >>
2036 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002037 mutability: syn!(Mutability) >>
2038 ident: syn!(Ident) >>
2039 ({
2040 let mut pat: Pat = PatIdent {
2041 mode: if let Some(mode) = mode {
2042 BindingMode::ByRef(mode, mutability)
2043 } else {
2044 BindingMode::ByValue(mutability)
2045 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002046 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002047 subpat: None,
2048 at_token: None,
2049 }.into();
2050 if let Some(boxed) = boxed {
2051 pat = PatBox {
2052 pat: Box::new(pat),
2053 box_token: boxed,
2054 }.into();
2055 }
2056 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002057 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002058 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002059 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002060 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002061 colon_token: None,
2062 }
2063 })
2064 )
2065 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002066 }
2067
Michael Layzell734adb42017-06-07 16:58:31 -04002068 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002069 impl Synom for Member {
2070 named!(parse -> Self, alt!(
2071 syn!(Ident) => { Member::Named }
2072 |
2073 syn!(Index) => { Member::Unnamed }
2074 ));
2075 }
2076
2077 #[cfg(feature = "full")]
2078 impl Synom for Index {
2079 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002080 lit: syn!(Lit) >>
2081 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002082 if let Ok(i) = lit.value.to_string().parse() {
2083 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002084 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002085 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002086 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002087 })
David Tolnay85b69a42017-12-27 20:43:10 -05002088 ));
2089 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002090
Michael Layzell734adb42017-06-07 16:58:31 -04002091 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002092 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002093 named!(parse -> Self, map!(
2094 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002095 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002096 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002097 }
David Tolnay9636c052016-10-02 17:11:17 -07002098
Michael Layzell734adb42017-06-07 16:58:31 -04002099 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002100 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002101 named!(parse -> Self, do_parse!(
2102 data: parens!(do_parse!(
2103 elems: call!(Delimited::parse_terminated) >>
2104 dotdot: map!(cond!(
2105 elems.is_empty() || elems.trailing_delim(),
2106 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002107 dots: punct!(..) >>
2108 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002109 (dots, trailing)
2110 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002111 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002112 rest: cond!(match dotdot {
2113 Some((_, Some(_))) => true,
2114 _ => false,
2115 },
2116 call!(Delimited::parse_terminated)) >>
2117 (elems, dotdot, rest)
2118 )) >>
2119 ({
2120 let ((mut elems, dotdot, rest), parens) = data;
2121 let (dotdot, trailing) = match dotdot {
2122 Some((a, b)) => (Some(a), Some(b)),
2123 None => (None, None),
2124 };
2125 PatTuple {
2126 paren_token: parens,
2127 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2128 dot2_token: dotdot,
2129 comma_token: trailing.and_then(|b| b),
2130 pats: {
2131 if let Some(rest) = rest {
2132 for elem in rest {
2133 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002134 }
Michael Layzell92639a52017-06-01 00:07:44 -04002135 }
2136 elems
2137 },
2138 }
2139 })
2140 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002141 }
David Tolnayfbb73232016-10-03 01:00:06 -07002142
Michael Layzell734adb42017-06-07 16:58:31 -04002143 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002144 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002145 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002146 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002147 mutability: syn!(Mutability) >>
2148 pat: syn!(Pat) >>
2149 (PatRef {
2150 pat: Box::new(pat),
2151 mutbl: mutability,
2152 and_token: and,
2153 })
2154 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002155 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002156
Michael Layzell734adb42017-06-07 16:58:31 -04002157 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002158 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002159 named!(parse -> Self, do_parse!(
2160 lit: pat_lit_expr >>
2161 (if let ExprKind::Path(_) = lit.node {
2162 return parse_error(); // these need to be parsed by pat_path
2163 } else {
2164 PatLit {
2165 expr: Box::new(lit),
2166 }
2167 })
2168 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002169 }
David Tolnaye1310902016-10-29 23:40:00 -07002170
Michael Layzell734adb42017-06-07 16:58:31 -04002171 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002172 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002173 named!(parse -> Self, do_parse!(
2174 lo: pat_lit_expr >>
2175 limits: syn!(RangeLimits) >>
2176 hi: pat_lit_expr >>
2177 (PatRange {
2178 lo: Box::new(lo),
2179 hi: Box::new(hi),
2180 limits: limits,
2181 })
2182 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002183 }
David Tolnaye1310902016-10-29 23:40:00 -07002184
Michael Layzell734adb42017-06-07 16:58:31 -04002185 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002186 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002187 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002188 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002189 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002190 |
Alex Crichton954046c2017-05-30 21:49:42 -07002191 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002192 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002193 (if let Some(neg) = neg {
Alex Crichton62a0a592017-05-22 13:58:53 -07002194 ExprKind::Unary(ExprUnary {
David Tolnayc29b9892017-12-27 22:58:14 -05002195 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002196 expr: Box::new(v.into())
2197 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002198 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002199 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002200 })
2201 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002202
Michael Layzell734adb42017-06-07 16:58:31 -04002203 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002204 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002205 named!(parse -> Self, map!(
2206 brackets!(do_parse!(
2207 before: call!(Delimited::parse_terminated) >>
2208 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002209 dots: punct!(..) >>
2210 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002211 (dots, trailing)
2212 )) >>
2213 after: cond!(
2214 match middle {
2215 Some((_, ref trailing)) => trailing.is_some(),
2216 _ => false,
2217 },
2218 call!(Delimited::parse_terminated)
2219 ) >>
2220 (before, middle, after)
2221 )),
2222 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002223 let mut before: Delimited<Pat, Token![,]> = before;
2224 let after: Option<Delimited<Pat, Token![,]>> = after;
2225 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002226 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002227 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002228 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002229 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002230 }),
2231 bracket_token: brackets,
2232 middle: middle.and_then(|_| {
2233 if !before.is_empty() && !before.trailing_delim() {
2234 Some(Box::new(before.pop().unwrap().into_item()))
2235 } else {
2236 None
2237 }
2238 }),
2239 front: before,
2240 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002241 }
Alex Crichton954046c2017-05-30 21:49:42 -07002242 }
Michael Layzell92639a52017-06-01 00:07:44 -04002243 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002244 }
David Tolnay435a9a82016-10-29 13:47:20 -07002245
Michael Layzell734adb42017-06-07 16:58:31 -04002246 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002247 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002248 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002249 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002250 |
2251 epsilon!() => { |_| CaptureBy::Ref }
2252 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002253 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002254}
2255
David Tolnayf4bbbd92016-09-23 14:41:55 -07002256#[cfg(feature = "printing")]
2257mod printing {
2258 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002259 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002260 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002261 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002262 #[cfg(feature = "full")]
2263 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002264
David Tolnaybcf26022017-12-25 22:10:52 -05002265 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2266 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002267 #[cfg(feature = "full")]
2268 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2269 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002270 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002271 e.to_tokens(tokens);
2272 });
2273 } else {
2274 e.to_tokens(tokens);
2275 }
2276 }
2277
David Tolnayf4bbbd92016-09-23 14:41:55 -07002278 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002279 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002280 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002281 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002282 self.node.to_tokens(tokens)
2283 }
Michael Layzell734adb42017-06-07 16:58:31 -04002284
2285 #[cfg(not(feature = "full"))]
2286 fn to_tokens(&self, tokens: &mut Tokens) {
2287 self.node.to_tokens(tokens)
2288 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002289 }
2290
Michael Layzell734adb42017-06-07 16:58:31 -04002291 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002292 impl ToTokens for ExprBox {
2293 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002294 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002295 self.expr.to_tokens(tokens);
2296 }
2297 }
2298
Michael Layzell734adb42017-06-07 16:58:31 -04002299 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002300 impl ToTokens for ExprInPlace {
2301 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002302 match self.kind {
2303 InPlaceKind::Arrow(ref arrow) => {
2304 self.place.to_tokens(tokens);
2305 arrow.to_tokens(tokens);
2306 self.value.to_tokens(tokens);
2307 }
2308 InPlaceKind::In(ref _in) => {
2309 _in.to_tokens(tokens);
2310 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002311 // NOTE: The second operand must be in a block, add one if
2312 // it is not present.
2313 if let ExprKind::Block(_) = self.value.node {
2314 self.value.to_tokens(tokens);
2315 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002316 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002317 self.value.to_tokens(tokens);
2318 })
2319 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002320 }
2321 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002322 }
2323 }
2324
Michael Layzell734adb42017-06-07 16:58:31 -04002325 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002326 impl ToTokens for ExprArray {
2327 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002328 self.bracket_token.surround(tokens, |tokens| {
2329 self.exprs.to_tokens(tokens);
2330 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002331 }
2332 }
2333
2334 impl ToTokens for ExprCall {
2335 fn to_tokens(&self, tokens: &mut Tokens) {
2336 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002337 self.paren_token.surround(tokens, |tokens| {
2338 self.args.to_tokens(tokens);
2339 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002340 }
2341 }
2342
Michael Layzell734adb42017-06-07 16:58:31 -04002343 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002344 impl ToTokens for ExprMethodCall {
2345 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002346 self.expr.to_tokens(tokens);
2347 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002348 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002349 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002350 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2351 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002352 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002353 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002354 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002355 self.paren_token.surround(tokens, |tokens| {
2356 self.args.to_tokens(tokens);
2357 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002358 }
2359 }
2360
Michael Layzell734adb42017-06-07 16:58:31 -04002361 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002362 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002363 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002364 self.paren_token.surround(tokens, |tokens| {
2365 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002366 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002367 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002368 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002369 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002370 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002371 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002372 }
2373 }
2374
2375 impl ToTokens for ExprBinary {
2376 fn to_tokens(&self, tokens: &mut Tokens) {
2377 self.left.to_tokens(tokens);
2378 self.op.to_tokens(tokens);
2379 self.right.to_tokens(tokens);
2380 }
2381 }
2382
2383 impl ToTokens for ExprUnary {
2384 fn to_tokens(&self, tokens: &mut Tokens) {
2385 self.op.to_tokens(tokens);
2386 self.expr.to_tokens(tokens);
2387 }
2388 }
2389
2390 impl ToTokens for ExprCast {
2391 fn to_tokens(&self, tokens: &mut Tokens) {
2392 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002393 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002394 self.ty.to_tokens(tokens);
2395 }
2396 }
2397
2398 impl ToTokens for ExprType {
2399 fn to_tokens(&self, tokens: &mut Tokens) {
2400 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002401 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002402 self.ty.to_tokens(tokens);
2403 }
2404 }
2405
Michael Layzell734adb42017-06-07 16:58:31 -04002406 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002407 fn maybe_wrap_else(
2408 tokens: &mut Tokens,
2409 else_token: &Option<Token![else]>,
2410 if_false: &Option<Box<Expr>>,
2411 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002412 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002413 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002414
2415 // If we are not one of the valid expressions to exist in an else
2416 // clause, wrap ourselves in a block.
2417 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002418 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002419 if_false.to_tokens(tokens);
2420 }
2421 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002422 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002423 if_false.to_tokens(tokens);
2424 });
2425 }
2426 }
2427 }
2428 }
2429
2430 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002431 impl ToTokens for ExprIf {
2432 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002433 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002434 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002435 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002436 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002437 }
2438 }
2439
Michael Layzell734adb42017-06-07 16:58:31 -04002440 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002441 impl ToTokens for ExprIfLet {
2442 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002443 self.if_token.to_tokens(tokens);
2444 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002445 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002446 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002447 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002448 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002449 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002450 }
2451 }
2452
Michael Layzell734adb42017-06-07 16:58:31 -04002453 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002454 impl ToTokens for ExprWhile {
2455 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002456 if self.label.is_some() {
2457 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002458 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002459 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002460 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002461 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002462 self.body.to_tokens(tokens);
2463 }
2464 }
2465
Michael Layzell734adb42017-06-07 16:58:31 -04002466 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 impl ToTokens for ExprWhileLet {
2468 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002469 if self.label.is_some() {
2470 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002471 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002472 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002473 self.while_token.to_tokens(tokens);
2474 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002475 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002476 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002477 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002478 self.body.to_tokens(tokens);
2479 }
2480 }
2481
Michael Layzell734adb42017-06-07 16:58:31 -04002482 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002483 impl ToTokens for ExprForLoop {
2484 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002485 if self.label.is_some() {
2486 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002487 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002488 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002489 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002490 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002491 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002492 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002493 self.body.to_tokens(tokens);
2494 }
2495 }
2496
Michael Layzell734adb42017-06-07 16:58:31 -04002497 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002498 impl ToTokens for ExprLoop {
2499 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002500 if self.label.is_some() {
2501 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002502 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002503 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002504 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002505 self.body.to_tokens(tokens);
2506 }
2507 }
2508
Michael Layzell734adb42017-06-07 16:58:31 -04002509 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002510 impl ToTokens for ExprMatch {
2511 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002512 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002513 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002514 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002515 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002516 arm.to_tokens(tokens);
2517 // Ensure that we have a comma after a non-block arm, except
2518 // for the last one.
2519 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002520 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002521 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002522 }
2523 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002524 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002525 }
2526 }
2527
Michael Layzell734adb42017-06-07 16:58:31 -04002528 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002529 impl ToTokens for ExprCatch {
2530 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002531 self.do_token.to_tokens(tokens);
2532 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002533 self.block.to_tokens(tokens);
2534 }
2535 }
2536
Michael Layzell734adb42017-06-07 16:58:31 -04002537 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002538 impl ToTokens for ExprYield {
2539 fn to_tokens(&self, tokens: &mut Tokens) {
2540 self.yield_token.to_tokens(tokens);
2541 self.expr.to_tokens(tokens);
2542 }
2543 }
2544
2545 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002546 impl ToTokens for ExprClosure {
2547 fn to_tokens(&self, tokens: &mut Tokens) {
2548 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002549 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002550 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002551 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002552 FnArg::Captured(ArgCaptured {
2553 ref pat,
2554 ty: Type::Infer(_),
2555 ..
2556 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002557 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002558 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002559 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002560 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002561 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002562 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002563 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002564 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002565 self.body.to_tokens(tokens);
2566 }
2567 }
2568
Michael Layzell734adb42017-06-07 16:58:31 -04002569 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002570 impl ToTokens for ExprUnsafe {
2571 fn to_tokens(&self, tokens: &mut Tokens) {
2572 self.unsafe_token.to_tokens(tokens);
2573 self.block.to_tokens(tokens);
2574 }
2575 }
2576
2577 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002578 impl ToTokens for ExprBlock {
2579 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002580 self.block.to_tokens(tokens);
2581 }
2582 }
2583
Michael Layzell734adb42017-06-07 16:58:31 -04002584 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002585 impl ToTokens for ExprAssign {
2586 fn to_tokens(&self, tokens: &mut Tokens) {
2587 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002588 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002589 self.right.to_tokens(tokens);
2590 }
2591 }
2592
Michael Layzell734adb42017-06-07 16:58:31 -04002593 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002594 impl ToTokens for ExprAssignOp {
2595 fn to_tokens(&self, tokens: &mut Tokens) {
2596 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002597 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002598 self.right.to_tokens(tokens);
2599 }
2600 }
2601
Michael Layzell734adb42017-06-07 16:58:31 -04002602 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002603 impl ToTokens for ExprField {
2604 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002605 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002606 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002607 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002608 }
2609 }
2610
Michael Layzell734adb42017-06-07 16:58:31 -04002611 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002612 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002614 match *self {
2615 Member::Named(ident) => ident.to_tokens(tokens),
2616 Member::Unnamed(ref index) => index.to_tokens(tokens),
2617 }
2618 }
2619 }
2620
2621 #[cfg(feature = "full")]
2622 impl ToTokens for Index {
2623 fn to_tokens(&self, tokens: &mut Tokens) {
2624 tokens.append(TokenTree {
2625 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002626 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002627 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002628 }
2629 }
2630
2631 impl ToTokens for ExprIndex {
2632 fn to_tokens(&self, tokens: &mut Tokens) {
2633 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002634 self.bracket_token.surround(tokens, |tokens| {
2635 self.index.to_tokens(tokens);
2636 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002637 }
2638 }
2639
Michael Layzell734adb42017-06-07 16:58:31 -04002640 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002641 impl ToTokens for ExprRange {
2642 fn to_tokens(&self, tokens: &mut Tokens) {
2643 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002644 match self.limits {
2645 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2646 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2647 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002648 self.to.to_tokens(tokens);
2649 }
2650 }
2651
2652 impl ToTokens for ExprPath {
2653 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002654 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002655 }
2656 }
2657
Michael Layzell734adb42017-06-07 16:58:31 -04002658 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002659 impl ToTokens for ExprAddrOf {
2660 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002661 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002662 self.mutbl.to_tokens(tokens);
2663 self.expr.to_tokens(tokens);
2664 }
2665 }
2666
Michael Layzell734adb42017-06-07 16:58:31 -04002667 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002668 impl ToTokens for ExprBreak {
2669 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002670 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 self.label.to_tokens(tokens);
2672 self.expr.to_tokens(tokens);
2673 }
2674 }
2675
Michael Layzell734adb42017-06-07 16:58:31 -04002676 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002677 impl ToTokens for ExprContinue {
2678 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002679 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002680 self.label.to_tokens(tokens);
2681 }
2682 }
2683
Michael Layzell734adb42017-06-07 16:58:31 -04002684 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002685 impl ToTokens for ExprRet {
2686 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002687 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002688 self.expr.to_tokens(tokens);
2689 }
2690 }
2691
Michael Layzell734adb42017-06-07 16:58:31 -04002692 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002693 impl ToTokens for ExprStruct {
2694 fn to_tokens(&self, tokens: &mut Tokens) {
2695 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002696 self.brace_token.surround(tokens, |tokens| {
2697 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002698 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002699 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002700 self.rest.to_tokens(tokens);
2701 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002702 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002703 }
2704 }
2705
Michael Layzell734adb42017-06-07 16:58:31 -04002706 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002707 impl ToTokens for ExprRepeat {
2708 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002709 self.bracket_token.surround(tokens, |tokens| {
2710 self.expr.to_tokens(tokens);
2711 self.semi_token.to_tokens(tokens);
2712 self.amt.to_tokens(tokens);
2713 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002714 }
2715 }
2716
Michael Layzell93c36282017-06-04 20:43:14 -04002717 impl ToTokens for ExprGroup {
2718 fn to_tokens(&self, tokens: &mut Tokens) {
2719 self.group_token.surround(tokens, |tokens| {
2720 self.expr.to_tokens(tokens);
2721 });
2722 }
2723 }
2724
Alex Crichton62a0a592017-05-22 13:58:53 -07002725 impl ToTokens for ExprParen {
2726 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002727 self.paren_token.surround(tokens, |tokens| {
2728 self.expr.to_tokens(tokens);
2729 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002730 }
2731 }
2732
Michael Layzell734adb42017-06-07 16:58:31 -04002733 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002734 impl ToTokens for ExprTry {
2735 fn to_tokens(&self, tokens: &mut Tokens) {
2736 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002737 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002738 }
2739 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002740
Michael Layzell734adb42017-06-07 16:58:31 -04002741 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002742 impl ToTokens for FieldValue {
2743 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002744 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002745 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2746 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002747 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002748 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002749 self.expr.to_tokens(tokens);
2750 }
David Tolnay055a7042016-10-02 19:23:54 -07002751 }
2752 }
2753
Michael Layzell734adb42017-06-07 16:58:31 -04002754 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002755 impl ToTokens for Arm {
2756 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002757 tokens.append_all(&self.attrs);
2758 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002759 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002760 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002761 self.guard.to_tokens(tokens);
2762 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002763 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002764 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002765 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002766 }
2767 }
2768
Michael Layzell734adb42017-06-07 16:58:31 -04002769 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002770 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002771 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002772 self.underscore_token.to_tokens(tokens);
2773 }
2774 }
2775
Michael Layzell734adb42017-06-07 16:58:31 -04002776 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002777 impl ToTokens for PatIdent {
2778 fn to_tokens(&self, tokens: &mut Tokens) {
2779 self.mode.to_tokens(tokens);
2780 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002781 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002782 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002783 self.subpat.to_tokens(tokens);
2784 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002785 }
2786 }
2787
Michael Layzell734adb42017-06-07 16:58:31 -04002788 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002789 impl ToTokens for PatStruct {
2790 fn to_tokens(&self, tokens: &mut Tokens) {
2791 self.path.to_tokens(tokens);
2792 self.brace_token.surround(tokens, |tokens| {
2793 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002794 // NOTE: We need a comma before the dot2 token if it is present.
2795 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002796 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002797 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002798 self.dot2_token.to_tokens(tokens);
2799 });
2800 }
2801 }
2802
Michael Layzell734adb42017-06-07 16:58:31 -04002803 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002804 impl ToTokens for PatTupleStruct {
2805 fn to_tokens(&self, tokens: &mut Tokens) {
2806 self.path.to_tokens(tokens);
2807 self.pat.to_tokens(tokens);
2808 }
2809 }
2810
Michael Layzell734adb42017-06-07 16:58:31 -04002811 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002812 impl ToTokens for PatPath {
2813 fn to_tokens(&self, tokens: &mut Tokens) {
2814 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2815 }
2816 }
2817
Michael Layzell734adb42017-06-07 16:58:31 -04002818 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002819 impl ToTokens for PatTuple {
2820 fn to_tokens(&self, tokens: &mut Tokens) {
2821 self.paren_token.surround(tokens, |tokens| {
2822 for (i, token) in self.pats.iter().enumerate() {
2823 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002824 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2825 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002826 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002827 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002828 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002829
2830 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002831 // Ensure there is a comma before the .. token.
2832 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002833 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002834 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002835 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002836 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002837 });
2838 }
2839 }
2840
Michael Layzell734adb42017-06-07 16:58:31 -04002841 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002842 impl ToTokens for PatBox {
2843 fn to_tokens(&self, tokens: &mut Tokens) {
2844 self.box_token.to_tokens(tokens);
2845 self.pat.to_tokens(tokens);
2846 }
2847 }
2848
Michael Layzell734adb42017-06-07 16:58:31 -04002849 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002850 impl ToTokens for PatRef {
2851 fn to_tokens(&self, tokens: &mut Tokens) {
2852 self.and_token.to_tokens(tokens);
2853 self.mutbl.to_tokens(tokens);
2854 self.pat.to_tokens(tokens);
2855 }
2856 }
2857
Michael Layzell734adb42017-06-07 16:58:31 -04002858 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002859 impl ToTokens for PatLit {
2860 fn to_tokens(&self, tokens: &mut Tokens) {
2861 self.expr.to_tokens(tokens);
2862 }
2863 }
2864
Michael Layzell734adb42017-06-07 16:58:31 -04002865 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002866 impl ToTokens for PatRange {
2867 fn to_tokens(&self, tokens: &mut Tokens) {
2868 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002869 match self.limits {
2870 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2871 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2872 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002873 self.hi.to_tokens(tokens);
2874 }
2875 }
2876
Michael Layzell734adb42017-06-07 16:58:31 -04002877 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002878 impl ToTokens for PatSlice {
2879 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002880 // XXX: This is a mess, and it will be so easy to screw it up. How
2881 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002882 self.bracket_token.surround(tokens, |tokens| {
2883 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002884
2885 // If we need a comma before the middle or standalone .. token,
2886 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002887 if !self.front.empty_or_trailing()
2888 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002889 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002890 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002891 }
2892
2893 // If we have an identifier, we always need a .. token.
2894 if self.middle.is_some() {
2895 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002896 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002897 } else if self.dot2_token.is_some() {
2898 self.dot2_token.to_tokens(tokens);
2899 }
2900
2901 // Make sure we have a comma before the back half.
2902 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002903 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002904 self.back.to_tokens(tokens);
2905 } else {
2906 self.comma_token.to_tokens(tokens);
2907 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002908 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002909 }
2910 }
2911
Michael Layzell734adb42017-06-07 16:58:31 -04002912 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002913 impl ToTokens for FieldPat {
2914 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002915 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002916 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05002917 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002918 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002919 }
2920 self.pat.to_tokens(tokens);
2921 }
2922 }
2923
Michael Layzell734adb42017-06-07 16:58:31 -04002924 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002925 impl ToTokens for BindingMode {
2926 fn to_tokens(&self, tokens: &mut Tokens) {
2927 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002928 BindingMode::ByRef(ref t, ref m) => {
2929 t.to_tokens(tokens);
2930 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002931 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002932 BindingMode::ByValue(ref m) => {
2933 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002934 }
2935 }
2936 }
2937 }
David Tolnay42602292016-10-01 22:25:45 -07002938
Michael Layzell734adb42017-06-07 16:58:31 -04002939 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002940 impl ToTokens for CaptureBy {
2941 fn to_tokens(&self, tokens: &mut Tokens) {
2942 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002943 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002944 CaptureBy::Ref => {
2945 // nothing
2946 }
David Tolnay89e05672016-10-02 14:39:42 -07002947 }
2948 }
2949 }
2950
Michael Layzell734adb42017-06-07 16:58:31 -04002951 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002952 impl ToTokens for Block {
2953 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002954 self.brace_token.surround(tokens, |tokens| {
2955 tokens.append_all(&self.stmts);
2956 });
David Tolnay42602292016-10-01 22:25:45 -07002957 }
2958 }
2959
Michael Layzell734adb42017-06-07 16:58:31 -04002960 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002961 impl ToTokens for Stmt {
2962 fn to_tokens(&self, tokens: &mut Tokens) {
2963 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002964 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002965 Stmt::Item(ref item) => item.to_tokens(tokens),
2966 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002967 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002968 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002969 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002970 }
David Tolnay42602292016-10-01 22:25:45 -07002971 }
2972 }
2973 }
David Tolnay191e0582016-10-02 18:31:09 -07002974
Michael Layzell734adb42017-06-07 16:58:31 -04002975 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002976 impl ToTokens for Local {
2977 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002978 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002979 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002980 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002981 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002982 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002983 self.ty.to_tokens(tokens);
2984 }
2985 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002986 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002987 self.init.to_tokens(tokens);
2988 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002989 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002990 }
2991 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002992}