blob: cec6dc2cea38d9a1bef1f28233bbd25d00d4be9a [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay85b69a42017-12-27 20:43:10 -05003#[cfg(feature = "full")]
4use proc_macro2::Span;
5#[cfg(feature = "full")]
6use std::hash::{Hash, Hasher};
David Tolnayf4bbbd92016-09-23 14:41:55 -07007
Alex Crichton62a0a592017-05-22 13:58:53 -07008ast_struct! {
9 /// An expression.
10 pub struct Expr {
11 /// Type of the expression.
12 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -050013
Alex Crichton62a0a592017-05-22 13:58:53 -070014 /// Attributes tagged on the expression.
15 pub attrs: Vec<Attribute>,
16 }
David Tolnay7184b132016-10-30 10:06:37 -070017}
18
19impl From<ExprKind> for Expr {
20 fn from(node: ExprKind) -> Expr {
21 Expr {
22 node: node,
23 attrs: Vec::new(),
24 }
25 }
26}
27
Alex Crichton62a0a592017-05-22 13:58:53 -070028ast_enum_of_structs! {
29 pub enum ExprKind {
30 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040031 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070032 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080033 pub box_token: Token![box],
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
Clar Charrd22b5702017-03-10 15:24:56 -050035
Michael Layzellb78f3b52017-06-04 19:03:03 -040036 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040037 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070038 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040039 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070040 pub value: Box<Expr>,
41 }),
Clar Charrd22b5702017-03-10 15:24:56 -050042
Alex Crichton62a0a592017-05-22 13:58:53 -070043 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040044 pub Array(ExprArray #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080045 pub exprs: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050046 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070047 }),
Clar Charrd22b5702017-03-10 15:24:56 -050048
Alex Crichton62a0a592017-05-22 13:58:53 -070049 /// A function call.
50 pub Call(ExprCall {
51 pub func: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080052 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050053 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070054 }),
Clar Charrd22b5702017-03-10 15:24:56 -050055
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
57 ///
58 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080059 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070060 /// (within the angle brackets).
61 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070062 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
63 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040064 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070066 pub method: Ident,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080067 pub typarams: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080068 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050069 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080070 pub dot_token: Token![.],
71 pub lt_token: Option<Token![<]>,
72 pub colon2_token: Option<Token![::]>,
73 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 }),
Clar Charrd22b5702017-03-10 15:24:56 -050075
Alex Crichton62a0a592017-05-22 13:58:53 -070076 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050077 pub Tuple(ExprTuple #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080078 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050079 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080080 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070081 }),
Clar Charrd22b5702017-03-10 15:24:56 -050082
Alex Crichton62a0a592017-05-22 13:58:53 -070083 /// A binary operation, e.g. `a + b`, `a * b`.
84 pub Binary(ExprBinary {
85 pub op: BinOp,
86 pub left: Box<Expr>,
87 pub right: Box<Expr>,
88 }),
Clar Charrd22b5702017-03-10 15:24:56 -050089
Alex Crichton62a0a592017-05-22 13:58:53 -070090 /// A unary operation, e.g. `!x`, `*x`.
91 pub Unary(ExprUnary {
92 pub op: UnOp,
93 pub expr: Box<Expr>,
94 }),
Clar Charrd22b5702017-03-10 15:24:56 -050095
Alex Crichton62a0a592017-05-22 13:58:53 -070096 /// A literal, e.g. `1`, `"foo"`.
97 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050098
Alex Crichton62a0a592017-05-22 13:58:53 -070099 /// A cast, e.g. `foo as f64`.
100 pub Cast(ExprCast {
101 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800102 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800103 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500105
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 /// A type ascription, e.g. `foo: f64`.
107 pub Type(ExprType {
108 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800109 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800110 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500112
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 /// An `if` block, with an optional else block
114 ///
115 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400116 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700117 pub cond: Box<Expr>,
118 pub if_true: Block,
119 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800120 pub if_token: Token![if],
121 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700122 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500123
Alex Crichton62a0a592017-05-22 13:58:53 -0700124 /// An `if let` expression with an optional else block
125 ///
126 /// E.g., `if let pat = expr { block } else { expr }`
127 ///
128 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400129 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700130 pub pat: Box<Pat>,
131 pub expr: Box<Expr>,
132 pub if_true: Block,
133 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800134 pub if_token: Token![if],
135 pub let_token: Token![let],
136 pub eq_token: Token![=],
137 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700138 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500139
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 /// A while loop, with an optional label
141 ///
142 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400143 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700144 pub cond: Box<Expr>,
145 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700146 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800147 pub colon_token: Option<Token![:]>,
148 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700149 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500150
Alex Crichton62a0a592017-05-22 13:58:53 -0700151 /// A while-let loop, with an optional label.
152 ///
153 /// E.g., `'label: while let pat = expr { block }`
154 ///
155 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400156 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700157 pub pat: Box<Pat>,
158 pub expr: Box<Expr>,
159 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700160 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800161 pub colon_token: Option<Token![:]>,
162 pub while_token: Token![while],
163 pub let_token: Token![let],
164 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700165 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500166
Alex Crichton62a0a592017-05-22 13:58:53 -0700167 /// A for loop, with an optional label.
168 ///
169 /// E.g., `'label: for pat in expr { block }`
170 ///
171 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400172 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 pub pat: Box<Pat>,
174 pub expr: Box<Expr>,
175 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700176 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800177 pub for_token: Token![for],
178 pub colon_token: Option<Token![:]>,
179 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700180 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500181
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 /// Conditionless loop with an optional label.
183 ///
184 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400185 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700187 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800188 pub loop_token: Token![loop],
189 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500191
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400193 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800194 pub match_token: Token![match],
David Tolnay32954ef2017-12-26 22:43:16 -0500195 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 pub expr: Box<Expr>,
197 pub arms: Vec<Arm>,
198 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500199
Alex Crichton62a0a592017-05-22 13:58:53 -0700200 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400201 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700202 pub capture: CaptureBy,
203 pub decl: Box<FnDecl>,
204 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800205 pub or1_token: Token![|],
206 pub or2_token: Token![|],
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500208
Nika Layzell640832a2017-12-04 13:37:09 -0500209 /// An unsafe block (`unsafe { ... }`)
210 pub Unsafe(ExprUnsafe #full {
211 pub unsafe_token: Token![unsafe],
212 pub block: Block,
213 }),
214
215 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400216 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700217 pub block: Block,
218 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700219
Alex Crichton62a0a592017-05-22 13:58:53 -0700220 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub left: Box<Expr>,
223 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800224 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// An assignment with an operator
228 ///
229 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400230 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 pub op: BinOp,
232 pub left: Box<Expr>,
233 pub right: Box<Expr>,
234 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500235
David Tolnay85b69a42017-12-27 20:43:10 -0500236 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
237 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400238 pub Field(ExprField #full {
David Tolnay85b69a42017-12-27 20:43:10 -0500239 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800240 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500241 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500243
Alex Crichton62a0a592017-05-22 13:58:53 -0700244 /// An indexing operation (`foo[2]`)
245 pub Index(ExprIndex {
246 pub expr: Box<Expr>,
247 pub index: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500248 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500250
David Tolnaybe55d7b2017-12-17 23:41:20 -0800251 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400252 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 pub from: Option<Box<Expr>>,
254 pub to: Option<Box<Expr>>,
255 pub limits: RangeLimits,
256 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700257
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 /// Variable reference, possibly containing `::` and/or type
259 /// parameters, e.g. foo::bar::<baz>.
260 ///
261 /// Optionally "qualified",
262 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
263 pub Path(ExprPath {
264 pub qself: Option<QSelf>,
265 pub path: Path,
266 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700267
Alex Crichton62a0a592017-05-22 13:58:53 -0700268 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400269 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800270 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 pub mutbl: Mutability,
272 pub expr: Box<Expr>,
273 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500274
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400276 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700277 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700278 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800279 pub break_token: Token![break],
Alex Crichton62a0a592017-05-22 13:58:53 -0700280 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500281
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400283 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700284 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800285 pub continue_token: Token![continue],
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500287
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400289 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700290 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800291 pub return_token: Token![return],
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700293
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800295 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700296
Alex Crichton62a0a592017-05-22 13:58:53 -0700297 /// A struct literal expression.
298 ///
299 /// For example, `Foo {x: 1, y: 2}`, or
300 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400301 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700302 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800303 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700304 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800305 pub dot2_token: Option<Token![..]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500306 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700307 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700308
Alex Crichton62a0a592017-05-22 13:58:53 -0700309 /// An array literal constructed from one repeated element.
310 ///
311 /// For example, `[1; 5]`. The first expression is the element
312 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400313 pub Repeat(ExprRepeat #full {
David Tolnay32954ef2017-12-26 22:43:16 -0500314 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800315 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700316 pub expr: Box<Expr>,
317 pub amt: Box<Expr>,
318 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700319
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 /// No-op: used solely so we can pretty-print faithfully
321 pub Paren(ExprParen {
322 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500323 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700325
Michael Layzell93c36282017-06-04 20:43:14 -0400326 /// No-op: used solely so we can pretty-print faithfully
327 ///
328 /// A `group` represents a `None`-delimited span in the input
329 /// `TokenStream` which affects the precidence of the resulting
330 /// expression. They are used for macro hygiene.
331 pub Group(ExprGroup {
332 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500333 pub group_token: token::Group,
Michael Layzell93c36282017-06-04 20:43:14 -0400334 }),
335
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400337 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700338 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800339 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700340 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700341
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 /// A catch expression.
343 ///
344 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400345 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800346 pub do_token: Token![do],
347 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700348 pub block: Block,
349 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700350
351 /// A yield expression.
352 ///
353 /// E.g. `yield expr`
354 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800355 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700356 pub expr: Option<Box<Expr>>,
357 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700358 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700359}
360
Michael Layzell734adb42017-06-07 16:58:31 -0400361#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500362ast_enum! {
363 /// A struct or tuple struct field accessed in a struct literal or field
364 /// expression.
365 pub enum Member {
366 /// A named field like `self.x`.
367 Named(Ident),
368 /// An unnamed field like `self.0`.
369 Unnamed(Index),
370 }
371}
372
373#[cfg(feature = "full")]
374ast_struct! {
375 /// The index of an unnamed tuple struct field.
376 pub struct Index #manual_extra_traits {
377 pub index: u32,
378 pub span: Span,
379 }
380}
381
382#[cfg(feature = "full")]
383impl Eq for Index {}
384
385#[cfg(feature = "full")]
386impl PartialEq for Index {
387 fn eq(&self, other: &Self) -> bool {
388 self.index == other.index
389 }
390}
391
392#[cfg(feature = "full")]
393impl Hash for Index {
394 fn hash<H: Hasher>(&self, state: &mut H) {
395 self.index.hash(state);
396 }
397}
398
399#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700400ast_struct! {
401 /// A field-value pair in a struct literal.
402 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500403 /// Attributes tagged on the field.
404 pub attrs: Vec<Attribute>,
405
406 /// Name or index of the field.
407 pub member: Member,
408
409 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// Value of the field.
412 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// Whether this is a shorthand field, e.g. `Struct { x }`
415 /// instead of `Struct { x: x }`.
416 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700417 }
David Tolnay055a7042016-10-02 19:23:54 -0700418}
419
Michael Layzell734adb42017-06-07 16:58:31 -0400420#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700421ast_struct! {
422 /// A Block (`{ .. }`).
423 ///
424 /// E.g. `{ .. }` as in `fn foo() { .. }`
425 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500426 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700427 /// Statements in a block
428 pub stmts: Vec<Stmt>,
429 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700430}
431
Michael Layzell734adb42017-06-07 16:58:31 -0400432#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700433ast_enum! {
434 /// A statement, usually ending in a semicolon.
435 pub enum Stmt {
436 /// A local (let) binding.
437 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700438
Alex Crichton62a0a592017-05-22 13:58:53 -0700439 /// An item definition.
440 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 /// Expr without trailing semicolon.
443 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800446 Semi(Box<Expr>, Token![;]),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700447
Alex Crichton62a0a592017-05-22 13:58:53 -0700448 /// Macro invocation.
David Tolnaydecf28d2017-11-11 11:56:45 -0800449 Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700450 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700451}
452
Michael Layzell734adb42017-06-07 16:58:31 -0400453#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700454ast_enum! {
455 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700456 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700457 pub enum MacStmtStyle {
458 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
459 /// `foo!(...);`, `foo![...];`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800460 Semicolon(Token![;]),
Clar Charrd22b5702017-03-10 15:24:56 -0500461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// The macro statement had braces; e.g. foo! { ... }
463 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500464
Alex Crichton62a0a592017-05-22 13:58:53 -0700465 /// The macro statement had parentheses or brackets and no semicolon; e.g.
466 /// `foo!(...)`. All of these will end up being converted into macro
467 /// expressions.
468 NoBraces,
469 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700470}
471
Michael Layzell734adb42017-06-07 16:58:31 -0400472#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700473ast_struct! {
474 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
475 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800476 pub let_token: Token![let],
477 pub colon_token: Option<Token![:]>,
478 pub eq_token: Option<Token![=]>,
479 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480
Alex Crichton62a0a592017-05-22 13:58:53 -0700481 pub pat: Box<Pat>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800482 pub ty: Option<Box<Type>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500483
Alex Crichton62a0a592017-05-22 13:58:53 -0700484 /// Initializer expression to set the value, if any
485 pub init: Option<Box<Expr>>,
486 pub attrs: Vec<Attribute>,
487 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700488}
489
Michael Layzell734adb42017-06-07 16:58:31 -0400490#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700491ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700492 // Clippy false positive
493 // https://github.com/Manishearth/rust-clippy/issues/1241
494 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
495 pub enum Pat {
496 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700497 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800498 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700499 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700500
Alex Crichton62a0a592017-05-22 13:58:53 -0700501 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
502 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
503 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
504 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700505 pub Ident(PatIdent {
506 pub mode: BindingMode,
507 pub ident: Ident,
508 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800509 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700510 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700511
Alex Crichton62a0a592017-05-22 13:58:53 -0700512 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
513 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700514 pub Struct(PatStruct {
515 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800516 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500517 pub brace_token: token::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800518 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700519 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700520
Alex Crichton62a0a592017-05-22 13:58:53 -0700521 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
522 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
523 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700524 pub TupleStruct(PatTupleStruct {
525 pub path: Path,
526 pub pat: PatTuple,
527 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700528
Alex Crichton62a0a592017-05-22 13:58:53 -0700529 /// A possibly qualified path pattern.
530 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
531 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
532 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700533 pub Path(PatPath {
534 pub qself: Option<QSelf>,
535 pub path: Path,
536 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700537
Alex Crichton62a0a592017-05-22 13:58:53 -0700538 /// A tuple pattern `(a, b)`.
539 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
540 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700541 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800542 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700543 pub dots_pos: Option<usize>,
David Tolnay32954ef2017-12-26 22:43:16 -0500544 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800545 pub dot2_token: Option<Token![..]>,
546 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700547 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700548 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700549 pub Box(PatBox {
550 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800551 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700552 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700553 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700554 pub Ref(PatRef {
555 pub pat: Box<Pat>,
556 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800557 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700559 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700560 pub Lit(PatLit {
561 pub expr: Box<Expr>,
562 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800563 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700564 pub Range(PatRange {
565 pub lo: Box<Expr>,
566 pub hi: Box<Expr>,
567 pub limits: RangeLimits,
568 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400569 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700570 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800571 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800573 pub back: Delimited<Pat, Token![,]>,
574 pub dot2_token: Option<Token![..]>,
575 pub comma_token: Option<Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500576 pub bracket_token: token::Bracket,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700577 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700578 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800579 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700580 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700581}
582
Michael Layzell734adb42017-06-07 16:58:31 -0400583#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700584ast_struct! {
585 /// An arm of a 'match'.
586 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800587 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700588 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500589 /// ```rust
590 /// # #![feature(dotdoteq_in_patterns)]
591 /// #
592 /// # fn main() {
593 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700594 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500595 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700596 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500597 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700598 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500599 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700600 /// ```
601 pub struct Arm {
602 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800603 pub pats: Delimited<Pat, Token![|]>,
604 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800606 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700607 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800608 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700609 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700610}
611
Michael Layzell734adb42017-06-07 16:58:31 -0400612#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700613ast_enum! {
614 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700615 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700616 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800617 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700618 Ref,
619 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700620}
621
Michael Layzell734adb42017-06-07 16:58:31 -0400622#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700623ast_enum! {
624 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700625 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700626 pub enum RangeLimits {
627 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800628 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700629 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800630 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700631 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700632}
633
Michael Layzell734adb42017-06-07 16:58:31 -0400634#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700635ast_struct! {
636 /// A single field in a struct pattern
637 ///
638 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
639 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
640 /// except `is_shorthand` is true
641 pub struct FieldPat {
642 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500643 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700644 /// The pattern the field is destructured to
645 pub pat: Box<Pat>,
646 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800647 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700648 pub attrs: Vec<Attribute>,
649 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700650}
651
Michael Layzell734adb42017-06-07 16:58:31 -0400652#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700653ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700654 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700655 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800656 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700657 ByValue(Mutability),
658 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700659}
660
Michael Layzell734adb42017-06-07 16:58:31 -0400661#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400662ast_enum! {
663 #[cfg_attr(feature = "clone-impls", derive(Copy))]
664 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800665 Arrow(Token![<-]),
666 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400667 }
668}
669
Michael Layzell3936ceb2017-07-08 00:28:36 -0400670#[cfg(any(feature = "parsing", feature = "printing"))]
671#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700672fn arm_expr_requires_comma(expr: &Expr) -> bool {
673 // see https://github.com/rust-lang/rust/blob/eb8f2586e
674 // /src/libsyntax/parse/classify.rs#L17-L37
675 match expr.node {
David Tolnay51382052017-12-27 13:46:21 -0500676 ExprKind::Unsafe(..)
677 | ExprKind::Block(..)
678 | ExprKind::If(..)
679 | ExprKind::IfLet(..)
680 | ExprKind::Match(..)
681 | ExprKind::While(..)
682 | ExprKind::WhileLet(..)
683 | ExprKind::Loop(..)
684 | ExprKind::ForLoop(..)
685 | ExprKind::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700686 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400687 }
688}
689
David Tolnayb9c8e322016-09-23 20:48:37 -0700690#[cfg(feature = "parsing")]
691pub mod parsing {
692 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700693 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700694
Michael Layzell734adb42017-06-07 16:58:31 -0400695 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500696 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500697 use synom::Synom;
698 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400699 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500700 use parse_error;
701 use PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700702
David Tolnaybcf26022017-12-25 22:10:52 -0500703 // When we're parsing expressions which occur before blocks, like in an if
704 // statement's condition, we cannot parse a struct literal.
705 //
706 // Struct literals are ambiguous in certain positions
707 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700708 macro_rules! ambiguous_expr {
709 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700710 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700711 };
712 }
713
David Tolnaybcf26022017-12-25 22:10:52 -0500714 // When we are parsing an optional suffix expression, we cannot allow blocks
715 // if structs are not allowed.
716 //
717 // Example:
718 //
719 // if break {} {}
720 //
721 // is ambiguous between:
722 //
723 // if (break {}) {}
724 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400725 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400726 macro_rules! opt_ambiguous_expr {
727 ($i:expr, $allow_struct:ident) => {
728 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
729 };
730 }
731
Alex Crichton954046c2017-05-30 21:49:42 -0700732 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400733 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700734
735 fn description() -> Option<&'static str> {
736 Some("expression")
737 }
738 }
739
Michael Layzell734adb42017-06-07 16:58:31 -0400740 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700741 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
742
David Tolnaybcf26022017-12-25 22:10:52 -0500743 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400744 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500745 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400746 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700747 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400748 call!(assign_expr, allow_struct, allow_block),
749 ExprKind::into
750 )
751 }
752
Michael Layzell734adb42017-06-07 16:58:31 -0400753 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500754 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzell734adb42017-06-07 16:58:31 -0400755 map!(
756 i,
757 // NOTE: We intentionally skip assign_expr, placement_expr, and
758 // range_expr, as they are not parsed in non-full mode.
759 call!(or_expr, allow_struct, allow_block),
760 ExprKind::into
761 )
762 }
763
David Tolnaybcf26022017-12-25 22:10:52 -0500764 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400765 macro_rules! binop {
766 (
767 $name: ident,
768 $next: ident,
769 $submac: ident!( $($args:tt)* )
770 ) => {
771 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
772 mut e: call!($next, allow_struct, allow_block) >>
773 many0!(do_parse!(
774 op: $submac!($($args)*) >>
775 rhs: call!($next, allow_struct, true) >>
776 ({
777 e = ExprBinary {
778 left: Box::new(e.into()),
779 op: op,
780 right: Box::new(rhs.into()),
781 }.into();
782 })
783 )) >>
784 (e)
785 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700786 }
David Tolnay54e854d2016-10-24 12:03:30 -0700787 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700788
David Tolnaybcf26022017-12-25 22:10:52 -0500789 // <placement> = <placement> ..
790 // <placement> += <placement> ..
791 // <placement> -= <placement> ..
792 // <placement> *= <placement> ..
793 // <placement> /= <placement> ..
794 // <placement> %= <placement> ..
795 // <placement> ^= <placement> ..
796 // <placement> &= <placement> ..
797 // <placement> |= <placement> ..
798 // <placement> <<= <placement> ..
799 // <placement> >>= <placement> ..
800 //
801 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400802 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400803 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
804 mut e: call!(placement_expr, allow_struct, allow_block) >>
805 alt!(
806 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800807 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400808 // Recurse into self to parse right-associative operator.
809 rhs: call!(assign_expr, allow_struct, true) >>
810 ({
811 e = ExprAssign {
812 left: Box::new(e.into()),
813 eq_token: eq,
814 right: Box::new(rhs.into()),
815 }.into();
816 })
817 )
818 |
819 do_parse!(
820 op: call!(BinOp::parse_assign_op) >>
821 // Recurse into self to parse right-associative operator.
822 rhs: call!(assign_expr, allow_struct, true) >>
823 ({
824 e = ExprAssignOp {
825 left: Box::new(e.into()),
826 op: op,
827 right: Box::new(rhs.into()),
828 }.into();
829 })
830 )
831 |
832 epsilon!()
833 ) >>
834 (e)
835 ));
836
David Tolnaybcf26022017-12-25 22:10:52 -0500837 // <range> <- <range> ..
838 //
839 // NOTE: The `in place { expr }` version of this syntax is parsed in
840 // `atom_expr`, not here.
841 //
842 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400843 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400844 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
845 mut e: call!(range_expr, allow_struct, allow_block) >>
846 alt!(
847 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800848 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400849 // Recurse into self to parse right-associative operator.
850 rhs: call!(placement_expr, allow_struct, true) >>
851 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400852 e = ExprInPlace {
853 // op: BinOp::Place(larrow),
854 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400855 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400856 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400857 }.into();
858 })
859 )
860 |
861 epsilon!()
862 ) >>
863 (e)
864 ));
865
David Tolnaybcf26022017-12-25 22:10:52 -0500866 // <or> ... <or> ..
867 // <or> .. <or> ..
868 // <or> ..
869 //
870 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
871 // rules are for parsing these expressions are, but this is not correct.
872 // For example, `a .. b .. c` is not a legal expression. It should not
873 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
874 //
875 // NOTE: The form of ranges which don't include a preceding expression are
876 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400877 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400878 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
879 mut e: call!(or_expr, allow_struct, allow_block) >>
880 many0!(do_parse!(
881 limits: syn!(RangeLimits) >>
882 // We don't want to allow blocks here if we don't allow structs. See
883 // the reasoning for `opt_ambiguous_expr!` above.
884 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
885 ({
886 e = ExprRange {
887 from: Some(Box::new(e.into())),
888 limits: limits,
889 to: hi.map(|e| Box::new(e.into())),
890 }.into();
891 })
892 )) >>
893 (e)
894 ));
895
David Tolnaybcf26022017-12-25 22:10:52 -0500896 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800897 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400898
David Tolnaybcf26022017-12-25 22:10:52 -0500899 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800900 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400901
David Tolnaybcf26022017-12-25 22:10:52 -0500902 // <bitor> == <bitor> ...
903 // <bitor> != <bitor> ...
904 // <bitor> >= <bitor> ...
905 // <bitor> <= <bitor> ...
906 // <bitor> > <bitor> ...
907 // <bitor> < <bitor> ...
908 //
909 // NOTE: This operator appears to be parsed as left-associative, but errors
910 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500911 binop!(
912 compare_expr,
913 bitor_expr,
914 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800915 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400916 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800917 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400918 |
919 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800920 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400921 |
922 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800923 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400924 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400925 do_parse!(
926 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800927 not!(punct!(<-)) >>
928 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400929 (BinOp::Lt(t))
930 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400931 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800932 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500933 )
934 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400935
David Tolnaybcf26022017-12-25 22:10:52 -0500936 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500937 binop!(
938 bitor_expr,
939 bitxor_expr,
940 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
941 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400942
David Tolnaybcf26022017-12-25 22:10:52 -0500943 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500944 binop!(
945 bitxor_expr,
946 bitand_expr,
947 do_parse!(
948 // NOTE: Make sure we aren't looking at ^=.
949 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
950 )
951 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400952
David Tolnaybcf26022017-12-25 22:10:52 -0500953 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -0500954 binop!(
955 bitand_expr,
956 shift_expr,
957 do_parse!(
958 // NOTE: Make sure we aren't looking at && or &=.
959 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
960 )
961 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400962
David Tolnaybcf26022017-12-25 22:10:52 -0500963 // <arith> << <arith> ...
964 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -0500965 binop!(
966 shift_expr,
967 arith_expr,
968 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800969 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400970 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800971 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -0500972 )
973 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400974
David Tolnaybcf26022017-12-25 22:10:52 -0500975 // <term> + <term> ...
976 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -0500977 binop!(
978 arith_expr,
979 term_expr,
980 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800981 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400982 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800983 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -0500984 )
985 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400986
David Tolnaybcf26022017-12-25 22:10:52 -0500987 // <cast> * <cast> ...
988 // <cast> / <cast> ...
989 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -0500990 binop!(
991 term_expr,
992 cast_expr,
993 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800994 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400995 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800996 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400997 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800998 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -0500999 )
1000 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001001
David Tolnaybcf26022017-12-25 22:10:52 -05001002 // <unary> as <ty>
1003 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001004 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1005 mut e: call!(unary_expr, allow_struct, allow_block) >>
1006 many0!(alt!(
1007 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001008 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001009 // We can't accept `A + B` in cast expressions, as it's
1010 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001011 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001012 ({
1013 e = ExprCast {
1014 expr: Box::new(e.into()),
1015 as_token: as_,
1016 ty: Box::new(ty),
1017 }.into();
1018 })
1019 )
1020 |
1021 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001022 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001023 // We can't accept `A + B` in cast expressions, as it's
1024 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001025 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001026 ({
1027 e = ExprType {
1028 expr: Box::new(e.into()),
1029 colon_token: colon,
1030 ty: Box::new(ty),
1031 }.into();
1032 })
1033 )
1034 )) >>
1035 (e)
1036 ));
1037
David Tolnaybcf26022017-12-25 22:10:52 -05001038 // <UnOp> <trailer>
1039 // & <trailer>
1040 // &mut <trailer>
1041 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001042 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001043 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1044 do_parse!(
1045 op: syn!(UnOp) >>
1046 expr: call!(unary_expr, allow_struct, true) >>
1047 (ExprUnary {
1048 op: op,
1049 expr: Box::new(expr.into()),
1050 }.into())
1051 )
1052 |
1053 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001054 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001055 mutability: syn!(Mutability) >>
1056 expr: call!(unary_expr, allow_struct, true) >>
1057 (ExprAddrOf {
1058 and_token: and,
1059 mutbl: mutability,
1060 expr: Box::new(expr.into()),
1061 }.into())
1062 )
1063 |
1064 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001065 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001066 expr: call!(unary_expr, allow_struct, true) >>
1067 (ExprBox {
1068 box_token: box_,
1069 expr: Box::new(expr.into()),
1070 }.into())
1071 )
1072 |
1073 call!(trailer_expr, allow_struct, allow_block)
1074 ));
1075
Michael Layzell734adb42017-06-07 16:58:31 -04001076 // XXX: This duplication is ugly
1077 #[cfg(not(feature = "full"))]
1078 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1079 do_parse!(
1080 op: syn!(UnOp) >>
1081 expr: call!(unary_expr, allow_struct, true) >>
1082 (ExprUnary {
1083 op: op,
1084 expr: Box::new(expr.into()),
1085 }.into())
1086 )
1087 |
1088 call!(trailer_expr, allow_struct, allow_block)
1089 ));
1090
David Tolnaybcf26022017-12-25 22:10:52 -05001091 // <atom> (..<args>) ...
1092 // <atom> . <ident> (..<args>) ...
1093 // <atom> . <ident> ...
1094 // <atom> . <lit> ...
1095 // <atom> [ <expr> ] ...
1096 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001097 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001098 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1099 mut e: call!(atom_expr, allow_struct, allow_block) >>
1100 many0!(alt!(
1101 tap!(args: and_call => {
1102 let (args, paren) = args;
1103 e = ExprCall {
1104 func: Box::new(e.into()),
1105 args: args,
1106 paren_token: paren,
1107 }.into();
1108 })
1109 |
1110 tap!(more: and_method_call => {
1111 let mut call = more;
1112 call.expr = Box::new(e.into());
1113 e = call.into();
1114 })
1115 |
1116 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001117 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001118 e = ExprField {
David Tolnay85b69a42017-12-27 20:43:10 -05001119 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001120 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001121 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001122 }.into();
1123 })
1124 |
1125 tap!(i: and_index => {
1126 let (i, token) = i;
1127 e = ExprIndex {
1128 expr: Box::new(e.into()),
1129 bracket_token: token,
1130 index: Box::new(i),
1131 }.into();
1132 })
1133 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001134 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001135 e = ExprTry {
1136 expr: Box::new(e.into()),
1137 question_token: question,
1138 }.into();
1139 })
1140 )) >>
1141 (e)
1142 ));
1143
Michael Layzell734adb42017-06-07 16:58:31 -04001144 // XXX: Duplication == ugly
1145 #[cfg(not(feature = "full"))]
1146 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1147 mut e: call!(atom_expr, allow_struct, allow_block) >>
1148 many0!(alt!(
1149 tap!(args: and_call => {
1150 let (args, paren) = args;
1151 e = ExprCall {
1152 func: Box::new(e.into()),
1153 args: args,
1154 paren_token: paren,
1155 }.into();
1156 })
1157 |
1158 tap!(i: and_index => {
1159 let (i, token) = i;
1160 e = ExprIndex {
1161 expr: Box::new(e.into()),
1162 bracket_token: token,
1163 index: Box::new(i),
1164 }.into();
1165 })
1166 )) >>
1167 (e)
1168 ));
1169
David Tolnaybcf26022017-12-25 22:10:52 -05001170 // Parse all atomic expressions which don't have to worry about precidence
1171 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001172 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001173 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001174 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1175 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001176 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1177 |
1178 // must be before expr_path
1179 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1180 |
1181 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1182 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001183 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001184 |
1185 call!(expr_break, allow_struct) // must be before expr_path
1186 |
1187 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1188 |
1189 call!(expr_ret, allow_struct) // must be before expr_path
1190 |
1191 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1192 syn!(ExprInPlace) => { ExprKind::InPlace }
1193 |
1194 syn!(ExprArray) => { ExprKind::Array }
1195 |
David Tolnay05362582017-12-26 01:33:57 -05001196 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001197 |
1198 syn!(ExprIf) => { ExprKind::If }
1199 |
1200 syn!(ExprIfLet) => { ExprKind::IfLet }
1201 |
1202 syn!(ExprWhile) => { ExprKind::While }
1203 |
1204 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1205 |
1206 syn!(ExprForLoop) => { ExprKind::ForLoop }
1207 |
1208 syn!(ExprLoop) => { ExprKind::Loop }
1209 |
1210 syn!(ExprMatch) => { ExprKind::Match }
1211 |
1212 syn!(ExprCatch) => { ExprKind::Catch }
1213 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001214 syn!(ExprYield) => { ExprKind::Yield }
1215 |
Nika Layzell640832a2017-12-04 13:37:09 -05001216 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1217 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001218 call!(expr_closure, allow_struct)
1219 |
1220 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1221 |
1222 // NOTE: This is the prefix-form of range
1223 call!(expr_range, allow_struct)
1224 |
1225 syn!(ExprPath) => { ExprKind::Path }
1226 |
1227 syn!(ExprRepeat) => { ExprKind::Repeat }
1228 ));
1229
Michael Layzell734adb42017-06-07 16:58:31 -04001230 #[cfg(not(feature = "full"))]
1231 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1232 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1233 |
1234 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1235 |
1236 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1237 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001238 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001239 |
1240 syn!(ExprPath) => { ExprKind::Path }
1241 ));
1242
Michael Layzell734adb42017-06-07 16:58:31 -04001243 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001244 named!(expr_nosemi -> Expr, map!(alt!(
1245 syn!(ExprIf) => { ExprKind::If }
1246 |
1247 syn!(ExprIfLet) => { ExprKind::IfLet }
1248 |
1249 syn!(ExprWhile) => { ExprKind::While }
1250 |
1251 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1252 |
1253 syn!(ExprForLoop) => { ExprKind::ForLoop }
1254 |
1255 syn!(ExprLoop) => { ExprKind::Loop }
1256 |
1257 syn!(ExprMatch) => { ExprKind::Match }
1258 |
1259 syn!(ExprCatch) => { ExprKind::Catch }
1260 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001261 syn!(ExprYield) => { ExprKind::Yield }
1262 |
Nika Layzell640832a2017-12-04 13:37:09 -05001263 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1264 |
Michael Layzell35418782017-06-07 09:20:25 -04001265 syn!(ExprBlock) => { ExprKind::Block }
1266 ), Expr::from));
1267
Michael Layzell93c36282017-06-04 20:43:14 -04001268 impl Synom for ExprGroup {
1269 named!(parse -> Self, do_parse!(
1270 e: grouped!(syn!(Expr)) >>
1271 (ExprGroup {
1272 expr: Box::new(e.0),
1273 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001274 })
Michael Layzell93c36282017-06-04 20:43:14 -04001275 ));
1276 }
1277
Alex Crichton954046c2017-05-30 21:49:42 -07001278 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001279 named!(parse -> Self, do_parse!(
1280 e: parens!(syn!(Expr)) >>
1281 (ExprParen {
1282 expr: Box::new(e.0),
1283 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001284 })
Michael Layzell92639a52017-06-01 00:07:44 -04001285 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001286 }
David Tolnay89e05672016-10-02 14:39:42 -07001287
Michael Layzell734adb42017-06-07 16:58:31 -04001288 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001289 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001290 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001291 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001292 place: expr_no_struct >>
1293 value: braces!(call!(Block::parse_within)) >>
1294 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001295 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001296 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001297 value: Box::new(Expr {
1298 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001299 block: Block {
1300 stmts: value.0,
1301 brace_token: value.1,
1302 },
1303 }.into(),
1304 attrs: Vec::new(),
1305 }),
1306 })
1307 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001308 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001309
Michael Layzell734adb42017-06-07 16:58:31 -04001310 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001311 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001312 named!(parse -> Self, do_parse!(
1313 elems: brackets!(call!(Delimited::parse_terminated)) >>
1314 (ExprArray {
1315 exprs: elems.0,
1316 bracket_token: elems.1,
1317 })
1318 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001319 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001320
David Tolnay32954ef2017-12-26 22:43:16 -05001321 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001322 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001323
Michael Layzell734adb42017-06-07 16:58:31 -04001324 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001325 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001326 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001327 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001328 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001329 colon2: punct!(::) >>
1330 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001331 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001332 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001333 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001334 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001335 args: parens!(call!(Delimited::parse_terminated)) >>
1336 ({
1337 let (colon2, lt, tys, gt) = match typarams {
1338 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1339 None => (None, None, None, None),
1340 };
1341 ExprMethodCall {
1342 // this expr will get overwritten after being returned
1343 expr: Box::new(ExprKind::Lit(Lit {
1344 span: Span::default(),
1345 value: LitKind::Bool(false),
1346 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001347
Alex Crichton954046c2017-05-30 21:49:42 -07001348 method: method,
1349 args: args.0,
1350 paren_token: args.1,
1351 dot_token: dot,
1352 lt_token: lt,
1353 gt_token: gt,
1354 colon2_token: colon2,
1355 typarams: tys.unwrap_or_default(),
1356 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001357 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001358 ));
1359
Michael Layzell734adb42017-06-07 16:58:31 -04001360 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001361 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001362 named!(parse -> Self, do_parse!(
1363 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001364 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001365 args: elems.0,
1366 paren_token: elems.1,
1367 lone_comma: None, // TODO: parse this
1368 })
1369 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001370 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001371
Michael Layzell734adb42017-06-07 16:58:31 -04001372 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001373 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001374 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001375 if_: keyword!(if) >>
1376 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001377 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001378 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001379 cond: expr_no_struct >>
1380 then_block: braces!(call!(Block::parse_within)) >>
1381 else_block: option!(else_block) >>
1382 (ExprIfLet {
1383 pat: Box::new(pat),
1384 let_token: let_,
1385 eq_token: eq,
1386 expr: Box::new(cond),
1387 if_true: Block {
1388 stmts: then_block.0,
1389 brace_token: then_block.1,
1390 },
1391 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001392 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001393 if_false: else_block.map(|p| Box::new(p.1.into())),
1394 })
1395 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001396 }
1397
Michael Layzell734adb42017-06-07 16:58:31 -04001398 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001399 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001400 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001401 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001402 cond: expr_no_struct >>
1403 then_block: braces!(call!(Block::parse_within)) >>
1404 else_block: option!(else_block) >>
1405 (ExprIf {
1406 cond: Box::new(cond),
1407 if_true: Block {
1408 stmts: then_block.0,
1409 brace_token: then_block.1,
1410 },
1411 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001412 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001413 if_false: else_block.map(|p| Box::new(p.1.into())),
1414 })
1415 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001416 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001417
Michael Layzell734adb42017-06-07 16:58:31 -04001418 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001419 named!(else_block -> (Token![else], ExprKind), do_parse!(
1420 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001421 expr: alt!(
1422 syn!(ExprIf) => { ExprKind::If }
1423 |
1424 syn!(ExprIfLet) => { ExprKind::IfLet }
1425 |
1426 do_parse!(
1427 else_block: braces!(call!(Block::parse_within)) >>
1428 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001429 block: Block {
1430 stmts: else_block.0,
1431 brace_token: else_block.1,
1432 },
1433 }))
David Tolnay939766a2016-09-23 23:48:12 -07001434 )
Alex Crichton954046c2017-05-30 21:49:42 -07001435 ) >>
1436 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001437 ));
1438
Michael Layzell734adb42017-06-07 16:58:31 -04001439 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001440 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001441 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001442 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1443 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001444 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001445 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001446 expr: expr_no_struct >>
1447 loop_block: syn!(Block) >>
1448 (ExprForLoop {
1449 for_token: for_,
1450 in_token: in_,
1451 pat: Box::new(pat),
1452 expr: Box::new(expr),
1453 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001454 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001455 label: lbl.map(|p| p.0),
1456 })
1457 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001458 }
Gregory Katze5f35682016-09-27 14:20:55 -04001459
Michael Layzell734adb42017-06-07 16:58:31 -04001460 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001461 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001462 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001463 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1464 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001465 loop_block: syn!(Block) >>
1466 (ExprLoop {
1467 loop_token: loop_,
1468 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001469 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001470 label: lbl.map(|p| p.0),
1471 })
1472 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001473 }
1474
Michael Layzell734adb42017-06-07 16:58:31 -04001475 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001476 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001477 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001478 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001479 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001480 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001481 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001482 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001483 ExprMatch {
1484 expr: Box::new(obj),
1485 match_token: match_,
1486 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001487 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001488 }
1489 })
1490 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001491 }
David Tolnay1978c672016-10-27 22:05:52 -07001492
Michael Layzell734adb42017-06-07 16:58:31 -04001493 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001494 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001495 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001496 do_: keyword!(do) >>
1497 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001498 catch_block: syn!(Block) >>
1499 (ExprCatch {
1500 block: catch_block,
1501 do_token: do_,
1502 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001503 })
Michael Layzell92639a52017-06-01 00:07:44 -04001504 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001505 }
Arnavion02ef13f2017-04-25 00:54:31 -07001506
Michael Layzell734adb42017-06-07 16:58:31 -04001507 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001508 impl Synom for ExprYield {
1509 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001510 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001511 expr: option!(syn!(Expr)) >>
1512 (ExprYield {
1513 yield_token: yield_,
1514 expr: expr.map(Box::new),
1515 })
1516 ));
1517 }
1518
1519 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001520 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001521 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001522 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001523 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001524 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1525 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001526 body: do_parse!(
1527 expr: alt!(expr_nosemi | syn!(Expr)) >>
1528 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1529 map!(input_end!(), |_| None)
1530 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001531 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001532 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001533 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001534 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001535 ) >>
1536 (Arm {
1537 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001538 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001539 attrs: attrs,
1540 pats: pats,
1541 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001542 body: Box::new(body.0),
1543 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001544 })
1545 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001546 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001547
Michael Layzell734adb42017-06-07 16:58:31 -04001548 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001549 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001550 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001551 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001552 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001553 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001554 ret_and_body: alt!(
1555 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001556 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001557 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001558 body: syn!(Block) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001559 (ReturnType::Type(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001560 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001561 block: body,
1562 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001563 )
1564 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001565 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001566 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001567 (ExprClosure {
1568 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001569 or1_token: or1,
1570 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001571 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001572 inputs: inputs,
1573 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001574 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001575 dot_tokens: None,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001576 fn_token: <Token![fn]>::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001577 generics: Generics::default(),
David Tolnay32954ef2017-12-26 22:43:16 -05001578 paren_token: token::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001579 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001580 body: Box::new(ret_and_body.1),
1581 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001582 ));
1583
Michael Layzell734adb42017-06-07 16:58:31 -04001584 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001585 named!(fn_arg -> FnArg, do_parse!(
1586 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001587 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001588 ({
1589 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001590 (<Token![:]>::default(), TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001591 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001592 }.into())
1593 });
1594 ArgCaptured {
1595 pat: pat,
1596 colon_token: colon,
1597 ty: ty,
1598 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001599 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001600 ));
1601
Michael Layzell734adb42017-06-07 16:58:31 -04001602 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001603 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001604 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001605 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1606 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001607 cond: expr_no_struct >>
1608 while_block: syn!(Block) >>
1609 (ExprWhile {
1610 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001611 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001612 cond: Box::new(cond),
1613 body: while_block,
1614 label: lbl.map(|p| p.0),
1615 })
1616 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001617 }
1618
Michael Layzell734adb42017-06-07 16:58:31 -04001619 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001620 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001621 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001622 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1623 while_: keyword!(while) >>
1624 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001625 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001626 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001627 value: expr_no_struct >>
1628 while_block: syn!(Block) >>
1629 (ExprWhileLet {
1630 eq_token: eq,
1631 let_token: let_,
1632 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001633 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001634 pat: Box::new(pat),
1635 expr: Box::new(value),
1636 body: while_block,
1637 label: lbl.map(|p| p.0),
1638 })
1639 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001640 }
1641
Michael Layzell734adb42017-06-07 16:58:31 -04001642 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001643 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001644 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001645 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001646 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001647 (ExprContinue {
1648 continue_token: cont,
1649 label: lbl,
1650 })
1651 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001652 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001653
Michael Layzell734adb42017-06-07 16:58:31 -04001654 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001655 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001656 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001657 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001658 // We can't allow blocks after a `break` expression when we wouldn't
1659 // allow structs, as this expression is ambiguous.
1660 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001661 (ExprBreak {
1662 label: lbl,
1663 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001664 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001665 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001666 ));
1667
Michael Layzell734adb42017-06-07 16:58:31 -04001668 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001669 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001670 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001671 // NOTE: return is greedy and eats blocks after it even when in a
1672 // position where structs are not allowed, such as in if statement
1673 // conditions. For example:
1674 //
David Tolnaybcf26022017-12-25 22:10:52 -05001675 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001676 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001677 (ExprRet {
1678 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001679 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001680 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001681 ));
1682
Michael Layzell734adb42017-06-07 16:58:31 -04001683 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001684 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001685 named!(parse -> Self, do_parse!(
1686 path: syn!(Path) >>
1687 data: braces!(do_parse!(
1688 fields: call!(Delimited::parse_terminated) >>
1689 base: option!(
1690 cond!(fields.is_empty() || fields.trailing_delim(),
1691 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001692 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001693 base: syn!(Expr) >>
1694 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001695 )
Michael Layzell92639a52017-06-01 00:07:44 -04001696 )
1697 ) >>
1698 (fields, base)
1699 )) >>
1700 ({
1701 let ((fields, base), brace) = data;
1702 let (dots, rest) = match base.and_then(|b| b) {
1703 Some((dots, base)) => (Some(dots), Some(base)),
1704 None => (None, None),
1705 };
1706 ExprStruct {
1707 brace_token: brace,
1708 path: path,
1709 fields: fields,
1710 dot2_token: dots,
1711 rest: rest.map(Box::new),
1712 }
1713 })
1714 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001715 }
1716
Michael Layzell734adb42017-06-07 16:58:31 -04001717 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001718 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001719 named!(parse -> Self, alt!(
1720 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001721 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001722 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001723 value: syn!(Expr) >>
1724 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001725 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001726 expr: value,
1727 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001728 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001729 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001730 })
Michael Layzell92639a52017-06-01 00:07:44 -04001731 )
1732 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001733 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001734 member: Member::Named(name),
Michael Layzell92639a52017-06-01 00:07:44 -04001735 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1736 is_shorthand: true,
1737 attrs: Vec::new(),
1738 colon_token: None,
1739 })
1740 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001741 }
David Tolnay055a7042016-10-02 19:23:54 -07001742
Michael Layzell734adb42017-06-07 16:58:31 -04001743 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001744 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001745 named!(parse -> Self, do_parse!(
1746 data: brackets!(do_parse!(
1747 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001748 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001749 times: syn!(Expr) >>
1750 (value, semi, times)
1751 )) >>
1752 (ExprRepeat {
1753 expr: Box::new((data.0).0),
1754 amt: Box::new((data.0).2),
1755 bracket_token: data.1,
1756 semi_token: (data.0).1,
1757 })
1758 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001759 }
David Tolnay055a7042016-10-02 19:23:54 -07001760
Michael Layzell734adb42017-06-07 16:58:31 -04001761 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001762 impl Synom for ExprUnsafe {
1763 named!(parse -> Self, do_parse!(
1764 unsafe_: keyword!(unsafe) >>
1765 b: syn!(Block) >>
1766 (ExprUnsafe {
1767 unsafe_token: unsafe_,
1768 block: b,
1769 })
1770 ));
1771 }
1772
1773 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001774 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001775 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001776 b: syn!(Block) >>
1777 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001778 block: b,
1779 })
1780 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001781 }
David Tolnay89e05672016-10-02 14:39:42 -07001782
Michael Layzell734adb42017-06-07 16:58:31 -04001783 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001784 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001785 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001786 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001787 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001788 ));
1789
Michael Layzell734adb42017-06-07 16:58:31 -04001790 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001791 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001792 named!(parse -> Self, alt!(
1793 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001794 punct!(..=) => { RangeLimits::Closed }
1795 |
1796 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001797 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001798 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001799 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001800 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001801 }
David Tolnay438c9052016-10-07 23:24:48 -07001802
Alex Crichton954046c2017-05-30 21:49:42 -07001803 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001804 named!(parse -> Self, do_parse!(
1805 pair: qpath >>
1806 (ExprPath {
1807 qself: pair.0,
1808 path: pair.1,
1809 })
1810 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001811 }
David Tolnay42602292016-10-01 22:25:45 -07001812
Michael Layzell734adb42017-06-07 16:58:31 -04001813 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001814 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001815
David Tolnay32954ef2017-12-26 22:43:16 -05001816 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001817
Michael Layzell734adb42017-06-07 16:58:31 -04001818 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001819 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001820 named!(parse -> Self, do_parse!(
1821 stmts: braces!(call!(Block::parse_within)) >>
1822 (Block {
1823 stmts: stmts.0,
1824 brace_token: stmts.1,
1825 })
1826 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001827 }
David Tolnay939766a2016-09-23 23:48:12 -07001828
Michael Layzell734adb42017-06-07 16:58:31 -04001829 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001830 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001831 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001832 many0!(punct!(;)) >>
1833 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001834 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001835 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001836 mut e: syn!(Expr) >>
1837 ({
1838 e.attrs = attrs;
1839 Stmt::Expr(Box::new(e))
1840 })
1841 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001842 (match last {
1843 None => standalone,
1844 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001845 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001846 standalone
1847 }
1848 })
1849 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001850 }
1851
Michael Layzell734adb42017-06-07 16:58:31 -04001852 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001853 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001854 named!(parse -> Self, alt!(
1855 stmt_mac
1856 |
1857 stmt_local
1858 |
1859 stmt_item
1860 |
Michael Layzell35418782017-06-07 09:20:25 -04001861 stmt_blockexpr
1862 |
Michael Layzell92639a52017-06-01 00:07:44 -04001863 stmt_expr
1864 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001865 }
David Tolnay939766a2016-09-23 23:48:12 -07001866
Michael Layzell734adb42017-06-07 16:58:31 -04001867 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001868 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001869 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001870 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001871 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001872 // Only parse braces here; paren and bracket will get parsed as
1873 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001874 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001875 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001876 (Stmt::Macro(Box::new((
1877 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001878 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001879 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001880 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001881 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001882 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001883 },
David Tolnayeea28d62016-10-25 20:44:08 -07001884 },
Alex Crichton954046c2017-05-30 21:49:42 -07001885 match semi {
1886 Some(semi) => MacStmtStyle::Semicolon(semi),
1887 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001888 },
David Tolnayeea28d62016-10-25 20:44:08 -07001889 attrs,
1890 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001891 ));
1892
Michael Layzell734adb42017-06-07 16:58:31 -04001893 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001894 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001895 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001896 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001897 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001898 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001899 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1900 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001901 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001902 let_token: let_,
1903 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001904 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1905 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001906 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001907 ty: ty.map(|p| Box::new(p.1)),
1908 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001909 attrs: attrs,
1910 })))
1911 ));
1912
Michael Layzell734adb42017-06-07 16:58:31 -04001913 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001914 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001915
Michael Layzell734adb42017-06-07 16:58:31 -04001916 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001917 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001918 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04001919 mut e: expr_nosemi >>
1920 // If the next token is a `.` or a `?` it is special-cased to parse as
1921 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001922 not!(punct!(.)) >>
1923 not!(punct!(?)) >>
1924 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001925 ({
1926 e.attrs = attrs;
1927 if let Some(semi) = semi {
1928 Stmt::Semi(Box::new(e), semi)
1929 } else {
1930 Stmt::Expr(Box::new(e))
1931 }
1932 })
1933 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001934
Michael Layzell734adb42017-06-07 16:58:31 -04001935 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001936 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001937 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001938 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001939 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001940 ({
1941 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001942 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001943 })
David Tolnay939766a2016-09-23 23:48:12 -07001944 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001945
Michael Layzell734adb42017-06-07 16:58:31 -04001946 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001947 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001948 named!(parse -> Self, alt!(
1949 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1950 |
1951 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1952 |
1953 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1954 |
1955 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1956 |
1957 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1958 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001959 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001960 |
1961 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1962 |
1963 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1964 |
1965 syn!(PatPath) => { Pat::Path }
1966 |
1967 syn!(PatTuple) => { Pat::Tuple }
1968 |
1969 syn!(PatRef) => { Pat::Ref }
1970 |
1971 syn!(PatSlice) => { Pat::Slice }
1972 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001973 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001974
Michael Layzell734adb42017-06-07 16:58:31 -04001975 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001976 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001977 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001978 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001979 |u| PatWild { underscore_token: u }
1980 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001981 }
David Tolnay84aa0752016-10-02 23:01:13 -07001982
Michael Layzell734adb42017-06-07 16:58:31 -04001983 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001984 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001985 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001986 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001987 pat: syn!(Pat) >>
1988 (PatBox {
1989 pat: Box::new(pat),
1990 box_token: boxed,
1991 })
1992 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001993 }
1994
Michael Layzell734adb42017-06-07 16:58:31 -04001995 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001996 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001997 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001998 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001999 mutability: syn!(Mutability) >>
2000 name: alt!(
2001 syn!(Ident)
2002 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08002003 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04002004 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002005 not!(punct!(<)) >>
2006 not!(punct!(::)) >>
2007 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002008 (PatIdent {
2009 mode: match mode {
2010 Some(mode) => BindingMode::ByRef(mode, mutability),
2011 None => BindingMode::ByValue(mutability),
2012 },
2013 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002014 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002015 subpat: subpat.map(|p| Box::new(p.1)),
2016 })
2017 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002018 }
2019
Michael Layzell734adb42017-06-07 16:58:31 -04002020 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002021 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002022 named!(parse -> Self, do_parse!(
2023 path: syn!(Path) >>
2024 tuple: syn!(PatTuple) >>
2025 (PatTupleStruct {
2026 path: path,
2027 pat: tuple,
2028 })
2029 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002030 }
2031
Michael Layzell734adb42017-06-07 16:58:31 -04002032 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002033 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002034 named!(parse -> Self, do_parse!(
2035 path: syn!(Path) >>
2036 data: braces!(do_parse!(
2037 fields: call!(Delimited::parse_terminated) >>
2038 base: option!(
2039 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002040 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002041 ) >>
2042 (fields, base)
2043 )) >>
2044 (PatStruct {
2045 path: path,
2046 fields: (data.0).0,
2047 brace_token: data.1,
2048 dot2_token: (data.0).1.and_then(|m| m),
2049 })
2050 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002051 }
2052
Michael Layzell734adb42017-06-07 16:58:31 -04002053 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002054 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002055 named!(parse -> Self, alt!(
2056 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002057 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002058 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002059 pat: syn!(Pat) >>
2060 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002061 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002062 pat: Box::new(pat),
2063 is_shorthand: false,
2064 attrs: Vec::new(),
2065 colon_token: Some(colon),
2066 })
2067 )
2068 |
2069 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002070 boxed: option!(keyword!(box)) >>
2071 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002072 mutability: syn!(Mutability) >>
2073 ident: syn!(Ident) >>
2074 ({
2075 let mut pat: Pat = PatIdent {
2076 mode: if let Some(mode) = mode {
2077 BindingMode::ByRef(mode, mutability)
2078 } else {
2079 BindingMode::ByValue(mutability)
2080 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002081 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002082 subpat: None,
2083 at_token: None,
2084 }.into();
2085 if let Some(boxed) = boxed {
2086 pat = PatBox {
2087 pat: Box::new(pat),
2088 box_token: boxed,
2089 }.into();
2090 }
2091 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002092 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002093 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002094 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002095 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002096 colon_token: None,
2097 }
2098 })
2099 )
2100 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002101 }
2102
Michael Layzell734adb42017-06-07 16:58:31 -04002103 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002104 impl Synom for Member {
2105 named!(parse -> Self, alt!(
2106 syn!(Ident) => { Member::Named }
2107 |
2108 syn!(Index) => { Member::Unnamed }
2109 ));
2110 }
2111
2112 #[cfg(feature = "full")]
2113 impl Synom for Index {
2114 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002115 lit: syn!(Lit) >>
2116 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002117 if let Ok(i) = lit.value.to_string().parse() {
2118 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002119 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002120 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002121 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002122 })
David Tolnay85b69a42017-12-27 20:43:10 -05002123 ));
2124 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002125
Michael Layzell734adb42017-06-07 16:58:31 -04002126 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002127 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002128 named!(parse -> Self, map!(
2129 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002130 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002131 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002132 }
David Tolnay9636c052016-10-02 17:11:17 -07002133
Michael Layzell734adb42017-06-07 16:58:31 -04002134 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002135 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002136 named!(parse -> Self, do_parse!(
2137 data: parens!(do_parse!(
2138 elems: call!(Delimited::parse_terminated) >>
2139 dotdot: map!(cond!(
2140 elems.is_empty() || elems.trailing_delim(),
2141 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002142 dots: punct!(..) >>
2143 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002144 (dots, trailing)
2145 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002146 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002147 rest: cond!(match dotdot {
2148 Some((_, Some(_))) => true,
2149 _ => false,
2150 },
2151 call!(Delimited::parse_terminated)) >>
2152 (elems, dotdot, rest)
2153 )) >>
2154 ({
2155 let ((mut elems, dotdot, rest), parens) = data;
2156 let (dotdot, trailing) = match dotdot {
2157 Some((a, b)) => (Some(a), Some(b)),
2158 None => (None, None),
2159 };
2160 PatTuple {
2161 paren_token: parens,
2162 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2163 dot2_token: dotdot,
2164 comma_token: trailing.and_then(|b| b),
2165 pats: {
2166 if let Some(rest) = rest {
2167 for elem in rest {
2168 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002169 }
Michael Layzell92639a52017-06-01 00:07:44 -04002170 }
2171 elems
2172 },
2173 }
2174 })
2175 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002176 }
David Tolnayfbb73232016-10-03 01:00:06 -07002177
Michael Layzell734adb42017-06-07 16:58:31 -04002178 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002179 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002180 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002181 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002182 mutability: syn!(Mutability) >>
2183 pat: syn!(Pat) >>
2184 (PatRef {
2185 pat: Box::new(pat),
2186 mutbl: mutability,
2187 and_token: and,
2188 })
2189 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002190 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002191
Michael Layzell734adb42017-06-07 16:58:31 -04002192 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002193 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002194 named!(parse -> Self, do_parse!(
2195 lit: pat_lit_expr >>
2196 (if let ExprKind::Path(_) = lit.node {
2197 return parse_error(); // these need to be parsed by pat_path
2198 } else {
2199 PatLit {
2200 expr: Box::new(lit),
2201 }
2202 })
2203 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002204 }
David Tolnaye1310902016-10-29 23:40:00 -07002205
Michael Layzell734adb42017-06-07 16:58:31 -04002206 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002207 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002208 named!(parse -> Self, do_parse!(
2209 lo: pat_lit_expr >>
2210 limits: syn!(RangeLimits) >>
2211 hi: pat_lit_expr >>
2212 (PatRange {
2213 lo: Box::new(lo),
2214 hi: Box::new(hi),
2215 limits: limits,
2216 })
2217 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002218 }
David Tolnaye1310902016-10-29 23:40:00 -07002219
Michael Layzell734adb42017-06-07 16:58:31 -04002220 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002221 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002222 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002223 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002224 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002225 |
Alex Crichton954046c2017-05-30 21:49:42 -07002226 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002227 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002228 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002229 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002230 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002231 expr: Box::new(v.into())
2232 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002233 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002234 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002235 })
2236 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002237
Michael Layzell734adb42017-06-07 16:58:31 -04002238 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002239 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002240 named!(parse -> Self, map!(
2241 brackets!(do_parse!(
2242 before: call!(Delimited::parse_terminated) >>
2243 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002244 dots: punct!(..) >>
2245 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002246 (dots, trailing)
2247 )) >>
2248 after: cond!(
2249 match middle {
2250 Some((_, ref trailing)) => trailing.is_some(),
2251 _ => false,
2252 },
2253 call!(Delimited::parse_terminated)
2254 ) >>
2255 (before, middle, after)
2256 )),
2257 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002258 let mut before: Delimited<Pat, Token![,]> = before;
2259 let after: Option<Delimited<Pat, Token![,]>> = after;
2260 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002261 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002262 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002263 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002264 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002265 }),
2266 bracket_token: brackets,
2267 middle: middle.and_then(|_| {
2268 if !before.is_empty() && !before.trailing_delim() {
2269 Some(Box::new(before.pop().unwrap().into_item()))
2270 } else {
2271 None
2272 }
2273 }),
2274 front: before,
2275 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002276 }
Alex Crichton954046c2017-05-30 21:49:42 -07002277 }
Michael Layzell92639a52017-06-01 00:07:44 -04002278 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002279 }
David Tolnay435a9a82016-10-29 13:47:20 -07002280
Michael Layzell734adb42017-06-07 16:58:31 -04002281 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002282 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002283 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002284 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002285 |
2286 epsilon!() => { |_| CaptureBy::Ref }
2287 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002288 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002289}
2290
David Tolnayf4bbbd92016-09-23 14:41:55 -07002291#[cfg(feature = "printing")]
2292mod printing {
2293 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002294 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002295 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002296 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002297 #[cfg(feature = "full")]
2298 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002299
David Tolnaybcf26022017-12-25 22:10:52 -05002300 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2301 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002302 #[cfg(feature = "full")]
2303 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2304 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002305 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002306 e.to_tokens(tokens);
2307 });
2308 } else {
2309 e.to_tokens(tokens);
2310 }
2311 }
2312
David Tolnayf4bbbd92016-09-23 14:41:55 -07002313 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002314 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002315 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002316 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002317 self.node.to_tokens(tokens)
2318 }
Michael Layzell734adb42017-06-07 16:58:31 -04002319
2320 #[cfg(not(feature = "full"))]
2321 fn to_tokens(&self, tokens: &mut Tokens) {
2322 self.node.to_tokens(tokens)
2323 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002324 }
2325
Michael Layzell734adb42017-06-07 16:58:31 -04002326 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002327 impl ToTokens for ExprBox {
2328 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002329 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002330 self.expr.to_tokens(tokens);
2331 }
2332 }
2333
Michael Layzell734adb42017-06-07 16:58:31 -04002334 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002335 impl ToTokens for ExprInPlace {
2336 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002337 match self.kind {
2338 InPlaceKind::Arrow(ref arrow) => {
2339 self.place.to_tokens(tokens);
2340 arrow.to_tokens(tokens);
2341 self.value.to_tokens(tokens);
2342 }
2343 InPlaceKind::In(ref _in) => {
2344 _in.to_tokens(tokens);
2345 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002346 // NOTE: The second operand must be in a block, add one if
2347 // it is not present.
2348 if let ExprKind::Block(_) = self.value.node {
2349 self.value.to_tokens(tokens);
2350 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002351 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002352 self.value.to_tokens(tokens);
2353 })
2354 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002355 }
2356 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002357 }
2358 }
2359
Michael Layzell734adb42017-06-07 16:58:31 -04002360 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002361 impl ToTokens for ExprArray {
2362 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002363 self.bracket_token.surround(tokens, |tokens| {
2364 self.exprs.to_tokens(tokens);
2365 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002366 }
2367 }
2368
2369 impl ToTokens for ExprCall {
2370 fn to_tokens(&self, tokens: &mut Tokens) {
2371 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002372 self.paren_token.surround(tokens, |tokens| {
2373 self.args.to_tokens(tokens);
2374 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002375 }
2376 }
2377
Michael Layzell734adb42017-06-07 16:58:31 -04002378 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002379 impl ToTokens for ExprMethodCall {
2380 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002381 self.expr.to_tokens(tokens);
2382 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002383 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002384 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002385 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2386 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002387 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002388 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002389 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002390 self.paren_token.surround(tokens, |tokens| {
2391 self.args.to_tokens(tokens);
2392 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002393 }
2394 }
2395
Michael Layzell734adb42017-06-07 16:58:31 -04002396 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002397 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002398 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002399 self.paren_token.surround(tokens, |tokens| {
2400 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002401 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002402 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002403 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002404 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002405 }
2406 // XXX: Not sure how to handle this, but we never parse it yet.
2407 // Is this for an expression like (0,)? Can't we use the
2408 // trailing delimiter on Delimited for that? (,) isn't a valid
2409 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002410 self.lone_comma.to_tokens(tokens);
2411 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002412 }
2413 }
2414
2415 impl ToTokens for ExprBinary {
2416 fn to_tokens(&self, tokens: &mut Tokens) {
2417 self.left.to_tokens(tokens);
2418 self.op.to_tokens(tokens);
2419 self.right.to_tokens(tokens);
2420 }
2421 }
2422
2423 impl ToTokens for ExprUnary {
2424 fn to_tokens(&self, tokens: &mut Tokens) {
2425 self.op.to_tokens(tokens);
2426 self.expr.to_tokens(tokens);
2427 }
2428 }
2429
2430 impl ToTokens for ExprCast {
2431 fn to_tokens(&self, tokens: &mut Tokens) {
2432 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002433 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002434 self.ty.to_tokens(tokens);
2435 }
2436 }
2437
2438 impl ToTokens for ExprType {
2439 fn to_tokens(&self, tokens: &mut Tokens) {
2440 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002441 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002442 self.ty.to_tokens(tokens);
2443 }
2444 }
2445
Michael Layzell734adb42017-06-07 16:58:31 -04002446 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002447 fn maybe_wrap_else(
2448 tokens: &mut Tokens,
2449 else_token: &Option<Token![else]>,
2450 if_false: &Option<Box<Expr>>,
2451 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002452 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002453 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002454
2455 // If we are not one of the valid expressions to exist in an else
2456 // clause, wrap ourselves in a block.
2457 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002458 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002459 if_false.to_tokens(tokens);
2460 }
2461 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002462 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002463 if_false.to_tokens(tokens);
2464 });
2465 }
2466 }
2467 }
2468 }
2469
2470 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002471 impl ToTokens for ExprIf {
2472 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002473 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002474 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002475 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002476 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002477 }
2478 }
2479
Michael Layzell734adb42017-06-07 16:58:31 -04002480 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002481 impl ToTokens for ExprIfLet {
2482 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002483 self.if_token.to_tokens(tokens);
2484 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002485 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002486 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002487 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002488 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002489 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002490 }
2491 }
2492
Michael Layzell734adb42017-06-07 16:58:31 -04002493 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002494 impl ToTokens for ExprWhile {
2495 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002496 if self.label.is_some() {
2497 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002498 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002499 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002500 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002501 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002502 self.body.to_tokens(tokens);
2503 }
2504 }
2505
Michael Layzell734adb42017-06-07 16:58:31 -04002506 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002507 impl ToTokens for ExprWhileLet {
2508 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002509 if self.label.is_some() {
2510 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002511 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002512 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002513 self.while_token.to_tokens(tokens);
2514 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002515 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002516 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002517 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002518 self.body.to_tokens(tokens);
2519 }
2520 }
2521
Michael Layzell734adb42017-06-07 16:58:31 -04002522 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002523 impl ToTokens for ExprForLoop {
2524 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002525 if self.label.is_some() {
2526 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002527 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002528 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002529 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002530 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002531 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002532 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002533 self.body.to_tokens(tokens);
2534 }
2535 }
2536
Michael Layzell734adb42017-06-07 16:58:31 -04002537 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002538 impl ToTokens for ExprLoop {
2539 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002540 if self.label.is_some() {
2541 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002542 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002543 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002544 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002545 self.body.to_tokens(tokens);
2546 }
2547 }
2548
Michael Layzell734adb42017-06-07 16:58:31 -04002549 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002550 impl ToTokens for ExprMatch {
2551 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002552 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002553 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002554 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002555 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002556 arm.to_tokens(tokens);
2557 // Ensure that we have a comma after a non-block arm, except
2558 // for the last one.
2559 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002560 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002561 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002562 }
2563 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002564 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002565 }
2566 }
2567
Michael Layzell734adb42017-06-07 16:58:31 -04002568 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002569 impl ToTokens for ExprCatch {
2570 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002571 self.do_token.to_tokens(tokens);
2572 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002573 self.block.to_tokens(tokens);
2574 }
2575 }
2576
Michael Layzell734adb42017-06-07 16:58:31 -04002577 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002578 impl ToTokens for ExprYield {
2579 fn to_tokens(&self, tokens: &mut Tokens) {
2580 self.yield_token.to_tokens(tokens);
2581 self.expr.to_tokens(tokens);
2582 }
2583 }
2584
2585 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002586 impl ToTokens for ExprClosure {
2587 fn to_tokens(&self, tokens: &mut Tokens) {
2588 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002589 self.or1_token.to_tokens(tokens);
2590 for item in self.decl.inputs.iter() {
2591 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002592 FnArg::Captured(ArgCaptured {
2593 ref pat,
2594 ty: Type::Infer(_),
2595 ..
2596 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002597 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002598 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002599 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002600 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002601 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002602 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002603 self.or2_token.to_tokens(tokens);
2604 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002605 self.body.to_tokens(tokens);
2606 }
2607 }
2608
Michael Layzell734adb42017-06-07 16:58:31 -04002609 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002610 impl ToTokens for ExprUnsafe {
2611 fn to_tokens(&self, tokens: &mut Tokens) {
2612 self.unsafe_token.to_tokens(tokens);
2613 self.block.to_tokens(tokens);
2614 }
2615 }
2616
2617 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002618 impl ToTokens for ExprBlock {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002620 self.block.to_tokens(tokens);
2621 }
2622 }
2623
Michael Layzell734adb42017-06-07 16:58:31 -04002624 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002625 impl ToTokens for ExprAssign {
2626 fn to_tokens(&self, tokens: &mut Tokens) {
2627 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002628 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002629 self.right.to_tokens(tokens);
2630 }
2631 }
2632
Michael Layzell734adb42017-06-07 16:58:31 -04002633 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002634 impl ToTokens for ExprAssignOp {
2635 fn to_tokens(&self, tokens: &mut Tokens) {
2636 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002637 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002638 self.right.to_tokens(tokens);
2639 }
2640 }
2641
Michael Layzell734adb42017-06-07 16:58:31 -04002642 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002643 impl ToTokens for ExprField {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002645 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002646 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002647 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002648 }
2649 }
2650
Michael Layzell734adb42017-06-07 16:58:31 -04002651 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002652 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002654 match *self {
2655 Member::Named(ident) => ident.to_tokens(tokens),
2656 Member::Unnamed(ref index) => index.to_tokens(tokens),
2657 }
2658 }
2659 }
2660
2661 #[cfg(feature = "full")]
2662 impl ToTokens for Index {
2663 fn to_tokens(&self, tokens: &mut Tokens) {
2664 tokens.append(TokenTree {
2665 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002666 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002667 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002668 }
2669 }
2670
2671 impl ToTokens for ExprIndex {
2672 fn to_tokens(&self, tokens: &mut Tokens) {
2673 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002674 self.bracket_token.surround(tokens, |tokens| {
2675 self.index.to_tokens(tokens);
2676 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002677 }
2678 }
2679
Michael Layzell734adb42017-06-07 16:58:31 -04002680 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002681 impl ToTokens for ExprRange {
2682 fn to_tokens(&self, tokens: &mut Tokens) {
2683 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002684 match self.limits {
2685 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2686 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2687 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002688 self.to.to_tokens(tokens);
2689 }
2690 }
2691
2692 impl ToTokens for ExprPath {
2693 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002694 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002695 }
2696 }
2697
Michael Layzell734adb42017-06-07 16:58:31 -04002698 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002699 impl ToTokens for ExprAddrOf {
2700 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002701 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002702 self.mutbl.to_tokens(tokens);
2703 self.expr.to_tokens(tokens);
2704 }
2705 }
2706
Michael Layzell734adb42017-06-07 16:58:31 -04002707 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002708 impl ToTokens for ExprBreak {
2709 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002710 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002711 self.label.to_tokens(tokens);
2712 self.expr.to_tokens(tokens);
2713 }
2714 }
2715
Michael Layzell734adb42017-06-07 16:58:31 -04002716 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002717 impl ToTokens for ExprContinue {
2718 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002719 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002720 self.label.to_tokens(tokens);
2721 }
2722 }
2723
Michael Layzell734adb42017-06-07 16:58:31 -04002724 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002725 impl ToTokens for ExprRet {
2726 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002727 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002728 self.expr.to_tokens(tokens);
2729 }
2730 }
2731
Michael Layzell734adb42017-06-07 16:58:31 -04002732 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002733 impl ToTokens for ExprStruct {
2734 fn to_tokens(&self, tokens: &mut Tokens) {
2735 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002736 self.brace_token.surround(tokens, |tokens| {
2737 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002738 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002739 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002740 self.rest.to_tokens(tokens);
2741 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002742 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002743 }
2744 }
2745
Michael Layzell734adb42017-06-07 16:58:31 -04002746 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002747 impl ToTokens for ExprRepeat {
2748 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002749 self.bracket_token.surround(tokens, |tokens| {
2750 self.expr.to_tokens(tokens);
2751 self.semi_token.to_tokens(tokens);
2752 self.amt.to_tokens(tokens);
2753 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002754 }
2755 }
2756
Michael Layzell93c36282017-06-04 20:43:14 -04002757 impl ToTokens for ExprGroup {
2758 fn to_tokens(&self, tokens: &mut Tokens) {
2759 self.group_token.surround(tokens, |tokens| {
2760 self.expr.to_tokens(tokens);
2761 });
2762 }
2763 }
2764
Alex Crichton62a0a592017-05-22 13:58:53 -07002765 impl ToTokens for ExprParen {
2766 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002767 self.paren_token.surround(tokens, |tokens| {
2768 self.expr.to_tokens(tokens);
2769 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002770 }
2771 }
2772
Michael Layzell734adb42017-06-07 16:58:31 -04002773 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002774 impl ToTokens for ExprTry {
2775 fn to_tokens(&self, tokens: &mut Tokens) {
2776 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002777 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002778 }
2779 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002780
Michael Layzell734adb42017-06-07 16:58:31 -04002781 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002782 impl ToTokens for FieldValue {
2783 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002784 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002785 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2786 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002787 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002788 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002789 self.expr.to_tokens(tokens);
2790 }
David Tolnay055a7042016-10-02 19:23:54 -07002791 }
2792 }
2793
Michael Layzell734adb42017-06-07 16:58:31 -04002794 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002795 impl ToTokens for Arm {
2796 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002797 tokens.append_all(&self.attrs);
2798 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002799 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002800 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002801 self.guard.to_tokens(tokens);
2802 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002803 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002804 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002805 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002806 }
2807 }
2808
Michael Layzell734adb42017-06-07 16:58:31 -04002809 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002810 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002811 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002812 self.underscore_token.to_tokens(tokens);
2813 }
2814 }
2815
Michael Layzell734adb42017-06-07 16:58:31 -04002816 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002817 impl ToTokens for PatIdent {
2818 fn to_tokens(&self, tokens: &mut Tokens) {
2819 self.mode.to_tokens(tokens);
2820 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002821 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002822 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002823 self.subpat.to_tokens(tokens);
2824 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002825 }
2826 }
2827
Michael Layzell734adb42017-06-07 16:58:31 -04002828 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002829 impl ToTokens for PatStruct {
2830 fn to_tokens(&self, tokens: &mut Tokens) {
2831 self.path.to_tokens(tokens);
2832 self.brace_token.surround(tokens, |tokens| {
2833 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002834 // NOTE: We need a comma before the dot2 token if it is present.
2835 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
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);
2839 });
2840 }
2841 }
2842
Michael Layzell734adb42017-06-07 16:58:31 -04002843 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002844 impl ToTokens for PatTupleStruct {
2845 fn to_tokens(&self, tokens: &mut Tokens) {
2846 self.path.to_tokens(tokens);
2847 self.pat.to_tokens(tokens);
2848 }
2849 }
2850
Michael Layzell734adb42017-06-07 16:58:31 -04002851 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002852 impl ToTokens for PatPath {
2853 fn to_tokens(&self, tokens: &mut Tokens) {
2854 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2855 }
2856 }
2857
Michael Layzell734adb42017-06-07 16:58:31 -04002858 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002859 impl ToTokens for PatTuple {
2860 fn to_tokens(&self, tokens: &mut Tokens) {
2861 self.paren_token.surround(tokens, |tokens| {
2862 for (i, token) in self.pats.iter().enumerate() {
2863 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002864 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2865 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002866 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002867 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002868 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002869
2870 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002871 // Ensure there is a comma before the .. token.
2872 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002873 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002874 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002875 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002876 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002877 });
2878 }
2879 }
2880
Michael Layzell734adb42017-06-07 16:58:31 -04002881 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002882 impl ToTokens for PatBox {
2883 fn to_tokens(&self, tokens: &mut Tokens) {
2884 self.box_token.to_tokens(tokens);
2885 self.pat.to_tokens(tokens);
2886 }
2887 }
2888
Michael Layzell734adb42017-06-07 16:58:31 -04002889 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002890 impl ToTokens for PatRef {
2891 fn to_tokens(&self, tokens: &mut Tokens) {
2892 self.and_token.to_tokens(tokens);
2893 self.mutbl.to_tokens(tokens);
2894 self.pat.to_tokens(tokens);
2895 }
2896 }
2897
Michael Layzell734adb42017-06-07 16:58:31 -04002898 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002899 impl ToTokens for PatLit {
2900 fn to_tokens(&self, tokens: &mut Tokens) {
2901 self.expr.to_tokens(tokens);
2902 }
2903 }
2904
Michael Layzell734adb42017-06-07 16:58:31 -04002905 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002906 impl ToTokens for PatRange {
2907 fn to_tokens(&self, tokens: &mut Tokens) {
2908 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002909 match self.limits {
2910 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2911 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2912 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002913 self.hi.to_tokens(tokens);
2914 }
2915 }
2916
Michael Layzell734adb42017-06-07 16:58:31 -04002917 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002918 impl ToTokens for PatSlice {
2919 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002920 // XXX: This is a mess, and it will be so easy to screw it up. How
2921 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002922 self.bracket_token.surround(tokens, |tokens| {
2923 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002924
2925 // If we need a comma before the middle or standalone .. token,
2926 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002927 if !self.front.empty_or_trailing()
2928 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002929 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002930 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002931 }
2932
2933 // If we have an identifier, we always need a .. token.
2934 if self.middle.is_some() {
2935 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002936 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002937 } else if self.dot2_token.is_some() {
2938 self.dot2_token.to_tokens(tokens);
2939 }
2940
2941 // Make sure we have a comma before the back half.
2942 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002943 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002944 self.back.to_tokens(tokens);
2945 } else {
2946 self.comma_token.to_tokens(tokens);
2947 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002948 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002949 }
2950 }
2951
Michael Layzell734adb42017-06-07 16:58:31 -04002952 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002953 impl ToTokens for FieldPat {
2954 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002955 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002956 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05002957 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002958 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002959 }
2960 self.pat.to_tokens(tokens);
2961 }
2962 }
2963
Michael Layzell734adb42017-06-07 16:58:31 -04002964 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002965 impl ToTokens for BindingMode {
2966 fn to_tokens(&self, tokens: &mut Tokens) {
2967 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002968 BindingMode::ByRef(ref t, ref m) => {
2969 t.to_tokens(tokens);
2970 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002971 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002972 BindingMode::ByValue(ref m) => {
2973 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002974 }
2975 }
2976 }
2977 }
David Tolnay42602292016-10-01 22:25:45 -07002978
Michael Layzell734adb42017-06-07 16:58:31 -04002979 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002980 impl ToTokens for CaptureBy {
2981 fn to_tokens(&self, tokens: &mut Tokens) {
2982 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002983 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002984 CaptureBy::Ref => {
2985 // nothing
2986 }
David Tolnay89e05672016-10-02 14:39:42 -07002987 }
2988 }
2989 }
2990
Michael Layzell734adb42017-06-07 16:58:31 -04002991 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002992 impl ToTokens for Block {
2993 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002994 self.brace_token.surround(tokens, |tokens| {
2995 tokens.append_all(&self.stmts);
2996 });
David Tolnay42602292016-10-01 22:25:45 -07002997 }
2998 }
2999
Michael Layzell734adb42017-06-07 16:58:31 -04003000 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003001 impl ToTokens for Stmt {
3002 fn to_tokens(&self, tokens: &mut Tokens) {
3003 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07003004 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07003005 Stmt::Item(ref item) => item.to_tokens(tokens),
3006 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003007 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003008 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003009 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003010 }
David Tolnaydecf28d2017-11-11 11:56:45 -08003011 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07003012 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07003013 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07003014 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07003015 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003016 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003017 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
3018 // no semicolon
3019 }
David Tolnay13b3d352016-10-03 00:31:15 -07003020 }
3021 }
David Tolnay42602292016-10-01 22:25:45 -07003022 }
3023 }
3024 }
David Tolnay191e0582016-10-02 18:31:09 -07003025
Michael Layzell734adb42017-06-07 16:58:31 -04003026 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003027 impl ToTokens for Local {
3028 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003029 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003030 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003031 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003032 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003033 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003034 self.ty.to_tokens(tokens);
3035 }
3036 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003037 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003038 self.init.to_tokens(tokens);
3039 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003040 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003041 }
3042 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003043}