blob: 6f81edb71f690c87f65dc33fc5d65db96a2285a5 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080029 pub box_token: Token![box],
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080041 pub exprs: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050042 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080048 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050049 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080055 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// (within the angle brackets).
57 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
59 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080063 pub typarams: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080064 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050065 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080066 pub dot_token: Token![.],
67 pub lt_token: Option<Token![<]>,
68 pub colon2_token: Option<Token![::]>,
69 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050073 pub Tuple(ExprTuple #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080074 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050075 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080076 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080098 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080099 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// A type ascription, e.g. `foo: f64`.
103 pub Type(ExprType {
104 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800105 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800106 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700107 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500108
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 /// An `if` block, with an optional else block
110 ///
111 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800116 pub if_token: Token![if],
117 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800130 pub if_token: Token![if],
131 pub let_token: Token![let],
132 pub eq_token: Token![=],
133 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800143 pub colon_token: Option<Token![:]>,
144 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
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],
160 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800173 pub for_token: Token![for],
174 pub colon_token: Option<Token![:]>,
175 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800184 pub loop_token: Token![loop],
185 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800190 pub match_token: Token![match],
David Tolnay32954ef2017-12-26 22:43:16 -0500191 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800201 pub or1_token: Token![|],
202 pub or2_token: Token![|],
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Nika Layzell640832a2017-12-04 13:37:09 -0500205 /// An unsafe block (`unsafe { ... }`)
206 pub Unsafe(ExprUnsafe #full {
207 pub unsafe_token: Token![unsafe],
208 pub block: Block,
209 }),
210
211 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub block: Block,
214 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700215
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400217 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 pub left: Box<Expr>,
219 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800220 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700221 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500222
Alex Crichton62a0a592017-05-22 13:58:53 -0700223 /// An assignment with an operator
224 ///
225 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400226 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 pub op: BinOp,
228 pub left: Box<Expr>,
229 pub right: Box<Expr>,
230 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500231
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 /// Access of a named struct field (`obj.foo`)
Michael Layzell734adb42017-06-07 16:58:31 -0400233 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 pub expr: Box<Expr>,
235 pub field: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800236 pub dot_token: Token![.],
Alex Crichton62a0a592017-05-22 13:58:53 -0700237 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500238
Alex Crichton62a0a592017-05-22 13:58:53 -0700239 /// Access of an unnamed field of a struct or tuple-struct
240 ///
241 /// For example, `foo.0`.
Michael Layzell734adb42017-06-07 16:58:31 -0400242 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700244 pub field: Lit,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800245 pub dot_token: Token![.],
Alex Crichton62a0a592017-05-22 13:58:53 -0700246 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500247
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 /// An indexing operation (`foo[2]`)
249 pub Index(ExprIndex {
250 pub expr: Box<Expr>,
251 pub index: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500252 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500254
David Tolnaybe55d7b2017-12-17 23:41:20 -0800255 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400256 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 pub from: Option<Box<Expr>>,
258 pub to: Option<Box<Expr>>,
259 pub limits: RangeLimits,
260 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700261
Alex Crichton62a0a592017-05-22 13:58:53 -0700262 /// Variable reference, possibly containing `::` and/or type
263 /// parameters, e.g. foo::bar::<baz>.
264 ///
265 /// Optionally "qualified",
266 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
267 pub Path(ExprPath {
268 pub qself: Option<QSelf>,
269 pub path: Path,
270 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700271
Alex Crichton62a0a592017-05-22 13:58:53 -0700272 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400273 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800274 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 pub mutbl: Mutability,
276 pub expr: Box<Expr>,
277 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500278
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400280 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700281 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800283 pub break_token: Token![break],
Alex Crichton62a0a592017-05-22 13:58:53 -0700284 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500285
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400287 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700288 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800289 pub continue_token: Token![continue],
Alex Crichton62a0a592017-05-22 13:58:53 -0700290 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500291
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400293 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800295 pub return_token: Token![return],
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700297
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800299 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700300
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 /// A struct literal expression.
302 ///
303 /// For example, `Foo {x: 1, y: 2}`, or
304 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400305 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800307 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800309 pub dot2_token: Option<Token![..]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500310 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700311 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700312
Alex Crichton62a0a592017-05-22 13:58:53 -0700313 /// An array literal constructed from one repeated element.
314 ///
315 /// For example, `[1; 5]`. The first expression is the element
316 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400317 pub Repeat(ExprRepeat #full {
David Tolnay32954ef2017-12-26 22:43:16 -0500318 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800319 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 pub expr: Box<Expr>,
321 pub amt: Box<Expr>,
322 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700323
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 /// No-op: used solely so we can pretty-print faithfully
325 pub Paren(ExprParen {
326 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500327 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700328 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700329
Michael Layzell93c36282017-06-04 20:43:14 -0400330 /// No-op: used solely so we can pretty-print faithfully
331 ///
332 /// A `group` represents a `None`-delimited span in the input
333 /// `TokenStream` which affects the precidence of the resulting
334 /// expression. They are used for macro hygiene.
335 pub Group(ExprGroup {
336 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500337 pub group_token: token::Group,
Michael Layzell93c36282017-06-04 20:43:14 -0400338 }),
339
Alex Crichton62a0a592017-05-22 13:58:53 -0700340 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400341 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800343 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700344 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700345
Alex Crichton62a0a592017-05-22 13:58:53 -0700346 /// A catch expression.
347 ///
348 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400349 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800350 pub do_token: Token![do],
351 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700352 pub block: Block,
353 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700354
355 /// A yield expression.
356 ///
357 /// E.g. `yield expr`
358 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800359 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700360 pub expr: Option<Box<Expr>>,
361 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700362 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700363}
364
Michael Layzell734adb42017-06-07 16:58:31 -0400365#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700366ast_struct! {
367 /// A field-value pair in a struct literal.
368 pub struct FieldValue {
369 /// Name of the field.
370 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500371
Alex Crichton62a0a592017-05-22 13:58:53 -0700372 /// Value of the field.
373 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500374
Alex Crichton62a0a592017-05-22 13:58:53 -0700375 /// Whether this is a shorthand field, e.g. `Struct { x }`
376 /// instead of `Struct { x: x }`.
377 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500378
Alex Crichton62a0a592017-05-22 13:58:53 -0700379 /// Attributes tagged on the field.
380 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700381
David Tolnayf8db7ba2017-11-11 22:52:16 -0800382 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700383 }
David Tolnay055a7042016-10-02 19:23:54 -0700384}
385
Michael Layzell734adb42017-06-07 16:58:31 -0400386#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700387ast_struct! {
388 /// A Block (`{ .. }`).
389 ///
390 /// E.g. `{ .. }` as in `fn foo() { .. }`
391 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500392 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700393 /// Statements in a block
394 pub stmts: Vec<Stmt>,
395 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700396}
397
Michael Layzell734adb42017-06-07 16:58:31 -0400398#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700399ast_enum! {
400 /// A statement, usually ending in a semicolon.
401 pub enum Stmt {
402 /// A local (let) binding.
403 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700404
Alex Crichton62a0a592017-05-22 13:58:53 -0700405 /// An item definition.
406 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700407
Alex Crichton62a0a592017-05-22 13:58:53 -0700408 /// Expr without trailing semicolon.
409 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800412 Semi(Box<Expr>, Token![;]),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// Macro invocation.
David Tolnaydecf28d2017-11-11 11:56:45 -0800415 Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700416 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700417}
418
Michael Layzell734adb42017-06-07 16:58:31 -0400419#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700420ast_enum! {
421 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700422 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 pub enum MacStmtStyle {
424 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
425 /// `foo!(...);`, `foo![...];`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800426 Semicolon(Token![;]),
Clar Charrd22b5702017-03-10 15:24:56 -0500427
Alex Crichton62a0a592017-05-22 13:58:53 -0700428 /// The macro statement had braces; e.g. foo! { ... }
429 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500430
Alex Crichton62a0a592017-05-22 13:58:53 -0700431 /// The macro statement had parentheses or brackets and no semicolon; e.g.
432 /// `foo!(...)`. All of these will end up being converted into macro
433 /// expressions.
434 NoBraces,
435 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700436}
437
Michael Layzell734adb42017-06-07 16:58:31 -0400438#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700439ast_struct! {
440 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
441 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800442 pub let_token: Token![let],
443 pub colon_token: Option<Token![:]>,
444 pub eq_token: Option<Token![=]>,
445 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700446
Alex Crichton62a0a592017-05-22 13:58:53 -0700447 pub pat: Box<Pat>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800448 pub ty: Option<Box<Type>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500449
Alex Crichton62a0a592017-05-22 13:58:53 -0700450 /// Initializer expression to set the value, if any
451 pub init: Option<Box<Expr>>,
452 pub attrs: Vec<Attribute>,
453 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700454}
455
Michael Layzell734adb42017-06-07 16:58:31 -0400456#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700457ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700458 // Clippy false positive
459 // https://github.com/Manishearth/rust-clippy/issues/1241
460 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
461 pub enum Pat {
462 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700463 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800464 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700465 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700466
Alex Crichton62a0a592017-05-22 13:58:53 -0700467 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
468 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
469 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
470 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700471 pub Ident(PatIdent {
472 pub mode: BindingMode,
473 pub ident: Ident,
474 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800475 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700476 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700477
Alex Crichton62a0a592017-05-22 13:58:53 -0700478 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
479 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480 pub Struct(PatStruct {
481 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800482 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500483 pub brace_token: token::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800484 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700486
Alex Crichton62a0a592017-05-22 13:58:53 -0700487 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
488 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
489 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700490 pub TupleStruct(PatTupleStruct {
491 pub path: Path,
492 pub pat: PatTuple,
493 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700494
Alex Crichton62a0a592017-05-22 13:58:53 -0700495 /// A possibly qualified path pattern.
496 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
497 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
498 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700499 pub Path(PatPath {
500 pub qself: Option<QSelf>,
501 pub path: Path,
502 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700503
Alex Crichton62a0a592017-05-22 13:58:53 -0700504 /// A tuple pattern `(a, b)`.
505 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
506 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700507 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800508 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700509 pub dots_pos: Option<usize>,
David Tolnay32954ef2017-12-26 22:43:16 -0500510 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800511 pub dot2_token: Option<Token![..]>,
512 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Box(PatBox {
516 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800517 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700518 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700519 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700520 pub Ref(PatRef {
521 pub pat: Box<Pat>,
522 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800523 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700524 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700525 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700526 pub Lit(PatLit {
527 pub expr: Box<Expr>,
528 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800529 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 pub Range(PatRange {
531 pub lo: Box<Expr>,
532 pub hi: Box<Expr>,
533 pub limits: RangeLimits,
534 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400535 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800537 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800539 pub back: Delimited<Pat, Token![,]>,
540 pub dot2_token: Option<Token![..]>,
541 pub comma_token: Option<Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500542 pub bracket_token: token::Bracket,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700543 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700544 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800545 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700546 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700547}
548
Michael Layzell734adb42017-06-07 16:58:31 -0400549#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700550ast_struct! {
551 /// An arm of a 'match'.
552 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800553 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500555 /// ```rust
556 /// # #![feature(dotdoteq_in_patterns)]
557 /// #
558 /// # fn main() {
559 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500561 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500563 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500565 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700566 /// ```
567 pub struct Arm {
568 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800569 pub pats: Delimited<Pat, Token![|]>,
570 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800572 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800574 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700575 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700576}
577
Michael Layzell734adb42017-06-07 16:58:31 -0400578#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700579ast_enum! {
580 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700581 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700582 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800583 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 Ref,
585 }
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 /// Limit types of a range (inclusive or exclusive)
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 RangeLimits {
593 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800594 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700595 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800596 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700597 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700598}
599
Michael Layzell734adb42017-06-07 16:58:31 -0400600#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700601ast_struct! {
602 /// A single field in a struct pattern
603 ///
604 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
605 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
606 /// except `is_shorthand` is true
607 pub struct FieldPat {
608 /// The identifier for the field
609 pub ident: Ident,
610 /// The pattern the field is destructured to
611 pub pat: Box<Pat>,
612 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800613 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700614 pub attrs: Vec<Attribute>,
615 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700616}
617
Michael Layzell734adb42017-06-07 16:58:31 -0400618#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700619ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700620 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700621 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800622 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700623 ByValue(Mutability),
624 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700625}
626
Michael Layzell734adb42017-06-07 16:58:31 -0400627#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400628ast_enum! {
629 #[cfg_attr(feature = "clone-impls", derive(Copy))]
630 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800631 Arrow(Token![<-]),
632 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400633 }
634}
635
Michael Layzell3936ceb2017-07-08 00:28:36 -0400636#[cfg(any(feature = "parsing", feature = "printing"))]
637#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700638fn arm_expr_requires_comma(expr: &Expr) -> bool {
639 // see https://github.com/rust-lang/rust/blob/eb8f2586e
640 // /src/libsyntax/parse/classify.rs#L17-L37
641 match expr.node {
David Tolnay51382052017-12-27 13:46:21 -0500642 ExprKind::Unsafe(..)
643 | ExprKind::Block(..)
644 | ExprKind::If(..)
645 | ExprKind::IfLet(..)
646 | ExprKind::Match(..)
647 | ExprKind::While(..)
648 | ExprKind::WhileLet(..)
649 | ExprKind::Loop(..)
650 | ExprKind::ForLoop(..)
651 | ExprKind::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700652 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400653 }
654}
655
David Tolnayb9c8e322016-09-23 20:48:37 -0700656#[cfg(feature = "parsing")]
657pub mod parsing {
658 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700659 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700660
Michael Layzell734adb42017-06-07 16:58:31 -0400661 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500662 use proc_macro2::{Delimiter, Span, Term, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500663 use synom::Synom;
664 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400665 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500666 use parse_error;
667 use PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700668
David Tolnaybcf26022017-12-25 22:10:52 -0500669 // When we're parsing expressions which occur before blocks, like in an if
670 // statement's condition, we cannot parse a struct literal.
671 //
672 // Struct literals are ambiguous in certain positions
673 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700674 macro_rules! ambiguous_expr {
675 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700676 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700677 };
678 }
679
David Tolnaybcf26022017-12-25 22:10:52 -0500680 // When we are parsing an optional suffix expression, we cannot allow blocks
681 // if structs are not allowed.
682 //
683 // Example:
684 //
685 // if break {} {}
686 //
687 // is ambiguous between:
688 //
689 // if (break {}) {}
690 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400691 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400692 macro_rules! opt_ambiguous_expr {
693 ($i:expr, $allow_struct:ident) => {
694 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
695 };
696 }
697
Alex Crichton954046c2017-05-30 21:49:42 -0700698 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400699 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700700
701 fn description() -> Option<&'static str> {
702 Some("expression")
703 }
704 }
705
Michael Layzell734adb42017-06-07 16:58:31 -0400706 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700707 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
708
David Tolnaybcf26022017-12-25 22:10:52 -0500709 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400710 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500711 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400712 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700713 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400714 call!(assign_expr, allow_struct, allow_block),
715 ExprKind::into
716 )
717 }
718
Michael Layzell734adb42017-06-07 16:58:31 -0400719 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500720 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzell734adb42017-06-07 16:58:31 -0400721 map!(
722 i,
723 // NOTE: We intentionally skip assign_expr, placement_expr, and
724 // range_expr, as they are not parsed in non-full mode.
725 call!(or_expr, allow_struct, allow_block),
726 ExprKind::into
727 )
728 }
729
David Tolnaybcf26022017-12-25 22:10:52 -0500730 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400731 macro_rules! binop {
732 (
733 $name: ident,
734 $next: ident,
735 $submac: ident!( $($args:tt)* )
736 ) => {
737 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
738 mut e: call!($next, allow_struct, allow_block) >>
739 many0!(do_parse!(
740 op: $submac!($($args)*) >>
741 rhs: call!($next, allow_struct, true) >>
742 ({
743 e = ExprBinary {
744 left: Box::new(e.into()),
745 op: op,
746 right: Box::new(rhs.into()),
747 }.into();
748 })
749 )) >>
750 (e)
751 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700752 }
David Tolnay54e854d2016-10-24 12:03:30 -0700753 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700754
David Tolnaybcf26022017-12-25 22:10:52 -0500755 // <placement> = <placement> ..
756 // <placement> += <placement> ..
757 // <placement> -= <placement> ..
758 // <placement> *= <placement> ..
759 // <placement> /= <placement> ..
760 // <placement> %= <placement> ..
761 // <placement> ^= <placement> ..
762 // <placement> &= <placement> ..
763 // <placement> |= <placement> ..
764 // <placement> <<= <placement> ..
765 // <placement> >>= <placement> ..
766 //
767 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400768 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400769 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
770 mut e: call!(placement_expr, allow_struct, allow_block) >>
771 alt!(
772 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800773 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400774 // Recurse into self to parse right-associative operator.
775 rhs: call!(assign_expr, allow_struct, true) >>
776 ({
777 e = ExprAssign {
778 left: Box::new(e.into()),
779 eq_token: eq,
780 right: Box::new(rhs.into()),
781 }.into();
782 })
783 )
784 |
785 do_parse!(
786 op: call!(BinOp::parse_assign_op) >>
787 // Recurse into self to parse right-associative operator.
788 rhs: call!(assign_expr, allow_struct, true) >>
789 ({
790 e = ExprAssignOp {
791 left: Box::new(e.into()),
792 op: op,
793 right: Box::new(rhs.into()),
794 }.into();
795 })
796 )
797 |
798 epsilon!()
799 ) >>
800 (e)
801 ));
802
David Tolnaybcf26022017-12-25 22:10:52 -0500803 // <range> <- <range> ..
804 //
805 // NOTE: The `in place { expr }` version of this syntax is parsed in
806 // `atom_expr`, not here.
807 //
808 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400809 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400810 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
811 mut e: call!(range_expr, allow_struct, allow_block) >>
812 alt!(
813 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800814 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400815 // Recurse into self to parse right-associative operator.
816 rhs: call!(placement_expr, allow_struct, true) >>
817 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400818 e = ExprInPlace {
819 // op: BinOp::Place(larrow),
820 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400821 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400822 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400823 }.into();
824 })
825 )
826 |
827 epsilon!()
828 ) >>
829 (e)
830 ));
831
David Tolnaybcf26022017-12-25 22:10:52 -0500832 // <or> ... <or> ..
833 // <or> .. <or> ..
834 // <or> ..
835 //
836 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
837 // rules are for parsing these expressions are, but this is not correct.
838 // For example, `a .. b .. c` is not a legal expression. It should not
839 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
840 //
841 // NOTE: The form of ranges which don't include a preceding expression are
842 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400843 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400844 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
845 mut e: call!(or_expr, allow_struct, allow_block) >>
846 many0!(do_parse!(
847 limits: syn!(RangeLimits) >>
848 // We don't want to allow blocks here if we don't allow structs. See
849 // the reasoning for `opt_ambiguous_expr!` above.
850 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
851 ({
852 e = ExprRange {
853 from: Some(Box::new(e.into())),
854 limits: limits,
855 to: hi.map(|e| Box::new(e.into())),
856 }.into();
857 })
858 )) >>
859 (e)
860 ));
861
David Tolnaybcf26022017-12-25 22:10:52 -0500862 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800863 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400864
David Tolnaybcf26022017-12-25 22:10:52 -0500865 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800866 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400867
David Tolnaybcf26022017-12-25 22:10:52 -0500868 // <bitor> == <bitor> ...
869 // <bitor> != <bitor> ...
870 // <bitor> >= <bitor> ...
871 // <bitor> <= <bitor> ...
872 // <bitor> > <bitor> ...
873 // <bitor> < <bitor> ...
874 //
875 // NOTE: This operator appears to be parsed as left-associative, but errors
876 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500877 binop!(
878 compare_expr,
879 bitor_expr,
880 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800881 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400882 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800883 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400884 |
885 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800886 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400887 |
888 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800889 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400890 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400891 do_parse!(
892 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800893 not!(punct!(<-)) >>
894 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400895 (BinOp::Lt(t))
896 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400897 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800898 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500899 )
900 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400901
David Tolnaybcf26022017-12-25 22:10:52 -0500902 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500903 binop!(
904 bitor_expr,
905 bitxor_expr,
906 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
907 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400908
David Tolnaybcf26022017-12-25 22:10:52 -0500909 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500910 binop!(
911 bitxor_expr,
912 bitand_expr,
913 do_parse!(
914 // NOTE: Make sure we aren't looking at ^=.
915 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
916 )
917 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400918
David Tolnaybcf26022017-12-25 22:10:52 -0500919 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -0500920 binop!(
921 bitand_expr,
922 shift_expr,
923 do_parse!(
924 // NOTE: Make sure we aren't looking at && or &=.
925 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
926 )
927 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400928
David Tolnaybcf26022017-12-25 22:10:52 -0500929 // <arith> << <arith> ...
930 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -0500931 binop!(
932 shift_expr,
933 arith_expr,
934 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800935 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400936 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800937 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -0500938 )
939 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400940
David Tolnaybcf26022017-12-25 22:10:52 -0500941 // <term> + <term> ...
942 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -0500943 binop!(
944 arith_expr,
945 term_expr,
946 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800947 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400948 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800949 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -0500950 )
951 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400952
David Tolnaybcf26022017-12-25 22:10:52 -0500953 // <cast> * <cast> ...
954 // <cast> / <cast> ...
955 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -0500956 binop!(
957 term_expr,
958 cast_expr,
959 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800960 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400961 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800962 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400963 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800964 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -0500965 )
966 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400967
David Tolnaybcf26022017-12-25 22:10:52 -0500968 // <unary> as <ty>
969 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400970 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
971 mut e: call!(unary_expr, allow_struct, allow_block) >>
972 many0!(alt!(
973 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800974 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400975 // We can't accept `A + B` in cast expressions, as it's
976 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800977 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400978 ({
979 e = ExprCast {
980 expr: Box::new(e.into()),
981 as_token: as_,
982 ty: Box::new(ty),
983 }.into();
984 })
985 )
986 |
987 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800988 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400989 // We can't accept `A + B` in cast expressions, as it's
990 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800991 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400992 ({
993 e = ExprType {
994 expr: Box::new(e.into()),
995 colon_token: colon,
996 ty: Box::new(ty),
997 }.into();
998 })
999 )
1000 )) >>
1001 (e)
1002 ));
1003
David Tolnaybcf26022017-12-25 22:10:52 -05001004 // <UnOp> <trailer>
1005 // & <trailer>
1006 // &mut <trailer>
1007 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001008 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001009 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1010 do_parse!(
1011 op: syn!(UnOp) >>
1012 expr: call!(unary_expr, allow_struct, true) >>
1013 (ExprUnary {
1014 op: op,
1015 expr: Box::new(expr.into()),
1016 }.into())
1017 )
1018 |
1019 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001020 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001021 mutability: syn!(Mutability) >>
1022 expr: call!(unary_expr, allow_struct, true) >>
1023 (ExprAddrOf {
1024 and_token: and,
1025 mutbl: mutability,
1026 expr: Box::new(expr.into()),
1027 }.into())
1028 )
1029 |
1030 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001031 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001032 expr: call!(unary_expr, allow_struct, true) >>
1033 (ExprBox {
1034 box_token: box_,
1035 expr: Box::new(expr.into()),
1036 }.into())
1037 )
1038 |
1039 call!(trailer_expr, allow_struct, allow_block)
1040 ));
1041
Michael Layzell734adb42017-06-07 16:58:31 -04001042 // XXX: This duplication is ugly
1043 #[cfg(not(feature = "full"))]
1044 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1045 do_parse!(
1046 op: syn!(UnOp) >>
1047 expr: call!(unary_expr, allow_struct, true) >>
1048 (ExprUnary {
1049 op: op,
1050 expr: Box::new(expr.into()),
1051 }.into())
1052 )
1053 |
1054 call!(trailer_expr, allow_struct, allow_block)
1055 ));
1056
David Tolnaybcf26022017-12-25 22:10:52 -05001057 // <atom> (..<args>) ...
1058 // <atom> . <ident> (..<args>) ...
1059 // <atom> . <ident> ...
1060 // <atom> . <lit> ...
1061 // <atom> [ <expr> ] ...
1062 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001063 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001064 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1065 mut e: call!(atom_expr, allow_struct, allow_block) >>
1066 many0!(alt!(
1067 tap!(args: and_call => {
1068 let (args, paren) = args;
1069 e = ExprCall {
1070 func: Box::new(e.into()),
1071 args: args,
1072 paren_token: paren,
1073 }.into();
1074 })
1075 |
1076 tap!(more: and_method_call => {
1077 let mut call = more;
1078 call.expr = Box::new(e.into());
1079 e = call.into();
1080 })
1081 |
1082 tap!(field: and_field => {
1083 let (field, token) = field;
1084 e = ExprField {
1085 expr: Box::new(e.into()),
1086 field: field,
1087 dot_token: token,
1088 }.into();
1089 })
1090 |
1091 tap!(field: and_tup_field => {
1092 let (field, token) = field;
1093 e = ExprTupField {
1094 expr: Box::new(e.into()),
1095 field: field,
1096 dot_token: token,
1097 }.into();
1098 })
1099 |
1100 tap!(i: and_index => {
1101 let (i, token) = i;
1102 e = ExprIndex {
1103 expr: Box::new(e.into()),
1104 bracket_token: token,
1105 index: Box::new(i),
1106 }.into();
1107 })
1108 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001109 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001110 e = ExprTry {
1111 expr: Box::new(e.into()),
1112 question_token: question,
1113 }.into();
1114 })
1115 )) >>
1116 (e)
1117 ));
1118
Michael Layzell734adb42017-06-07 16:58:31 -04001119 // XXX: Duplication == ugly
1120 #[cfg(not(feature = "full"))]
1121 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1122 mut e: call!(atom_expr, allow_struct, allow_block) >>
1123 many0!(alt!(
1124 tap!(args: and_call => {
1125 let (args, paren) = args;
1126 e = ExprCall {
1127 func: Box::new(e.into()),
1128 args: args,
1129 paren_token: paren,
1130 }.into();
1131 })
1132 |
1133 tap!(i: and_index => {
1134 let (i, token) = i;
1135 e = ExprIndex {
1136 expr: Box::new(e.into()),
1137 bracket_token: token,
1138 index: Box::new(i),
1139 }.into();
1140 })
1141 )) >>
1142 (e)
1143 ));
1144
David Tolnaybcf26022017-12-25 22:10:52 -05001145 // Parse all atomic expressions which don't have to worry about precidence
1146 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001147 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001148 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001149 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1150 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001151 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1152 |
1153 // must be before expr_path
1154 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1155 |
1156 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1157 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001158 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001159 |
1160 call!(expr_break, allow_struct) // must be before expr_path
1161 |
1162 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1163 |
1164 call!(expr_ret, allow_struct) // must be before expr_path
1165 |
1166 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1167 syn!(ExprInPlace) => { ExprKind::InPlace }
1168 |
1169 syn!(ExprArray) => { ExprKind::Array }
1170 |
David Tolnay05362582017-12-26 01:33:57 -05001171 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001172 |
1173 syn!(ExprIf) => { ExprKind::If }
1174 |
1175 syn!(ExprIfLet) => { ExprKind::IfLet }
1176 |
1177 syn!(ExprWhile) => { ExprKind::While }
1178 |
1179 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1180 |
1181 syn!(ExprForLoop) => { ExprKind::ForLoop }
1182 |
1183 syn!(ExprLoop) => { ExprKind::Loop }
1184 |
1185 syn!(ExprMatch) => { ExprKind::Match }
1186 |
1187 syn!(ExprCatch) => { ExprKind::Catch }
1188 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001189 syn!(ExprYield) => { ExprKind::Yield }
1190 |
Nika Layzell640832a2017-12-04 13:37:09 -05001191 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1192 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001193 call!(expr_closure, allow_struct)
1194 |
1195 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1196 |
1197 // NOTE: This is the prefix-form of range
1198 call!(expr_range, allow_struct)
1199 |
1200 syn!(ExprPath) => { ExprKind::Path }
1201 |
1202 syn!(ExprRepeat) => { ExprKind::Repeat }
1203 ));
1204
Michael Layzell734adb42017-06-07 16:58:31 -04001205 #[cfg(not(feature = "full"))]
1206 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1207 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1208 |
1209 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1210 |
1211 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1212 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001213 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001214 |
1215 syn!(ExprPath) => { ExprKind::Path }
1216 ));
1217
Michael Layzell734adb42017-06-07 16:58:31 -04001218 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001219 named!(expr_nosemi -> Expr, map!(alt!(
1220 syn!(ExprIf) => { ExprKind::If }
1221 |
1222 syn!(ExprIfLet) => { ExprKind::IfLet }
1223 |
1224 syn!(ExprWhile) => { ExprKind::While }
1225 |
1226 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1227 |
1228 syn!(ExprForLoop) => { ExprKind::ForLoop }
1229 |
1230 syn!(ExprLoop) => { ExprKind::Loop }
1231 |
1232 syn!(ExprMatch) => { ExprKind::Match }
1233 |
1234 syn!(ExprCatch) => { ExprKind::Catch }
1235 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001236 syn!(ExprYield) => { ExprKind::Yield }
1237 |
Nika Layzell640832a2017-12-04 13:37:09 -05001238 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1239 |
Michael Layzell35418782017-06-07 09:20:25 -04001240 syn!(ExprBlock) => { ExprKind::Block }
1241 ), Expr::from));
1242
Michael Layzell93c36282017-06-04 20:43:14 -04001243 impl Synom for ExprGroup {
1244 named!(parse -> Self, do_parse!(
1245 e: grouped!(syn!(Expr)) >>
1246 (ExprGroup {
1247 expr: Box::new(e.0),
1248 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001249 })
Michael Layzell93c36282017-06-04 20:43:14 -04001250 ));
1251 }
1252
Alex Crichton954046c2017-05-30 21:49:42 -07001253 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001254 named!(parse -> Self, do_parse!(
1255 e: parens!(syn!(Expr)) >>
1256 (ExprParen {
1257 expr: Box::new(e.0),
1258 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001259 })
Michael Layzell92639a52017-06-01 00:07:44 -04001260 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001261 }
David Tolnay89e05672016-10-02 14:39:42 -07001262
Michael Layzell734adb42017-06-07 16:58:31 -04001263 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001264 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001265 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001266 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001267 place: expr_no_struct >>
1268 value: braces!(call!(Block::parse_within)) >>
1269 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001270 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001271 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001272 value: Box::new(Expr {
1273 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001274 block: Block {
1275 stmts: value.0,
1276 brace_token: value.1,
1277 },
1278 }.into(),
1279 attrs: Vec::new(),
1280 }),
1281 })
1282 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001283 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001284
Michael Layzell734adb42017-06-07 16:58:31 -04001285 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001286 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001287 named!(parse -> Self, do_parse!(
1288 elems: brackets!(call!(Delimited::parse_terminated)) >>
1289 (ExprArray {
1290 exprs: elems.0,
1291 bracket_token: elems.1,
1292 })
1293 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001294 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001295
David Tolnay32954ef2017-12-26 22:43:16 -05001296 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001297 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001298
Michael Layzell734adb42017-06-07 16:58:31 -04001299 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001300 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001301 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001302 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001303 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001304 colon2: punct!(::) >>
1305 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001306 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001307 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001308 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001309 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001310 args: parens!(call!(Delimited::parse_terminated)) >>
1311 ({
1312 let (colon2, lt, tys, gt) = match typarams {
1313 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1314 None => (None, None, None, None),
1315 };
1316 ExprMethodCall {
1317 // this expr will get overwritten after being returned
1318 expr: Box::new(ExprKind::Lit(Lit {
1319 span: Span::default(),
1320 value: LitKind::Bool(false),
1321 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001322
Alex Crichton954046c2017-05-30 21:49:42 -07001323 method: method,
1324 args: args.0,
1325 paren_token: args.1,
1326 dot_token: dot,
1327 lt_token: lt,
1328 gt_token: gt,
1329 colon2_token: colon2,
1330 typarams: tys.unwrap_or_default(),
1331 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001332 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001333 ));
1334
Michael Layzell734adb42017-06-07 16:58:31 -04001335 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001336 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001337 named!(parse -> Self, do_parse!(
1338 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001339 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001340 args: elems.0,
1341 paren_token: elems.1,
1342 lone_comma: None, // TODO: parse this
1343 })
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 >>
Alex Crichton03b30272017-08-28 09:35:24 -07001455 res: braces!(many0!(syn!(Arm))) >>
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!(
1497 attrs: many0!(call!(Attribute::parse_outer)) >>
1498 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 Tolnayfd6bf5c2017-11-12 09:41:14 -08001534 (ReturnType::Type(ty, arrow),
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,
1545 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001546 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001547 inputs: inputs,
1548 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001549 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001550 dot_tokens: None,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001551 fn_token: <Token![fn]>::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001552 generics: Generics::default(),
David Tolnay32954ef2017-12-26 22:43:16 -05001553 paren_token: token::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001554 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001555 body: Box::new(ret_and_body.1),
1556 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001557 ));
1558
Michael Layzell734adb42017-06-07 16:58:31 -04001559 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001560 named!(fn_arg -> FnArg, do_parse!(
1561 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001562 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001563 ({
1564 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001565 (<Token![:]>::default(), TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001566 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001567 }.into())
1568 });
1569 ArgCaptured {
1570 pat: pat,
1571 colon_token: colon,
1572 ty: ty,
1573 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001574 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001575 ));
1576
Michael Layzell734adb42017-06-07 16:58:31 -04001577 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001578 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001579 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001580 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1581 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001582 cond: expr_no_struct >>
1583 while_block: syn!(Block) >>
1584 (ExprWhile {
1585 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001586 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001587 cond: Box::new(cond),
1588 body: while_block,
1589 label: lbl.map(|p| p.0),
1590 })
1591 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001592 }
1593
Michael Layzell734adb42017-06-07 16:58:31 -04001594 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001595 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001596 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001597 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1598 while_: keyword!(while) >>
1599 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001600 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001601 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001602 value: expr_no_struct >>
1603 while_block: syn!(Block) >>
1604 (ExprWhileLet {
1605 eq_token: eq,
1606 let_token: let_,
1607 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001608 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001609 pat: Box::new(pat),
1610 expr: Box::new(value),
1611 body: while_block,
1612 label: lbl.map(|p| p.0),
1613 })
1614 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001615 }
1616
Michael Layzell734adb42017-06-07 16:58:31 -04001617 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001618 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001619 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001620 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001621 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001622 (ExprContinue {
1623 continue_token: cont,
1624 label: lbl,
1625 })
1626 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001627 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001628
Michael Layzell734adb42017-06-07 16:58:31 -04001629 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001630 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001631 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001632 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001633 // We can't allow blocks after a `break` expression when we wouldn't
1634 // allow structs, as this expression is ambiguous.
1635 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001636 (ExprBreak {
1637 label: lbl,
1638 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001639 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001640 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001641 ));
1642
Michael Layzell734adb42017-06-07 16:58:31 -04001643 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001644 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001645 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001646 // NOTE: return is greedy and eats blocks after it even when in a
1647 // position where structs are not allowed, such as in if statement
1648 // conditions. For example:
1649 //
David Tolnaybcf26022017-12-25 22:10:52 -05001650 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001651 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001652 (ExprRet {
1653 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001654 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001655 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001656 ));
1657
Michael Layzell734adb42017-06-07 16:58:31 -04001658 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001659 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001660 named!(parse -> Self, do_parse!(
1661 path: syn!(Path) >>
1662 data: braces!(do_parse!(
1663 fields: call!(Delimited::parse_terminated) >>
1664 base: option!(
1665 cond!(fields.is_empty() || fields.trailing_delim(),
1666 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001667 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001668 base: syn!(Expr) >>
1669 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001670 )
Michael Layzell92639a52017-06-01 00:07:44 -04001671 )
1672 ) >>
1673 (fields, base)
1674 )) >>
1675 ({
1676 let ((fields, base), brace) = data;
1677 let (dots, rest) = match base.and_then(|b| b) {
1678 Some((dots, base)) => (Some(dots), Some(base)),
1679 None => (None, None),
1680 };
1681 ExprStruct {
1682 brace_token: brace,
1683 path: path,
1684 fields: fields,
1685 dot2_token: dots,
1686 rest: rest.map(Box::new),
1687 }
1688 })
1689 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001690 }
1691
Michael Layzell734adb42017-06-07 16:58:31 -04001692 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001693 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001694 named!(parse -> Self, alt!(
1695 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001696 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001697 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001698 value: syn!(Expr) >>
1699 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001700 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001701 expr: value,
1702 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001703 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001704 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001705 })
Michael Layzell92639a52017-06-01 00:07:44 -04001706 )
1707 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001708 map!(syn!(Ident), |name| FieldValue {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001709 ident: name,
Michael Layzell92639a52017-06-01 00:07:44 -04001710 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1711 is_shorthand: true,
1712 attrs: Vec::new(),
1713 colon_token: None,
1714 })
1715 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001716 }
David Tolnay055a7042016-10-02 19:23:54 -07001717
Michael Layzell734adb42017-06-07 16:58:31 -04001718 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001719 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001720 named!(parse -> Self, do_parse!(
1721 data: brackets!(do_parse!(
1722 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001723 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001724 times: syn!(Expr) >>
1725 (value, semi, times)
1726 )) >>
1727 (ExprRepeat {
1728 expr: Box::new((data.0).0),
1729 amt: Box::new((data.0).2),
1730 bracket_token: data.1,
1731 semi_token: (data.0).1,
1732 })
1733 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001734 }
David Tolnay055a7042016-10-02 19:23:54 -07001735
Michael Layzell734adb42017-06-07 16:58:31 -04001736 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001737 impl Synom for ExprUnsafe {
1738 named!(parse -> Self, do_parse!(
1739 unsafe_: keyword!(unsafe) >>
1740 b: syn!(Block) >>
1741 (ExprUnsafe {
1742 unsafe_token: unsafe_,
1743 block: b,
1744 })
1745 ));
1746 }
1747
1748 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001749 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001750 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001751 b: syn!(Block) >>
1752 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001753 block: b,
1754 })
1755 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001756 }
David Tolnay89e05672016-10-02 14:39:42 -07001757
Michael Layzell734adb42017-06-07 16:58:31 -04001758 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001759 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001760 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001761 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001762 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001763 ));
1764
Michael Layzell734adb42017-06-07 16:58:31 -04001765 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001766 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001767 named!(parse -> Self, alt!(
1768 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001769 punct!(..=) => { RangeLimits::Closed }
1770 |
1771 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001772 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001773 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001774 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001775 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001776 }
David Tolnay438c9052016-10-07 23:24:48 -07001777
Alex Crichton954046c2017-05-30 21:49:42 -07001778 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001779 named!(parse -> Self, do_parse!(
1780 pair: qpath >>
1781 (ExprPath {
1782 qself: pair.0,
1783 path: pair.1,
1784 })
1785 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001786 }
David Tolnay42602292016-10-01 22:25:45 -07001787
Michael Layzell734adb42017-06-07 16:58:31 -04001788 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001789 named!(and_field -> (Ident, Token![.]),
1790 map!(tuple!(punct!(.), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001791
Michael Layzell734adb42017-06-07 16:58:31 -04001792 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001793 named!(and_tup_field -> (Lit, Token![.]),
1794 map!(tuple!(punct!(.), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001795
David Tolnay32954ef2017-12-26 22:43:16 -05001796 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001797
Michael Layzell734adb42017-06-07 16:58:31 -04001798 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001799 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001800 named!(parse -> Self, do_parse!(
1801 stmts: braces!(call!(Block::parse_within)) >>
1802 (Block {
1803 stmts: stmts.0,
1804 brace_token: stmts.1,
1805 })
1806 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001807 }
David Tolnay939766a2016-09-23 23:48:12 -07001808
Michael Layzell734adb42017-06-07 16:58:31 -04001809 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001810 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001811 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001812 many0!(punct!(;)) >>
1813 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001814 last: option!(do_parse!(
1815 attrs: many0!(call!(Attribute::parse_outer)) >>
1816 mut e: syn!(Expr) >>
1817 ({
1818 e.attrs = attrs;
1819 Stmt::Expr(Box::new(e))
1820 })
1821 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001822 (match last {
1823 None => standalone,
1824 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001825 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001826 standalone
1827 }
1828 })
1829 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001830 }
1831
Michael Layzell734adb42017-06-07 16:58:31 -04001832 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001833 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001834 named!(parse -> Self, alt!(
1835 stmt_mac
1836 |
1837 stmt_local
1838 |
1839 stmt_item
1840 |
Michael Layzell35418782017-06-07 09:20:25 -04001841 stmt_blockexpr
1842 |
Michael Layzell92639a52017-06-01 00:07:44 -04001843 stmt_expr
1844 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001845 }
David Tolnay939766a2016-09-23 23:48:12 -07001846
Michael Layzell734adb42017-06-07 16:58:31 -04001847 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001848 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001849 attrs: many0!(call!(Attribute::parse_outer)) >>
1850 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001851 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001852 // Only parse braces here; paren and bracket will get parsed as
1853 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001854 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001855 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001856 (Stmt::Macro(Box::new((
1857 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001858 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001859 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001860 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001861 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001862 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001863 },
David Tolnayeea28d62016-10-25 20:44:08 -07001864 },
Alex Crichton954046c2017-05-30 21:49:42 -07001865 match semi {
1866 Some(semi) => MacStmtStyle::Semicolon(semi),
1867 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001868 },
David Tolnayeea28d62016-10-25 20:44:08 -07001869 attrs,
1870 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001871 ));
1872
Michael Layzell734adb42017-06-07 16:58:31 -04001873 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001874 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001875 attrs: many0!(call!(Attribute::parse_outer)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001876 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001877 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001878 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001879 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1880 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001881 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001882 let_token: let_,
1883 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001884 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1885 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001886 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001887 ty: ty.map(|p| Box::new(p.1)),
1888 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001889 attrs: attrs,
1890 })))
1891 ));
1892
Michael Layzell734adb42017-06-07 16:58:31 -04001893 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001894 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001895
Michael Layzell734adb42017-06-07 16:58:31 -04001896 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001897 named!(stmt_blockexpr -> Stmt, do_parse!(
1898 attrs: many0!(call!(Attribute::parse_outer)) >>
1899 mut e: expr_nosemi >>
1900 // If the next token is a `.` or a `?` it is special-cased to parse as
1901 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001902 not!(punct!(.)) >>
1903 not!(punct!(?)) >>
1904 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001905 ({
1906 e.attrs = attrs;
1907 if let Some(semi) = semi {
1908 Stmt::Semi(Box::new(e), semi)
1909 } else {
1910 Stmt::Expr(Box::new(e))
1911 }
1912 })
1913 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001914
Michael Layzell734adb42017-06-07 16:58:31 -04001915 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001916 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001917 attrs: many0!(call!(Attribute::parse_outer)) >>
1918 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001919 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001920 ({
1921 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001922 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001923 })
David Tolnay939766a2016-09-23 23:48:12 -07001924 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001925
Michael Layzell734adb42017-06-07 16:58:31 -04001926 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001927 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001928 named!(parse -> Self, alt!(
1929 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1930 |
1931 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1932 |
1933 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1934 |
1935 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1936 |
1937 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1938 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001939 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001940 |
1941 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1942 |
1943 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1944 |
1945 syn!(PatPath) => { Pat::Path }
1946 |
1947 syn!(PatTuple) => { Pat::Tuple }
1948 |
1949 syn!(PatRef) => { Pat::Ref }
1950 |
1951 syn!(PatSlice) => { Pat::Slice }
1952 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001953 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001954
Michael Layzell734adb42017-06-07 16:58:31 -04001955 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001956 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001957 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001958 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001959 |u| PatWild { underscore_token: u }
1960 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001961 }
David Tolnay84aa0752016-10-02 23:01:13 -07001962
Michael Layzell734adb42017-06-07 16:58:31 -04001963 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001964 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001965 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001966 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001967 pat: syn!(Pat) >>
1968 (PatBox {
1969 pat: Box::new(pat),
1970 box_token: boxed,
1971 })
1972 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001973 }
1974
Michael Layzell734adb42017-06-07 16:58:31 -04001975 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001976 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001977 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001978 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001979 mutability: syn!(Mutability) >>
1980 name: alt!(
1981 syn!(Ident)
1982 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001983 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001984 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001985 not!(punct!(<)) >>
1986 not!(punct!(::)) >>
1987 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001988 (PatIdent {
1989 mode: match mode {
1990 Some(mode) => BindingMode::ByRef(mode, mutability),
1991 None => BindingMode::ByValue(mutability),
1992 },
1993 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001994 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001995 subpat: subpat.map(|p| Box::new(p.1)),
1996 })
1997 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001998 }
1999
Michael Layzell734adb42017-06-07 16:58:31 -04002000 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002001 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002002 named!(parse -> Self, do_parse!(
2003 path: syn!(Path) >>
2004 tuple: syn!(PatTuple) >>
2005 (PatTupleStruct {
2006 path: path,
2007 pat: tuple,
2008 })
2009 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002010 }
2011
Michael Layzell734adb42017-06-07 16:58:31 -04002012 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002013 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002014 named!(parse -> Self, do_parse!(
2015 path: syn!(Path) >>
2016 data: braces!(do_parse!(
2017 fields: call!(Delimited::parse_terminated) >>
2018 base: option!(
2019 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002020 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002021 ) >>
2022 (fields, base)
2023 )) >>
2024 (PatStruct {
2025 path: path,
2026 fields: (data.0).0,
2027 brace_token: data.1,
2028 dot2_token: (data.0).1.and_then(|m| m),
2029 })
2030 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002031 }
2032
Michael Layzell734adb42017-06-07 16:58:31 -04002033 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002034 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002035 named!(parse -> Self, alt!(
2036 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002037 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002038 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002039 pat: syn!(Pat) >>
2040 (FieldPat {
2041 ident: ident,
2042 pat: Box::new(pat),
2043 is_shorthand: false,
2044 attrs: Vec::new(),
2045 colon_token: Some(colon),
2046 })
2047 )
2048 |
2049 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002050 boxed: option!(keyword!(box)) >>
2051 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002052 mutability: syn!(Mutability) >>
2053 ident: syn!(Ident) >>
2054 ({
2055 let mut pat: Pat = PatIdent {
2056 mode: if let Some(mode) = mode {
2057 BindingMode::ByRef(mode, mutability)
2058 } else {
2059 BindingMode::ByValue(mutability)
2060 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002061 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002062 subpat: None,
2063 at_token: None,
2064 }.into();
2065 if let Some(boxed) = boxed {
2066 pat = PatBox {
2067 pat: Box::new(pat),
2068 box_token: boxed,
2069 }.into();
2070 }
2071 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002072 ident: ident,
2073 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002074 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002075 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002076 colon_token: None,
2077 }
2078 })
2079 )
2080 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002081 }
2082
Michael Layzell734adb42017-06-07 16:58:31 -04002083 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002084 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002085 syn!(Ident)
2086 |
2087 do_parse!(
2088 lit: syn!(Lit) >>
2089 ({
David Tolnay570695e2017-06-03 16:15:13 -07002090 let s = lit.to_string();
2091 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002092 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002093 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002094 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002095 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002096 })
2097 )
2098 ));
2099
Michael Layzell734adb42017-06-07 16:58:31 -04002100 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002101 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002102 named!(parse -> Self, map!(
2103 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002104 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002105 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002106 }
David Tolnay9636c052016-10-02 17:11:17 -07002107
Michael Layzell734adb42017-06-07 16:58:31 -04002108 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002109 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002110 named!(parse -> Self, do_parse!(
2111 data: parens!(do_parse!(
2112 elems: call!(Delimited::parse_terminated) >>
2113 dotdot: map!(cond!(
2114 elems.is_empty() || elems.trailing_delim(),
2115 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002116 dots: punct!(..) >>
2117 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002118 (dots, trailing)
2119 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002120 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002121 rest: cond!(match dotdot {
2122 Some((_, Some(_))) => true,
2123 _ => false,
2124 },
2125 call!(Delimited::parse_terminated)) >>
2126 (elems, dotdot, rest)
2127 )) >>
2128 ({
2129 let ((mut elems, dotdot, rest), parens) = data;
2130 let (dotdot, trailing) = match dotdot {
2131 Some((a, b)) => (Some(a), Some(b)),
2132 None => (None, None),
2133 };
2134 PatTuple {
2135 paren_token: parens,
2136 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2137 dot2_token: dotdot,
2138 comma_token: trailing.and_then(|b| b),
2139 pats: {
2140 if let Some(rest) = rest {
2141 for elem in rest {
2142 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002143 }
Michael Layzell92639a52017-06-01 00:07:44 -04002144 }
2145 elems
2146 },
2147 }
2148 })
2149 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002150 }
David Tolnayfbb73232016-10-03 01:00:06 -07002151
Michael Layzell734adb42017-06-07 16:58:31 -04002152 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002153 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002154 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002155 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002156 mutability: syn!(Mutability) >>
2157 pat: syn!(Pat) >>
2158 (PatRef {
2159 pat: Box::new(pat),
2160 mutbl: mutability,
2161 and_token: and,
2162 })
2163 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002164 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002165
Michael Layzell734adb42017-06-07 16:58:31 -04002166 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002167 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002168 named!(parse -> Self, do_parse!(
2169 lit: pat_lit_expr >>
2170 (if let ExprKind::Path(_) = lit.node {
2171 return parse_error(); // these need to be parsed by pat_path
2172 } else {
2173 PatLit {
2174 expr: Box::new(lit),
2175 }
2176 })
2177 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002178 }
David Tolnaye1310902016-10-29 23:40:00 -07002179
Michael Layzell734adb42017-06-07 16:58:31 -04002180 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002181 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002182 named!(parse -> Self, do_parse!(
2183 lo: pat_lit_expr >>
2184 limits: syn!(RangeLimits) >>
2185 hi: pat_lit_expr >>
2186 (PatRange {
2187 lo: Box::new(lo),
2188 hi: Box::new(hi),
2189 limits: limits,
2190 })
2191 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002192 }
David Tolnaye1310902016-10-29 23:40:00 -07002193
Michael Layzell734adb42017-06-07 16:58:31 -04002194 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002195 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002196 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002197 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002198 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002199 |
Alex Crichton954046c2017-05-30 21:49:42 -07002200 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002201 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002202 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002203 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002204 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002205 expr: Box::new(v.into())
2206 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002207 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002208 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002209 })
2210 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002211
Michael Layzell734adb42017-06-07 16:58:31 -04002212 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002213 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002214 named!(parse -> Self, map!(
2215 brackets!(do_parse!(
2216 before: call!(Delimited::parse_terminated) >>
2217 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002218 dots: punct!(..) >>
2219 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002220 (dots, trailing)
2221 )) >>
2222 after: cond!(
2223 match middle {
2224 Some((_, ref trailing)) => trailing.is_some(),
2225 _ => false,
2226 },
2227 call!(Delimited::parse_terminated)
2228 ) >>
2229 (before, middle, after)
2230 )),
2231 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002232 let mut before: Delimited<Pat, Token![,]> = before;
2233 let after: Option<Delimited<Pat, Token![,]>> = after;
2234 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002235 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002236 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002237 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002238 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002239 }),
2240 bracket_token: brackets,
2241 middle: middle.and_then(|_| {
2242 if !before.is_empty() && !before.trailing_delim() {
2243 Some(Box::new(before.pop().unwrap().into_item()))
2244 } else {
2245 None
2246 }
2247 }),
2248 front: before,
2249 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002250 }
Alex Crichton954046c2017-05-30 21:49:42 -07002251 }
Michael Layzell92639a52017-06-01 00:07:44 -04002252 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002253 }
David Tolnay435a9a82016-10-29 13:47:20 -07002254
Michael Layzell734adb42017-06-07 16:58:31 -04002255 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002256 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002257 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002258 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002259 |
2260 epsilon!() => { |_| CaptureBy::Ref }
2261 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002262 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002263}
2264
David Tolnayf4bbbd92016-09-23 14:41:55 -07002265#[cfg(feature = "printing")]
2266mod printing {
2267 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002268 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002269 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002270 use quote::{ToTokens, Tokens};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002271
David Tolnaybcf26022017-12-25 22:10:52 -05002272 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2273 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002274 #[cfg(feature = "full")]
2275 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2276 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002277 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002278 e.to_tokens(tokens);
2279 });
2280 } else {
2281 e.to_tokens(tokens);
2282 }
2283 }
2284
David Tolnayf4bbbd92016-09-23 14:41:55 -07002285 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002286 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002287 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002288 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002289 self.node.to_tokens(tokens)
2290 }
Michael Layzell734adb42017-06-07 16:58:31 -04002291
2292 #[cfg(not(feature = "full"))]
2293 fn to_tokens(&self, tokens: &mut Tokens) {
2294 self.node.to_tokens(tokens)
2295 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002296 }
2297
Michael Layzell734adb42017-06-07 16:58:31 -04002298 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002299 impl ToTokens for ExprBox {
2300 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002301 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002302 self.expr.to_tokens(tokens);
2303 }
2304 }
2305
Michael Layzell734adb42017-06-07 16:58:31 -04002306 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002307 impl ToTokens for ExprInPlace {
2308 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002309 match self.kind {
2310 InPlaceKind::Arrow(ref arrow) => {
2311 self.place.to_tokens(tokens);
2312 arrow.to_tokens(tokens);
2313 self.value.to_tokens(tokens);
2314 }
2315 InPlaceKind::In(ref _in) => {
2316 _in.to_tokens(tokens);
2317 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002318 // NOTE: The second operand must be in a block, add one if
2319 // it is not present.
2320 if let ExprKind::Block(_) = self.value.node {
2321 self.value.to_tokens(tokens);
2322 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002323 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002324 self.value.to_tokens(tokens);
2325 })
2326 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002327 }
2328 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002329 }
2330 }
2331
Michael Layzell734adb42017-06-07 16:58:31 -04002332 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002333 impl ToTokens for ExprArray {
2334 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002335 self.bracket_token.surround(tokens, |tokens| {
2336 self.exprs.to_tokens(tokens);
2337 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002338 }
2339 }
2340
2341 impl ToTokens for ExprCall {
2342 fn to_tokens(&self, tokens: &mut Tokens) {
2343 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002344 self.paren_token.surround(tokens, |tokens| {
2345 self.args.to_tokens(tokens);
2346 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002347 }
2348 }
2349
Michael Layzell734adb42017-06-07 16:58:31 -04002350 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002351 impl ToTokens for ExprMethodCall {
2352 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002353 self.expr.to_tokens(tokens);
2354 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002355 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002356 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002357 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2358 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002359 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002360 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002361 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002362 self.paren_token.surround(tokens, |tokens| {
2363 self.args.to_tokens(tokens);
2364 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002365 }
2366 }
2367
Michael Layzell734adb42017-06-07 16:58:31 -04002368 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002369 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002370 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002371 self.paren_token.surround(tokens, |tokens| {
2372 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002373 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002374 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002375 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002376 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002377 }
2378 // XXX: Not sure how to handle this, but we never parse it yet.
2379 // Is this for an expression like (0,)? Can't we use the
2380 // trailing delimiter on Delimited for that? (,) isn't a valid
2381 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002382 self.lone_comma.to_tokens(tokens);
2383 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002384 }
2385 }
2386
2387 impl ToTokens for ExprBinary {
2388 fn to_tokens(&self, tokens: &mut Tokens) {
2389 self.left.to_tokens(tokens);
2390 self.op.to_tokens(tokens);
2391 self.right.to_tokens(tokens);
2392 }
2393 }
2394
2395 impl ToTokens for ExprUnary {
2396 fn to_tokens(&self, tokens: &mut Tokens) {
2397 self.op.to_tokens(tokens);
2398 self.expr.to_tokens(tokens);
2399 }
2400 }
2401
2402 impl ToTokens for ExprCast {
2403 fn to_tokens(&self, tokens: &mut Tokens) {
2404 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002405 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002406 self.ty.to_tokens(tokens);
2407 }
2408 }
2409
2410 impl ToTokens for ExprType {
2411 fn to_tokens(&self, tokens: &mut Tokens) {
2412 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002413 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002414 self.ty.to_tokens(tokens);
2415 }
2416 }
2417
Michael Layzell734adb42017-06-07 16:58:31 -04002418 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002419 fn maybe_wrap_else(
2420 tokens: &mut Tokens,
2421 else_token: &Option<Token![else]>,
2422 if_false: &Option<Box<Expr>>,
2423 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002424 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002425 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002426
2427 // If we are not one of the valid expressions to exist in an else
2428 // clause, wrap ourselves in a block.
2429 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002430 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002431 if_false.to_tokens(tokens);
2432 }
2433 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002434 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002435 if_false.to_tokens(tokens);
2436 });
2437 }
2438 }
2439 }
2440 }
2441
2442 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002443 impl ToTokens for ExprIf {
2444 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002445 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002446 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002447 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002448 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002449 }
2450 }
2451
Michael Layzell734adb42017-06-07 16:58:31 -04002452 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002453 impl ToTokens for ExprIfLet {
2454 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002455 self.if_token.to_tokens(tokens);
2456 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002457 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002458 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002459 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002460 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002461 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002462 }
2463 }
2464
Michael Layzell734adb42017-06-07 16:58:31 -04002465 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002466 impl ToTokens for ExprWhile {
2467 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002468 if self.label.is_some() {
2469 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002470 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002471 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002472 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002473 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002474 self.body.to_tokens(tokens);
2475 }
2476 }
2477
Michael Layzell734adb42017-06-07 16:58:31 -04002478 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002479 impl ToTokens for ExprWhileLet {
2480 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002481 if self.label.is_some() {
2482 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002483 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002484 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002485 self.while_token.to_tokens(tokens);
2486 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002487 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002488 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002489 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002490 self.body.to_tokens(tokens);
2491 }
2492 }
2493
Michael Layzell734adb42017-06-07 16:58:31 -04002494 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002495 impl ToTokens for ExprForLoop {
2496 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002497 if self.label.is_some() {
2498 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002499 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002500 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002501 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002502 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002503 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002504 wrap_bare_struct(tokens, &self.expr);
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 ExprLoop {
2511 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002512 if self.label.is_some() {
2513 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002514 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002515 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002516 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002517 self.body.to_tokens(tokens);
2518 }
2519 }
2520
Michael Layzell734adb42017-06-07 16:58:31 -04002521 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002522 impl ToTokens for ExprMatch {
2523 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002524 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002525 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002526 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002527 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002528 arm.to_tokens(tokens);
2529 // Ensure that we have a comma after a non-block arm, except
2530 // for the last one.
2531 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002532 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002533 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002534 }
2535 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002536 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002537 }
2538 }
2539
Michael Layzell734adb42017-06-07 16:58:31 -04002540 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002541 impl ToTokens for ExprCatch {
2542 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002543 self.do_token.to_tokens(tokens);
2544 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002545 self.block.to_tokens(tokens);
2546 }
2547 }
2548
Michael Layzell734adb42017-06-07 16:58:31 -04002549 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002550 impl ToTokens for ExprYield {
2551 fn to_tokens(&self, tokens: &mut Tokens) {
2552 self.yield_token.to_tokens(tokens);
2553 self.expr.to_tokens(tokens);
2554 }
2555 }
2556
2557 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 impl ToTokens for ExprClosure {
2559 fn to_tokens(&self, tokens: &mut Tokens) {
2560 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002561 self.or1_token.to_tokens(tokens);
2562 for item in self.decl.inputs.iter() {
2563 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002564 FnArg::Captured(ArgCaptured {
2565 ref pat,
2566 ty: Type::Infer(_),
2567 ..
2568 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002569 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002570 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002571 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002572 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002573 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002574 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002575 self.or2_token.to_tokens(tokens);
2576 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002577 self.body.to_tokens(tokens);
2578 }
2579 }
2580
Michael Layzell734adb42017-06-07 16:58:31 -04002581 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002582 impl ToTokens for ExprUnsafe {
2583 fn to_tokens(&self, tokens: &mut Tokens) {
2584 self.unsafe_token.to_tokens(tokens);
2585 self.block.to_tokens(tokens);
2586 }
2587 }
2588
2589 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002590 impl ToTokens for ExprBlock {
2591 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002592 self.block.to_tokens(tokens);
2593 }
2594 }
2595
Michael Layzell734adb42017-06-07 16:58:31 -04002596 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002597 impl ToTokens for ExprAssign {
2598 fn to_tokens(&self, tokens: &mut Tokens) {
2599 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002600 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002601 self.right.to_tokens(tokens);
2602 }
2603 }
2604
Michael Layzell734adb42017-06-07 16:58:31 -04002605 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002606 impl ToTokens for ExprAssignOp {
2607 fn to_tokens(&self, tokens: &mut Tokens) {
2608 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002609 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002610 self.right.to_tokens(tokens);
2611 }
2612 }
2613
Michael Layzell734adb42017-06-07 16:58:31 -04002614 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 impl ToTokens for ExprField {
2616 fn to_tokens(&self, tokens: &mut Tokens) {
2617 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002618 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002619 // XXX: I don't think we can do anything if someone shoves a
2620 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002621 self.field.to_tokens(tokens);
2622 }
2623 }
2624
Michael Layzell734adb42017-06-07 16:58:31 -04002625 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002626 impl ToTokens for ExprTupField {
2627 fn to_tokens(&self, tokens: &mut Tokens) {
2628 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002629 self.dot_token.to_tokens(tokens);
2630 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002631 }
2632 }
2633
2634 impl ToTokens for ExprIndex {
2635 fn to_tokens(&self, tokens: &mut Tokens) {
2636 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002637 self.bracket_token.surround(tokens, |tokens| {
2638 self.index.to_tokens(tokens);
2639 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002640 }
2641 }
2642
Michael Layzell734adb42017-06-07 16:58:31 -04002643 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002644 impl ToTokens for ExprRange {
2645 fn to_tokens(&self, tokens: &mut Tokens) {
2646 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002647 match self.limits {
2648 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2649 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2650 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002651 self.to.to_tokens(tokens);
2652 }
2653 }
2654
2655 impl ToTokens for ExprPath {
2656 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002657 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002658 }
2659 }
2660
Michael Layzell734adb42017-06-07 16:58:31 -04002661 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002662 impl ToTokens for ExprAddrOf {
2663 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002664 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002665 self.mutbl.to_tokens(tokens);
2666 self.expr.to_tokens(tokens);
2667 }
2668 }
2669
Michael Layzell734adb42017-06-07 16:58:31 -04002670 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 impl ToTokens for ExprBreak {
2672 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002673 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002674 self.label.to_tokens(tokens);
2675 self.expr.to_tokens(tokens);
2676 }
2677 }
2678
Michael Layzell734adb42017-06-07 16:58:31 -04002679 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002680 impl ToTokens for ExprContinue {
2681 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002682 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002683 self.label.to_tokens(tokens);
2684 }
2685 }
2686
Michael Layzell734adb42017-06-07 16:58:31 -04002687 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002688 impl ToTokens for ExprRet {
2689 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002690 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002691 self.expr.to_tokens(tokens);
2692 }
2693 }
2694
Michael Layzell734adb42017-06-07 16:58:31 -04002695 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002696 impl ToTokens for ExprStruct {
2697 fn to_tokens(&self, tokens: &mut Tokens) {
2698 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002699 self.brace_token.surround(tokens, |tokens| {
2700 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002701 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002702 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002703 self.rest.to_tokens(tokens);
2704 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002705 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002706 }
2707 }
2708
Michael Layzell734adb42017-06-07 16:58:31 -04002709 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002710 impl ToTokens for ExprRepeat {
2711 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002712 self.bracket_token.surround(tokens, |tokens| {
2713 self.expr.to_tokens(tokens);
2714 self.semi_token.to_tokens(tokens);
2715 self.amt.to_tokens(tokens);
2716 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002717 }
2718 }
2719
Michael Layzell93c36282017-06-04 20:43:14 -04002720 impl ToTokens for ExprGroup {
2721 fn to_tokens(&self, tokens: &mut Tokens) {
2722 self.group_token.surround(tokens, |tokens| {
2723 self.expr.to_tokens(tokens);
2724 });
2725 }
2726 }
2727
Alex Crichton62a0a592017-05-22 13:58:53 -07002728 impl ToTokens for ExprParen {
2729 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002730 self.paren_token.surround(tokens, |tokens| {
2731 self.expr.to_tokens(tokens);
2732 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002733 }
2734 }
2735
Michael Layzell734adb42017-06-07 16:58:31 -04002736 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002737 impl ToTokens for ExprTry {
2738 fn to_tokens(&self, tokens: &mut Tokens) {
2739 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002740 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002741 }
2742 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002743
Michael Layzell734adb42017-06-07 16:58:31 -04002744 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002745 impl ToTokens for FieldValue {
2746 fn to_tokens(&self, tokens: &mut Tokens) {
2747 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002748 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2749 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002750 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002751 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002752 self.expr.to_tokens(tokens);
2753 }
David Tolnay055a7042016-10-02 19:23:54 -07002754 }
2755 }
2756
Michael Layzell734adb42017-06-07 16:58:31 -04002757 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002758 impl ToTokens for Arm {
2759 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002760 tokens.append_all(&self.attrs);
2761 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002762 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002763 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002764 self.guard.to_tokens(tokens);
2765 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002766 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002767 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002768 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002769 }
2770 }
2771
Michael Layzell734adb42017-06-07 16:58:31 -04002772 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002773 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002774 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002775 self.underscore_token.to_tokens(tokens);
2776 }
2777 }
2778
Michael Layzell734adb42017-06-07 16:58:31 -04002779 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002780 impl ToTokens for PatIdent {
2781 fn to_tokens(&self, tokens: &mut Tokens) {
2782 self.mode.to_tokens(tokens);
2783 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002784 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002785 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002786 self.subpat.to_tokens(tokens);
2787 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002788 }
2789 }
2790
Michael Layzell734adb42017-06-07 16:58:31 -04002791 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002792 impl ToTokens for PatStruct {
2793 fn to_tokens(&self, tokens: &mut Tokens) {
2794 self.path.to_tokens(tokens);
2795 self.brace_token.surround(tokens, |tokens| {
2796 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002797 // NOTE: We need a comma before the dot2 token if it is present.
2798 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002799 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002800 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002801 self.dot2_token.to_tokens(tokens);
2802 });
2803 }
2804 }
2805
Michael Layzell734adb42017-06-07 16:58:31 -04002806 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002807 impl ToTokens for PatTupleStruct {
2808 fn to_tokens(&self, tokens: &mut Tokens) {
2809 self.path.to_tokens(tokens);
2810 self.pat.to_tokens(tokens);
2811 }
2812 }
2813
Michael Layzell734adb42017-06-07 16:58:31 -04002814 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002815 impl ToTokens for PatPath {
2816 fn to_tokens(&self, tokens: &mut Tokens) {
2817 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2818 }
2819 }
2820
Michael Layzell734adb42017-06-07 16:58:31 -04002821 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002822 impl ToTokens for PatTuple {
2823 fn to_tokens(&self, tokens: &mut Tokens) {
2824 self.paren_token.surround(tokens, |tokens| {
2825 for (i, token) in self.pats.iter().enumerate() {
2826 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002827 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2828 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002829 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002830 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002831 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002832
2833 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002834 // Ensure there is a comma before the .. token.
2835 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002836 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002837 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002838 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002839 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002840 });
2841 }
2842 }
2843
Michael Layzell734adb42017-06-07 16:58:31 -04002844 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002845 impl ToTokens for PatBox {
2846 fn to_tokens(&self, tokens: &mut Tokens) {
2847 self.box_token.to_tokens(tokens);
2848 self.pat.to_tokens(tokens);
2849 }
2850 }
2851
Michael Layzell734adb42017-06-07 16:58:31 -04002852 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002853 impl ToTokens for PatRef {
2854 fn to_tokens(&self, tokens: &mut Tokens) {
2855 self.and_token.to_tokens(tokens);
2856 self.mutbl.to_tokens(tokens);
2857 self.pat.to_tokens(tokens);
2858 }
2859 }
2860
Michael Layzell734adb42017-06-07 16:58:31 -04002861 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002862 impl ToTokens for PatLit {
2863 fn to_tokens(&self, tokens: &mut Tokens) {
2864 self.expr.to_tokens(tokens);
2865 }
2866 }
2867
Michael Layzell734adb42017-06-07 16:58:31 -04002868 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002869 impl ToTokens for PatRange {
2870 fn to_tokens(&self, tokens: &mut Tokens) {
2871 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002872 match self.limits {
2873 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2874 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2875 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002876 self.hi.to_tokens(tokens);
2877 }
2878 }
2879
Michael Layzell734adb42017-06-07 16:58:31 -04002880 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002881 impl ToTokens for PatSlice {
2882 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002883 // XXX: This is a mess, and it will be so easy to screw it up. How
2884 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002885 self.bracket_token.surround(tokens, |tokens| {
2886 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002887
2888 // If we need a comma before the middle or standalone .. token,
2889 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002890 if !self.front.empty_or_trailing()
2891 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002892 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002893 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002894 }
2895
2896 // If we have an identifier, we always need a .. token.
2897 if self.middle.is_some() {
2898 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002899 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002900 } else if self.dot2_token.is_some() {
2901 self.dot2_token.to_tokens(tokens);
2902 }
2903
2904 // Make sure we have a comma before the back half.
2905 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002906 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002907 self.back.to_tokens(tokens);
2908 } else {
2909 self.comma_token.to_tokens(tokens);
2910 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002911 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002912 }
2913 }
2914
Michael Layzell734adb42017-06-07 16:58:31 -04002915 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002916 impl ToTokens for FieldPat {
2917 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002918 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002919 if !self.is_shorthand {
2920 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002921 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002922 }
2923 self.pat.to_tokens(tokens);
2924 }
2925 }
2926
Michael Layzell734adb42017-06-07 16:58:31 -04002927 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002928 impl ToTokens for BindingMode {
2929 fn to_tokens(&self, tokens: &mut Tokens) {
2930 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002931 BindingMode::ByRef(ref t, ref m) => {
2932 t.to_tokens(tokens);
2933 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002934 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002935 BindingMode::ByValue(ref m) => {
2936 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002937 }
2938 }
2939 }
2940 }
David Tolnay42602292016-10-01 22:25:45 -07002941
Michael Layzell734adb42017-06-07 16:58:31 -04002942 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002943 impl ToTokens for CaptureBy {
2944 fn to_tokens(&self, tokens: &mut Tokens) {
2945 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002946 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002947 CaptureBy::Ref => {
2948 // nothing
2949 }
David Tolnay89e05672016-10-02 14:39:42 -07002950 }
2951 }
2952 }
2953
Michael Layzell734adb42017-06-07 16:58:31 -04002954 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002955 impl ToTokens for Block {
2956 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002957 self.brace_token.surround(tokens, |tokens| {
2958 tokens.append_all(&self.stmts);
2959 });
David Tolnay42602292016-10-01 22:25:45 -07002960 }
2961 }
2962
Michael Layzell734adb42017-06-07 16:58:31 -04002963 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002964 impl ToTokens for Stmt {
2965 fn to_tokens(&self, tokens: &mut Tokens) {
2966 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002967 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002968 Stmt::Item(ref item) => item.to_tokens(tokens),
2969 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002970 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002971 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002972 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002973 }
David Tolnaydecf28d2017-11-11 11:56:45 -08002974 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002975 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002976 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002977 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002978 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002979 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002980 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2981 // no semicolon
2982 }
David Tolnay13b3d352016-10-03 00:31:15 -07002983 }
2984 }
David Tolnay42602292016-10-01 22:25:45 -07002985 }
2986 }
2987 }
David Tolnay191e0582016-10-02 18:31:09 -07002988
Michael Layzell734adb42017-06-07 16:58:31 -04002989 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002990 impl ToTokens for Local {
2991 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002992 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002993 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002994 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002995 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002996 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002997 self.ty.to_tokens(tokens);
2998 }
2999 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003000 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003001 self.init.to_tokens(tokens);
3002 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003003 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003004 }
3005 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003006}