blob: c5d7d143218578302bf6ad756db3dd2ee3908f8f [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080029 pub box_token: Token![box],
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080041 pub exprs: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070042 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080048 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070049 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080055 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// (within the angle brackets).
57 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
59 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080063 pub typarams: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080064 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080066 pub dot_token: Token![.],
67 pub lt_token: Option<Token![<]>,
68 pub colon2_token: Option<Token![::]>,
69 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
Michael Layzell734adb42017-06-07 16:58:31 -040073 pub Tup(ExprTup #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080074 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080076 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080098 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080099 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// A type ascription, e.g. `foo: f64`.
103 pub Type(ExprType {
104 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800105 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800106 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700107 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500108
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 /// An `if` block, with an optional else block
110 ///
111 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800116 pub if_token: Token![if],
117 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800130 pub if_token: Token![if],
131 pub let_token: Token![let],
132 pub eq_token: Token![=],
133 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800143 pub colon_token: Option<Token![:]>,
144 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800157 pub colon_token: Option<Token![:]>,
158 pub while_token: Token![while],
159 pub let_token: Token![let],
160 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800173 pub for_token: Token![for],
174 pub colon_token: Option<Token![:]>,
175 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800184 pub loop_token: Token![loop],
185 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800190 pub match_token: Token![match],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700191 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800201 pub or1_token: Token![|],
202 pub or2_token: Token![|],
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Nika Layzell640832a2017-12-04 13:37:09 -0500205 /// An unsafe block (`unsafe { ... }`)
206 pub Unsafe(ExprUnsafe #full {
207 pub unsafe_token: Token![unsafe],
208 pub block: Block,
209 }),
210
211 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub block: Block,
214 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700215
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400217 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 pub left: Box<Expr>,
219 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800220 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700221 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500222
Alex Crichton62a0a592017-05-22 13:58:53 -0700223 /// An assignment with an operator
224 ///
225 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400226 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 pub op: BinOp,
228 pub left: Box<Expr>,
229 pub right: Box<Expr>,
230 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500231
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 /// Access of a named struct field (`obj.foo`)
Michael Layzell734adb42017-06-07 16:58:31 -0400233 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 pub expr: Box<Expr>,
235 pub field: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800236 pub dot_token: Token![.],
Alex Crichton62a0a592017-05-22 13:58:53 -0700237 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500238
Alex Crichton62a0a592017-05-22 13:58:53 -0700239 /// Access of an unnamed field of a struct or tuple-struct
240 ///
241 /// For example, `foo.0`.
Michael Layzell734adb42017-06-07 16:58:31 -0400242 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700244 pub field: Lit,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800245 pub dot_token: Token![.],
Alex Crichton62a0a592017-05-22 13:58:53 -0700246 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500247
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 /// An indexing operation (`foo[2]`)
249 pub Index(ExprIndex {
250 pub expr: Box<Expr>,
251 pub index: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700252 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500254
David Tolnaybe55d7b2017-12-17 23:41:20 -0800255 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400256 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 pub from: Option<Box<Expr>>,
258 pub to: Option<Box<Expr>>,
259 pub limits: RangeLimits,
260 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700261
Alex Crichton62a0a592017-05-22 13:58:53 -0700262 /// Variable reference, possibly containing `::` and/or type
263 /// parameters, e.g. foo::bar::<baz>.
264 ///
265 /// Optionally "qualified",
266 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
267 pub Path(ExprPath {
268 pub qself: Option<QSelf>,
269 pub path: Path,
270 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700271
Alex Crichton62a0a592017-05-22 13:58:53 -0700272 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400273 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800274 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 pub mutbl: Mutability,
276 pub expr: Box<Expr>,
277 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500278
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400280 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700281 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800283 pub break_token: Token![break],
Alex Crichton62a0a592017-05-22 13:58:53 -0700284 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500285
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400287 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700288 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800289 pub continue_token: Token![continue],
Alex Crichton62a0a592017-05-22 13:58:53 -0700290 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500291
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400293 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800295 pub return_token: Token![return],
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700297
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800299 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700300
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 /// A struct literal expression.
302 ///
303 /// For example, `Foo {x: 1, y: 2}`, or
304 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400305 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800307 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800309 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700310 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700311 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700312
Alex Crichton62a0a592017-05-22 13:58:53 -0700313 /// An array literal constructed from one repeated element.
314 ///
315 /// For example, `[1; 5]`. The first expression is the element
316 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400317 pub Repeat(ExprRepeat #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700318 pub bracket_token: tokens::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800319 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 pub expr: Box<Expr>,
321 pub amt: Box<Expr>,
322 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700323
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 /// No-op: used solely so we can pretty-print faithfully
325 pub Paren(ExprParen {
326 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700327 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700328 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700329
Michael Layzell93c36282017-06-04 20:43:14 -0400330 /// No-op: used solely so we can pretty-print faithfully
331 ///
332 /// A `group` represents a `None`-delimited span in the input
333 /// `TokenStream` which affects the precidence of the resulting
334 /// expression. They are used for macro hygiene.
335 pub Group(ExprGroup {
336 pub expr: Box<Expr>,
337 pub group_token: tokens::Group,
338 }),
339
Alex Crichton62a0a592017-05-22 13:58:53 -0700340 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400341 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800343 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700344 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700345
Alex Crichton62a0a592017-05-22 13:58:53 -0700346 /// A catch expression.
347 ///
348 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400349 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800350 pub do_token: Token![do],
351 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700352 pub block: Block,
353 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700354
355 /// A yield expression.
356 ///
357 /// E.g. `yield expr`
358 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800359 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700360 pub expr: Option<Box<Expr>>,
361 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700362 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700363}
364
Michael Layzell734adb42017-06-07 16:58:31 -0400365#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700366ast_struct! {
367 /// A field-value pair in a struct literal.
368 pub struct FieldValue {
369 /// Name of the field.
370 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500371
Alex Crichton62a0a592017-05-22 13:58:53 -0700372 /// Value of the field.
373 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500374
Alex Crichton62a0a592017-05-22 13:58:53 -0700375 /// Whether this is a shorthand field, e.g. `Struct { x }`
376 /// instead of `Struct { x: x }`.
377 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500378
Alex Crichton62a0a592017-05-22 13:58:53 -0700379 /// Attributes tagged on the field.
380 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700381
David Tolnayf8db7ba2017-11-11 22:52:16 -0800382 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700383 }
David Tolnay055a7042016-10-02 19:23:54 -0700384}
385
Michael Layzell734adb42017-06-07 16:58:31 -0400386#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700387ast_struct! {
388 /// A Block (`{ .. }`).
389 ///
390 /// E.g. `{ .. }` as in `fn foo() { .. }`
391 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700392 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700393 /// Statements in a block
394 pub stmts: Vec<Stmt>,
395 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700396}
397
Michael Layzell734adb42017-06-07 16:58:31 -0400398#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700399ast_enum! {
400 /// A statement, usually ending in a semicolon.
401 pub enum Stmt {
402 /// A local (let) binding.
403 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700404
Alex Crichton62a0a592017-05-22 13:58:53 -0700405 /// An item definition.
406 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700407
Alex Crichton62a0a592017-05-22 13:58:53 -0700408 /// Expr without trailing semicolon.
409 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800412 Semi(Box<Expr>, Token![;]),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// Macro invocation.
David Tolnaydecf28d2017-11-11 11:56:45 -0800415 Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700416 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700417}
418
Michael Layzell734adb42017-06-07 16:58:31 -0400419#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700420ast_enum! {
421 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700422 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 pub enum MacStmtStyle {
424 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
425 /// `foo!(...);`, `foo![...];`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800426 Semicolon(Token![;]),
Clar Charrd22b5702017-03-10 15:24:56 -0500427
Alex Crichton62a0a592017-05-22 13:58:53 -0700428 /// The macro statement had braces; e.g. foo! { ... }
429 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500430
Alex Crichton62a0a592017-05-22 13:58:53 -0700431 /// The macro statement had parentheses or brackets and no semicolon; e.g.
432 /// `foo!(...)`. All of these will end up being converted into macro
433 /// expressions.
434 NoBraces,
435 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700436}
437
Michael Layzell734adb42017-06-07 16:58:31 -0400438#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700439ast_struct! {
440 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
441 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800442 pub let_token: Token![let],
443 pub colon_token: Option<Token![:]>,
444 pub eq_token: Option<Token![=]>,
445 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700446
Alex Crichton62a0a592017-05-22 13:58:53 -0700447 pub pat: Box<Pat>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800448 pub ty: Option<Box<Type>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500449
Alex Crichton62a0a592017-05-22 13:58:53 -0700450 /// Initializer expression to set the value, if any
451 pub init: Option<Box<Expr>>,
452 pub attrs: Vec<Attribute>,
453 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700454}
455
Michael Layzell734adb42017-06-07 16:58:31 -0400456#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700457ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700458 // Clippy false positive
459 // https://github.com/Manishearth/rust-clippy/issues/1241
460 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
461 pub enum Pat {
462 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700463 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800464 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700465 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700466
Alex Crichton62a0a592017-05-22 13:58:53 -0700467 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
468 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
469 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
470 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700471 pub Ident(PatIdent {
472 pub mode: BindingMode,
473 pub ident: Ident,
474 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800475 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700476 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700477
Alex Crichton62a0a592017-05-22 13:58:53 -0700478 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
479 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480 pub Struct(PatStruct {
481 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800482 pub fields: Delimited<FieldPat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700483 pub brace_token: tokens::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800484 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700486
Alex Crichton62a0a592017-05-22 13:58:53 -0700487 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
488 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
489 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700490 pub TupleStruct(PatTupleStruct {
491 pub path: Path,
492 pub pat: PatTuple,
493 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700494
Alex Crichton62a0a592017-05-22 13:58:53 -0700495 /// A possibly qualified path pattern.
496 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
497 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
498 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700499 pub Path(PatPath {
500 pub qself: Option<QSelf>,
501 pub path: Path,
502 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700503
Alex Crichton62a0a592017-05-22 13:58:53 -0700504 /// A tuple pattern `(a, b)`.
505 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
506 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700507 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800508 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700509 pub dots_pos: Option<usize>,
510 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800511 pub dot2_token: Option<Token![..]>,
512 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Box(PatBox {
516 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800517 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700518 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700519 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700520 pub Ref(PatRef {
521 pub pat: Box<Pat>,
522 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800523 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700524 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700525 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700526 pub Lit(PatLit {
527 pub expr: Box<Expr>,
528 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800529 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 pub Range(PatRange {
531 pub lo: Box<Expr>,
532 pub hi: Box<Expr>,
533 pub limits: RangeLimits,
534 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400535 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800537 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800539 pub back: Delimited<Pat, Token![,]>,
540 pub dot2_token: Option<Token![..]>,
541 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700542 pub bracket_token: tokens::Bracket,
543 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700544 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800545 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700546 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700547}
548
Michael Layzell734adb42017-06-07 16:58:31 -0400549#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700550ast_struct! {
551 /// An arm of a 'match'.
552 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800553 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 ///
555 /// ```rust,ignore
556 /// match n {
David Tolnaybe55d7b2017-12-17 23:41:20 -0800557 /// 0..=10 => { println!("match!") },
Alex Crichton62a0a592017-05-22 13:58:53 -0700558 /// // ..
559 /// }
560 /// ```
561 pub struct Arm {
562 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800563 pub pats: Delimited<Pat, Token![|]>,
564 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700565 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800566 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700567 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800568 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700569 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700570}
571
Michael Layzell734adb42017-06-07 16:58:31 -0400572#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700573ast_enum! {
574 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700575 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800577 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700578 Ref,
579 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700580}
581
Michael Layzell734adb42017-06-07 16:58:31 -0400582#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700583ast_enum! {
584 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700585 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 pub enum RangeLimits {
587 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800588 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700589 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800590 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700591 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700592}
593
Michael Layzell734adb42017-06-07 16:58:31 -0400594#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700595ast_struct! {
596 /// A single field in a struct pattern
597 ///
598 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
599 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
600 /// except `is_shorthand` is true
601 pub struct FieldPat {
602 /// The identifier for the field
603 pub ident: Ident,
604 /// The pattern the field is destructured to
605 pub pat: Box<Pat>,
606 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800607 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700608 pub attrs: Vec<Attribute>,
609 }
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! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700614 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700615 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800616 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700617 ByValue(Mutability),
618 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700619}
620
Michael Layzell734adb42017-06-07 16:58:31 -0400621#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400622ast_enum! {
623 #[cfg_attr(feature = "clone-impls", derive(Copy))]
624 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800625 Arrow(Token![<-]),
626 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400627 }
628}
629
Michael Layzell3936ceb2017-07-08 00:28:36 -0400630#[cfg(any(feature = "parsing", feature = "printing"))]
631#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700632fn arm_expr_requires_comma(expr: &Expr) -> bool {
633 // see https://github.com/rust-lang/rust/blob/eb8f2586e
634 // /src/libsyntax/parse/classify.rs#L17-L37
635 match expr.node {
Nika Layzell640832a2017-12-04 13:37:09 -0500636 ExprKind::Unsafe(..) |
Alex Crichton03b30272017-08-28 09:35:24 -0700637 ExprKind::Block(..) |
638 ExprKind::If(..) |
639 ExprKind::IfLet(..) |
640 ExprKind::Match(..) |
641 ExprKind::While(..) |
642 ExprKind::WhileLet(..) |
643 ExprKind::Loop(..) |
644 ExprKind::ForLoop(..) |
645 ExprKind::Catch(..) => false,
646 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400647 }
648}
649
David Tolnayb9c8e322016-09-23 20:48:37 -0700650#[cfg(feature = "parsing")]
651pub mod parsing {
652 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700653 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700654
Michael Layzell734adb42017-06-07 16:58:31 -0400655 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700656 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400657 use synom::{PResult, Cursor, Synom};
658 #[cfg(feature = "full")]
659 use synom::parse_error;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700660
Michael Layzellb78f3b52017-06-04 19:03:03 -0400661 /// When we're parsing expressions which occur before blocks, like in
662 /// an if statement's condition, we cannot parse a struct literal.
663 ///
664 /// Struct literals are ambiguous in certain positions
665 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700666 macro_rules! ambiguous_expr {
667 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700668 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700669 };
670 }
671
Michael Layzellb78f3b52017-06-04 19:03:03 -0400672 /// When we are parsing an optional suffix expression, we cannot allow
673 /// blocks if structs are not allowed.
674 ///
675 /// Example:
676 /// ```ignore
677 /// if break { } { }
678 /// // is ambiguous between:
679 /// if (break { }) { }
680 /// // - or -
681 /// if (break) { } { }
682 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400683 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400684 macro_rules! opt_ambiguous_expr {
685 ($i:expr, $allow_struct:ident) => {
686 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
687 };
688 }
689
Alex Crichton954046c2017-05-30 21:49:42 -0700690 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400691 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700692
693 fn description() -> Option<&'static str> {
694 Some("expression")
695 }
696 }
697
Michael Layzell734adb42017-06-07 16:58:31 -0400698 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700699 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
700
Michael Layzellb78f3b52017-06-04 19:03:03 -0400701 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400702 #[cfg(feature = "full")]
703 fn ambiguous_expr(i: Cursor,
704 allow_struct: bool,
705 allow_block: bool)
706 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400707 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700708 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400709 call!(assign_expr, allow_struct, allow_block),
710 ExprKind::into
711 )
712 }
713
Michael Layzell734adb42017-06-07 16:58:31 -0400714 #[cfg(not(feature = "full"))]
715 fn ambiguous_expr(i: Cursor,
716 allow_struct: bool,
717 allow_block: bool)
718 -> PResult<Expr> {
719 map!(
720 i,
721 // NOTE: We intentionally skip assign_expr, placement_expr, and
722 // range_expr, as they are not parsed in non-full mode.
723 call!(or_expr, allow_struct, allow_block),
724 ExprKind::into
725 )
726 }
727
Michael Layzellb78f3b52017-06-04 19:03:03 -0400728 /// Parse a left-associative binary operator.
729 macro_rules! binop {
730 (
731 $name: ident,
732 $next: ident,
733 $submac: ident!( $($args:tt)* )
734 ) => {
735 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
736 mut e: call!($next, allow_struct, allow_block) >>
737 many0!(do_parse!(
738 op: $submac!($($args)*) >>
739 rhs: call!($next, allow_struct, true) >>
740 ({
741 e = ExprBinary {
742 left: Box::new(e.into()),
743 op: op,
744 right: Box::new(rhs.into()),
745 }.into();
746 })
747 )) >>
748 (e)
749 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700750 }
David Tolnay54e854d2016-10-24 12:03:30 -0700751 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700752
Michael Layzellb78f3b52017-06-04 19:03:03 -0400753 /// ```ignore
754 /// <placement> = <placement> ..
755 /// <placement> += <placement> ..
756 /// <placement> -= <placement> ..
757 /// <placement> *= <placement> ..
758 /// <placement> /= <placement> ..
759 /// <placement> %= <placement> ..
760 /// <placement> ^= <placement> ..
761 /// <placement> &= <placement> ..
762 /// <placement> |= <placement> ..
763 /// <placement> <<= <placement> ..
764 /// <placement> >>= <placement> ..
765 /// ```
766 ///
767 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400768 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400769 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
770 mut e: call!(placement_expr, allow_struct, allow_block) >>
771 alt!(
772 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800773 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400774 // Recurse into self to parse right-associative operator.
775 rhs: call!(assign_expr, allow_struct, true) >>
776 ({
777 e = ExprAssign {
778 left: Box::new(e.into()),
779 eq_token: eq,
780 right: Box::new(rhs.into()),
781 }.into();
782 })
783 )
784 |
785 do_parse!(
786 op: call!(BinOp::parse_assign_op) >>
787 // Recurse into self to parse right-associative operator.
788 rhs: call!(assign_expr, allow_struct, true) >>
789 ({
790 e = ExprAssignOp {
791 left: Box::new(e.into()),
792 op: op,
793 right: Box::new(rhs.into()),
794 }.into();
795 })
796 )
797 |
798 epsilon!()
799 ) >>
800 (e)
801 ));
802
803 /// ```ignore
804 /// <range> <- <range> ..
805 /// ```
806 ///
807 /// NOTE: The `in place { expr }` version of this syntax is parsed in
808 /// `atom_expr`, not here.
809 ///
810 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400811 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400812 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
813 mut e: call!(range_expr, allow_struct, allow_block) >>
814 alt!(
815 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800816 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400817 // Recurse into self to parse right-associative operator.
818 rhs: call!(placement_expr, allow_struct, true) >>
819 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400820 e = ExprInPlace {
821 // op: BinOp::Place(larrow),
822 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400823 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400824 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400825 }.into();
826 })
827 )
828 |
829 epsilon!()
830 ) >>
831 (e)
832 ));
833
834 /// ```ignore
835 /// <or> ... <or> ..
836 /// <or> .. <or> ..
837 /// <or> ..
838 /// ```
839 ///
840 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
841 /// rules are for parsing these expressions are, but this is not correct.
842 /// For example, `a .. b .. c` is not a legal expression. It should not
843 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
844 ///
845 /// NOTE: The form of ranges which don't include a preceding expression are
846 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400847 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400848 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
849 mut e: call!(or_expr, allow_struct, allow_block) >>
850 many0!(do_parse!(
851 limits: syn!(RangeLimits) >>
852 // We don't want to allow blocks here if we don't allow structs. See
853 // the reasoning for `opt_ambiguous_expr!` above.
854 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
855 ({
856 e = ExprRange {
857 from: Some(Box::new(e.into())),
858 limits: limits,
859 to: hi.map(|e| Box::new(e.into())),
860 }.into();
861 })
862 )) >>
863 (e)
864 ));
865
866 /// ```ignore
867 /// <and> || <and> ...
868 /// ```
David Tolnayf8db7ba2017-11-11 22:52:16 -0800869 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400870
871 /// ```ignore
872 /// <compare> && <compare> ...
873 /// ```
David Tolnayf8db7ba2017-11-11 22:52:16 -0800874 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400875
876 /// ```ignore
877 /// <bitor> == <bitor> ...
878 /// <bitor> != <bitor> ...
879 /// <bitor> >= <bitor> ...
880 /// <bitor> <= <bitor> ...
881 /// <bitor> > <bitor> ...
882 /// <bitor> < <bitor> ...
883 /// ```
884 ///
885 /// NOTE: This operator appears to be parsed as left-associative, but errors
886 /// if it is used in a non-associative manner.
887 binop!(compare_expr, bitor_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800888 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400889 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800890 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400891 |
892 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800893 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400894 |
895 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800896 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400897 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400898 do_parse!(
899 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800900 not!(punct!(<-)) >>
901 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400902 (BinOp::Lt(t))
903 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400904 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800905 punct!(>) => { BinOp::Gt }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400906 ));
907
908 /// ```ignore
909 /// <bitxor> | <bitxor> ...
910 /// ```
911 binop!(bitor_expr, bitxor_expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800912 not!(punct!(||)) >>
913 not!(punct!(|=)) >>
914 t: punct!(|) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400915 (BinOp::BitOr(t))
916 ));
917
918 /// ```ignore
919 /// <bitand> ^ <bitand> ...
920 /// ```
921 binop!(bitxor_expr, bitand_expr, do_parse!(
922 // NOTE: Make sure we aren't looking at ^=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800923 not!(punct!(^=)) >>
924 t: punct!(^) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400925 (BinOp::BitXor(t))
926 ));
927
928 /// ```ignore
929 /// <shift> & <shift> ...
930 /// ```
931 binop!(bitand_expr, shift_expr, do_parse!(
932 // NOTE: Make sure we aren't looking at && or &=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800933 not!(punct!(&&)) >>
934 not!(punct!(&=)) >>
935 t: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400936 (BinOp::BitAnd(t))
937 ));
938
939 /// ```ignore
940 /// <arith> << <arith> ...
941 /// <arith> >> <arith> ...
942 /// ```
943 binop!(shift_expr, arith_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800944 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400945 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800946 punct!(>>) => { BinOp::Shr }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400947 ));
948
949 /// ```ignore
950 /// <term> + <term> ...
951 /// <term> - <term> ...
952 /// ```
953 binop!(arith_expr, term_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800954 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400955 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800956 punct!(-) => { BinOp::Sub }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400957 ));
958
959 /// ```ignore
960 /// <cast> * <cast> ...
961 /// <cast> / <cast> ...
962 /// <cast> % <cast> ...
963 /// ```
964 binop!(term_expr, cast_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800965 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400966 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800967 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400968 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800969 punct!(%) => { BinOp::Rem }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400970 ));
971
972 /// ```ignore
973 /// <unary> as <ty>
974 /// <unary> : <ty>
975 /// ```
976 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
977 mut e: call!(unary_expr, allow_struct, allow_block) >>
978 many0!(alt!(
979 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800980 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400981 // We can't accept `A + B` in cast expressions, as it's
982 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800983 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400984 ({
985 e = ExprCast {
986 expr: Box::new(e.into()),
987 as_token: as_,
988 ty: Box::new(ty),
989 }.into();
990 })
991 )
992 |
993 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800994 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400995 // We can't accept `A + B` in cast expressions, as it's
996 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800997 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400998 ({
999 e = ExprType {
1000 expr: Box::new(e.into()),
1001 colon_token: colon,
1002 ty: Box::new(ty),
1003 }.into();
1004 })
1005 )
1006 )) >>
1007 (e)
1008 ));
1009
1010 /// ```
1011 /// <UnOp> <trailer>
1012 /// & <trailer>
1013 /// &mut <trailer>
1014 /// box <trailer>
1015 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001016 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001017 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1018 do_parse!(
1019 op: syn!(UnOp) >>
1020 expr: call!(unary_expr, allow_struct, true) >>
1021 (ExprUnary {
1022 op: op,
1023 expr: Box::new(expr.into()),
1024 }.into())
1025 )
1026 |
1027 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001028 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001029 mutability: syn!(Mutability) >>
1030 expr: call!(unary_expr, allow_struct, true) >>
1031 (ExprAddrOf {
1032 and_token: and,
1033 mutbl: mutability,
1034 expr: Box::new(expr.into()),
1035 }.into())
1036 )
1037 |
1038 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001039 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001040 expr: call!(unary_expr, allow_struct, true) >>
1041 (ExprBox {
1042 box_token: box_,
1043 expr: Box::new(expr.into()),
1044 }.into())
1045 )
1046 |
1047 call!(trailer_expr, allow_struct, allow_block)
1048 ));
1049
Michael Layzell734adb42017-06-07 16:58:31 -04001050 // XXX: This duplication is ugly
1051 #[cfg(not(feature = "full"))]
1052 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1053 do_parse!(
1054 op: syn!(UnOp) >>
1055 expr: call!(unary_expr, allow_struct, true) >>
1056 (ExprUnary {
1057 op: op,
1058 expr: Box::new(expr.into()),
1059 }.into())
1060 )
1061 |
1062 call!(trailer_expr, allow_struct, allow_block)
1063 ));
1064
Michael Layzellb78f3b52017-06-04 19:03:03 -04001065 /// ```ignore
1066 /// <atom> (..<args>) ...
1067 /// <atom> . <ident> (..<args>) ...
1068 /// <atom> . <ident> ...
1069 /// <atom> . <lit> ...
1070 /// <atom> [ <expr> ] ...
1071 /// <atom> ? ...
1072 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001073 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001074 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1075 mut e: call!(atom_expr, allow_struct, allow_block) >>
1076 many0!(alt!(
1077 tap!(args: and_call => {
1078 let (args, paren) = args;
1079 e = ExprCall {
1080 func: Box::new(e.into()),
1081 args: args,
1082 paren_token: paren,
1083 }.into();
1084 })
1085 |
1086 tap!(more: and_method_call => {
1087 let mut call = more;
1088 call.expr = Box::new(e.into());
1089 e = call.into();
1090 })
1091 |
1092 tap!(field: and_field => {
1093 let (field, token) = field;
1094 e = ExprField {
1095 expr: Box::new(e.into()),
1096 field: field,
1097 dot_token: token,
1098 }.into();
1099 })
1100 |
1101 tap!(field: and_tup_field => {
1102 let (field, token) = field;
1103 e = ExprTupField {
1104 expr: Box::new(e.into()),
1105 field: field,
1106 dot_token: token,
1107 }.into();
1108 })
1109 |
1110 tap!(i: and_index => {
1111 let (i, token) = i;
1112 e = ExprIndex {
1113 expr: Box::new(e.into()),
1114 bracket_token: token,
1115 index: Box::new(i),
1116 }.into();
1117 })
1118 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001119 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001120 e = ExprTry {
1121 expr: Box::new(e.into()),
1122 question_token: question,
1123 }.into();
1124 })
1125 )) >>
1126 (e)
1127 ));
1128
Michael Layzell734adb42017-06-07 16:58:31 -04001129 // XXX: Duplication == ugly
1130 #[cfg(not(feature = "full"))]
1131 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1132 mut e: call!(atom_expr, allow_struct, allow_block) >>
1133 many0!(alt!(
1134 tap!(args: and_call => {
1135 let (args, paren) = args;
1136 e = ExprCall {
1137 func: Box::new(e.into()),
1138 args: args,
1139 paren_token: paren,
1140 }.into();
1141 })
1142 |
1143 tap!(i: and_index => {
1144 let (i, token) = i;
1145 e = ExprIndex {
1146 expr: Box::new(e.into()),
1147 bracket_token: token,
1148 index: Box::new(i),
1149 }.into();
1150 })
1151 )) >>
1152 (e)
1153 ));
1154
Michael Layzellb78f3b52017-06-04 19:03:03 -04001155 /// Parse all atomic expressions which don't have to worry about precidence
1156 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001157 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001158 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001159 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1160 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001161 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1162 |
1163 // must be before expr_path
1164 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1165 |
1166 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1167 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001168 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001169 |
1170 call!(expr_break, allow_struct) // must be before expr_path
1171 |
1172 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1173 |
1174 call!(expr_ret, allow_struct) // must be before expr_path
1175 |
1176 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1177 syn!(ExprInPlace) => { ExprKind::InPlace }
1178 |
1179 syn!(ExprArray) => { ExprKind::Array }
1180 |
1181 syn!(ExprTup) => { ExprKind::Tup }
1182 |
1183 syn!(ExprIf) => { ExprKind::If }
1184 |
1185 syn!(ExprIfLet) => { ExprKind::IfLet }
1186 |
1187 syn!(ExprWhile) => { ExprKind::While }
1188 |
1189 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1190 |
1191 syn!(ExprForLoop) => { ExprKind::ForLoop }
1192 |
1193 syn!(ExprLoop) => { ExprKind::Loop }
1194 |
1195 syn!(ExprMatch) => { ExprKind::Match }
1196 |
1197 syn!(ExprCatch) => { ExprKind::Catch }
1198 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001199 syn!(ExprYield) => { ExprKind::Yield }
1200 |
Nika Layzell640832a2017-12-04 13:37:09 -05001201 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1202 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001203 call!(expr_closure, allow_struct)
1204 |
1205 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1206 |
1207 // NOTE: This is the prefix-form of range
1208 call!(expr_range, allow_struct)
1209 |
1210 syn!(ExprPath) => { ExprKind::Path }
1211 |
1212 syn!(ExprRepeat) => { ExprKind::Repeat }
1213 ));
1214
Michael Layzell734adb42017-06-07 16:58:31 -04001215 #[cfg(not(feature = "full"))]
1216 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1217 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1218 |
1219 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1220 |
1221 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1222 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001223 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001224 |
1225 syn!(ExprPath) => { ExprKind::Path }
1226 ));
1227
1228
1229 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001230 named!(expr_nosemi -> Expr, map!(alt!(
1231 syn!(ExprIf) => { ExprKind::If }
1232 |
1233 syn!(ExprIfLet) => { ExprKind::IfLet }
1234 |
1235 syn!(ExprWhile) => { ExprKind::While }
1236 |
1237 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1238 |
1239 syn!(ExprForLoop) => { ExprKind::ForLoop }
1240 |
1241 syn!(ExprLoop) => { ExprKind::Loop }
1242 |
1243 syn!(ExprMatch) => { ExprKind::Match }
1244 |
1245 syn!(ExprCatch) => { ExprKind::Catch }
1246 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001247 syn!(ExprYield) => { ExprKind::Yield }
1248 |
Nika Layzell640832a2017-12-04 13:37:09 -05001249 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1250 |
Michael Layzell35418782017-06-07 09:20:25 -04001251 syn!(ExprBlock) => { ExprKind::Block }
1252 ), Expr::from));
1253
Michael Layzell93c36282017-06-04 20:43:14 -04001254 impl Synom for ExprGroup {
1255 named!(parse -> Self, do_parse!(
1256 e: grouped!(syn!(Expr)) >>
1257 (ExprGroup {
1258 expr: Box::new(e.0),
1259 group_token: e.1,
1260 }.into())
1261 ));
1262 }
1263
Alex Crichton954046c2017-05-30 21:49:42 -07001264 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001265 named!(parse -> Self, do_parse!(
1266 e: parens!(syn!(Expr)) >>
1267 (ExprParen {
1268 expr: Box::new(e.0),
1269 paren_token: e.1,
1270 }.into())
1271 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001272 }
David Tolnay89e05672016-10-02 14:39:42 -07001273
Michael Layzell734adb42017-06-07 16:58:31 -04001274 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001275 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001276 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001277 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001278 place: expr_no_struct >>
1279 value: braces!(call!(Block::parse_within)) >>
1280 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001281 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001282 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001283 value: Box::new(Expr {
1284 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001285 block: Block {
1286 stmts: value.0,
1287 brace_token: value.1,
1288 },
1289 }.into(),
1290 attrs: Vec::new(),
1291 }),
1292 })
1293 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001294 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001295
Michael Layzell734adb42017-06-07 16:58:31 -04001296 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001297 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001298 named!(parse -> Self, do_parse!(
1299 elems: brackets!(call!(Delimited::parse_terminated)) >>
1300 (ExprArray {
1301 exprs: elems.0,
1302 bracket_token: elems.1,
1303 })
1304 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001305 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001306
David Tolnayf8db7ba2017-11-11 22:52:16 -08001307 named!(and_call -> (Delimited<Expr, Token![,]>, tokens::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001308 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001309
Michael Layzell734adb42017-06-07 16:58:31 -04001310 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001311 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001312 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001313 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001314 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001315 colon2: punct!(::) >>
1316 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001317 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001318 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001319 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001320 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001321 args: parens!(call!(Delimited::parse_terminated)) >>
1322 ({
1323 let (colon2, lt, tys, gt) = match typarams {
1324 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1325 None => (None, None, None, None),
1326 };
1327 ExprMethodCall {
1328 // this expr will get overwritten after being returned
1329 expr: Box::new(ExprKind::Lit(Lit {
1330 span: Span::default(),
1331 value: LitKind::Bool(false),
1332 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001333
Alex Crichton954046c2017-05-30 21:49:42 -07001334 method: method,
1335 args: args.0,
1336 paren_token: args.1,
1337 dot_token: dot,
1338 lt_token: lt,
1339 gt_token: gt,
1340 colon2_token: colon2,
1341 typarams: tys.unwrap_or_default(),
1342 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001343 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001344 ));
1345
Michael Layzell734adb42017-06-07 16:58:31 -04001346 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001347 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001348 named!(parse -> Self, do_parse!(
1349 elems: parens!(call!(Delimited::parse_terminated)) >>
1350 (ExprTup {
1351 args: elems.0,
1352 paren_token: elems.1,
1353 lone_comma: None, // TODO: parse this
1354 })
1355 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001356 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001357
Michael Layzell734adb42017-06-07 16:58:31 -04001358 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001359 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001360 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001361 if_: keyword!(if) >>
1362 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001363 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001364 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001365 cond: expr_no_struct >>
1366 then_block: braces!(call!(Block::parse_within)) >>
1367 else_block: option!(else_block) >>
1368 (ExprIfLet {
1369 pat: Box::new(pat),
1370 let_token: let_,
1371 eq_token: eq,
1372 expr: Box::new(cond),
1373 if_true: Block {
1374 stmts: then_block.0,
1375 brace_token: then_block.1,
1376 },
1377 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001378 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001379 if_false: else_block.map(|p| Box::new(p.1.into())),
1380 })
1381 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001382 }
1383
Michael Layzell734adb42017-06-07 16:58:31 -04001384 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001385 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001386 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001387 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001388 cond: expr_no_struct >>
1389 then_block: braces!(call!(Block::parse_within)) >>
1390 else_block: option!(else_block) >>
1391 (ExprIf {
1392 cond: Box::new(cond),
1393 if_true: Block {
1394 stmts: then_block.0,
1395 brace_token: then_block.1,
1396 },
1397 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001398 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001399 if_false: else_block.map(|p| Box::new(p.1.into())),
1400 })
1401 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001402 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001403
Michael Layzell734adb42017-06-07 16:58:31 -04001404 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001405 named!(else_block -> (Token![else], ExprKind), do_parse!(
1406 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001407 expr: alt!(
1408 syn!(ExprIf) => { ExprKind::If }
1409 |
1410 syn!(ExprIfLet) => { ExprKind::IfLet }
1411 |
1412 do_parse!(
1413 else_block: braces!(call!(Block::parse_within)) >>
1414 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001415 block: Block {
1416 stmts: else_block.0,
1417 brace_token: else_block.1,
1418 },
1419 }))
David Tolnay939766a2016-09-23 23:48:12 -07001420 )
Alex Crichton954046c2017-05-30 21:49:42 -07001421 ) >>
1422 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001423 ));
1424
David Tolnaybb6feae2016-10-02 21:25:20 -07001425
Michael Layzell734adb42017-06-07 16:58:31 -04001426 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001427 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001428 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001429 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1430 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001431 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001432 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001433 expr: expr_no_struct >>
1434 loop_block: syn!(Block) >>
1435 (ExprForLoop {
1436 for_token: for_,
1437 in_token: in_,
1438 pat: Box::new(pat),
1439 expr: Box::new(expr),
1440 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001441 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001442 label: lbl.map(|p| p.0),
1443 })
1444 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001445 }
Gregory Katze5f35682016-09-27 14:20:55 -04001446
Michael Layzell734adb42017-06-07 16:58:31 -04001447 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001448 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001449 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001450 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1451 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001452 loop_block: syn!(Block) >>
1453 (ExprLoop {
1454 loop_token: loop_,
1455 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001456 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001457 label: lbl.map(|p| p.0),
1458 })
1459 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001460 }
1461
Michael Layzell734adb42017-06-07 16:58:31 -04001462 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001463 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001464 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001465 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001466 obj: expr_no_struct >>
Alex Crichton03b30272017-08-28 09:35:24 -07001467 res: braces!(many0!(syn!(Arm))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001468 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001469 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001470 ExprMatch {
1471 expr: Box::new(obj),
1472 match_token: match_,
1473 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001474 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001475 }
1476 })
1477 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001478 }
David Tolnay1978c672016-10-27 22:05:52 -07001479
Michael Layzell734adb42017-06-07 16:58:31 -04001480 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001481 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001482 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001483 do_: keyword!(do) >>
1484 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001485 catch_block: syn!(Block) >>
1486 (ExprCatch {
1487 block: catch_block,
1488 do_token: do_,
1489 catch_token: catch_,
1490 }.into())
1491 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001492 }
Arnavion02ef13f2017-04-25 00:54:31 -07001493
Michael Layzell734adb42017-06-07 16:58:31 -04001494 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001495 impl Synom for ExprYield {
1496 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001497 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001498 expr: option!(syn!(Expr)) >>
1499 (ExprYield {
1500 yield_token: yield_,
1501 expr: expr.map(Box::new),
1502 })
1503 ));
1504 }
1505
1506 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001507 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001508 named!(parse -> Self, do_parse!(
1509 attrs: many0!(call!(Attribute::parse_outer)) >>
1510 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001511 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1512 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001513 body: do_parse!(
1514 expr: alt!(expr_nosemi | syn!(Expr)) >>
1515 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1516 map!(input_end!(), |_| None)
1517 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001518 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001519 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001520 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001521 (expr, comma1.and_then(|x| x).or(comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001522 ) >>
1523 (Arm {
1524 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001525 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001526 attrs: attrs,
1527 pats: pats,
1528 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001529 body: Box::new(body.0),
1530 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001531 })
1532 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001533 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001534
Michael Layzell734adb42017-06-07 16:58:31 -04001535 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001536 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001537 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001538 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001539 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001540 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001541 ret_and_body: alt!(
1542 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001543 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001544 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001545 body: syn!(Block) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001546 (ReturnType::Type(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001547 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001548 block: body,
1549 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001550 )
1551 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001552 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001553 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001554 (ExprClosure {
1555 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001556 or1_token: or1,
1557 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001558 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001559 inputs: inputs,
1560 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001561 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001562 dot_tokens: None,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001563 fn_token: <Token![fn]>::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001564 generics: Generics::default(),
1565 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001566 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001567 body: Box::new(ret_and_body.1),
1568 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001569 ));
1570
Michael Layzell734adb42017-06-07 16:58:31 -04001571 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001572 named!(fn_arg -> FnArg, do_parse!(
1573 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001574 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001575 ({
1576 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001577 (<Token![:]>::default(), TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001578 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001579 }.into())
1580 });
1581 ArgCaptured {
1582 pat: pat,
1583 colon_token: colon,
1584 ty: ty,
1585 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001586 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001587 ));
1588
Michael Layzell734adb42017-06-07 16:58:31 -04001589 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001590 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001591 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001592 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1593 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001594 cond: expr_no_struct >>
1595 while_block: syn!(Block) >>
1596 (ExprWhile {
1597 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001598 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001599 cond: Box::new(cond),
1600 body: while_block,
1601 label: lbl.map(|p| p.0),
1602 })
1603 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001604 }
1605
Michael Layzell734adb42017-06-07 16:58:31 -04001606 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001607 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001608 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001609 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1610 while_: keyword!(while) >>
1611 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001612 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001613 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001614 value: expr_no_struct >>
1615 while_block: syn!(Block) >>
1616 (ExprWhileLet {
1617 eq_token: eq,
1618 let_token: let_,
1619 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001620 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001621 pat: Box::new(pat),
1622 expr: Box::new(value),
1623 body: while_block,
1624 label: lbl.map(|p| p.0),
1625 })
1626 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001627 }
1628
Michael Layzell734adb42017-06-07 16:58:31 -04001629 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001630 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001631 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001632 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001633 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001634 (ExprContinue {
1635 continue_token: cont,
1636 label: lbl,
1637 })
1638 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001639 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001640
Michael Layzell734adb42017-06-07 16:58:31 -04001641 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001642 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001643 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001644 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001645 // We can't allow blocks after a `break` expression when we wouldn't
1646 // allow structs, as this expression is ambiguous.
1647 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001648 (ExprBreak {
1649 label: lbl,
1650 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001651 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001652 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001653 ));
1654
Michael Layzell734adb42017-06-07 16:58:31 -04001655 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001656 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001657 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001658 // NOTE: return is greedy and eats blocks after it even when in a
1659 // position where structs are not allowed, such as in if statement
1660 // conditions. For example:
1661 //
1662 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001663 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001664 (ExprRet {
1665 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001666 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001667 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001668 ));
1669
Michael Layzell734adb42017-06-07 16:58:31 -04001670 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001671 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001672 named!(parse -> Self, do_parse!(
1673 path: syn!(Path) >>
1674 data: braces!(do_parse!(
1675 fields: call!(Delimited::parse_terminated) >>
1676 base: option!(
1677 cond!(fields.is_empty() || fields.trailing_delim(),
1678 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001679 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001680 base: syn!(Expr) >>
1681 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001682 )
Michael Layzell92639a52017-06-01 00:07:44 -04001683 )
1684 ) >>
1685 (fields, base)
1686 )) >>
1687 ({
1688 let ((fields, base), brace) = data;
1689 let (dots, rest) = match base.and_then(|b| b) {
1690 Some((dots, base)) => (Some(dots), Some(base)),
1691 None => (None, None),
1692 };
1693 ExprStruct {
1694 brace_token: brace,
1695 path: path,
1696 fields: fields,
1697 dot2_token: dots,
1698 rest: rest.map(Box::new),
1699 }
1700 })
1701 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001702 }
1703
Michael Layzell734adb42017-06-07 16:58:31 -04001704 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001705 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001706 named!(parse -> Self, alt!(
1707 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001708 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001709 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001710 value: syn!(Expr) >>
1711 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001712 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001713 expr: value,
1714 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001715 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001716 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001717 })
Michael Layzell92639a52017-06-01 00:07:44 -04001718 )
1719 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001720 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001721 ident: name.clone(),
1722 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1723 is_shorthand: true,
1724 attrs: Vec::new(),
1725 colon_token: None,
1726 })
1727 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001728 }
David Tolnay055a7042016-10-02 19:23:54 -07001729
Michael Layzell734adb42017-06-07 16:58:31 -04001730 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001731 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001732 named!(parse -> Self, do_parse!(
1733 data: brackets!(do_parse!(
1734 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001735 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001736 times: syn!(Expr) >>
1737 (value, semi, times)
1738 )) >>
1739 (ExprRepeat {
1740 expr: Box::new((data.0).0),
1741 amt: Box::new((data.0).2),
1742 bracket_token: data.1,
1743 semi_token: (data.0).1,
1744 })
1745 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001746 }
David Tolnay055a7042016-10-02 19:23:54 -07001747
Michael Layzell734adb42017-06-07 16:58:31 -04001748 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001749 impl Synom for ExprUnsafe {
1750 named!(parse -> Self, do_parse!(
1751 unsafe_: keyword!(unsafe) >>
1752 b: syn!(Block) >>
1753 (ExprUnsafe {
1754 unsafe_token: unsafe_,
1755 block: b,
1756 })
1757 ));
1758 }
1759
1760 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001761 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001762 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001763 b: syn!(Block) >>
1764 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001765 block: b,
1766 })
1767 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001768 }
David Tolnay89e05672016-10-02 14:39:42 -07001769
Michael Layzell734adb42017-06-07 16:58:31 -04001770 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001771 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001772 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001773 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001774 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001775 ));
1776
Michael Layzell734adb42017-06-07 16:58:31 -04001777 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001778 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001779 named!(parse -> Self, alt!(
1780 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001781 punct!(..=) => { RangeLimits::Closed }
1782 |
1783 // Must come before Dot2
1784 punct!(...) => { |dot3: Token![...]| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001785 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001786 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001787 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001788 }
David Tolnay438c9052016-10-07 23:24:48 -07001789
Alex Crichton954046c2017-05-30 21:49:42 -07001790 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001791 named!(parse -> Self, do_parse!(
1792 pair: qpath >>
1793 (ExprPath {
1794 qself: pair.0,
1795 path: pair.1,
1796 })
1797 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001798 }
David Tolnay42602292016-10-01 22:25:45 -07001799
Michael Layzell734adb42017-06-07 16:58:31 -04001800 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001801 named!(and_field -> (Ident, Token![.]),
1802 map!(tuple!(punct!(.), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001803
Michael Layzell734adb42017-06-07 16:58:31 -04001804 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001805 named!(and_tup_field -> (Lit, Token![.]),
1806 map!(tuple!(punct!(.), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001807
Alex Crichton954046c2017-05-30 21:49:42 -07001808 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001809
Michael Layzell734adb42017-06-07 16:58:31 -04001810 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001811 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001812 named!(parse -> Self, do_parse!(
1813 stmts: braces!(call!(Block::parse_within)) >>
1814 (Block {
1815 stmts: stmts.0,
1816 brace_token: stmts.1,
1817 })
1818 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001819 }
David Tolnay939766a2016-09-23 23:48:12 -07001820
Michael Layzell734adb42017-06-07 16:58:31 -04001821 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001822 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001823 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001824 many0!(punct!(;)) >>
1825 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001826 last: option!(do_parse!(
1827 attrs: many0!(call!(Attribute::parse_outer)) >>
1828 mut e: syn!(Expr) >>
1829 ({
1830 e.attrs = attrs;
1831 Stmt::Expr(Box::new(e))
1832 })
1833 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001834 (match last {
1835 None => standalone,
1836 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001837 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001838 standalone
1839 }
1840 })
1841 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001842 }
1843
Michael Layzell734adb42017-06-07 16:58:31 -04001844 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001845 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001846 named!(parse -> Self, alt!(
1847 stmt_mac
1848 |
1849 stmt_local
1850 |
1851 stmt_item
1852 |
Michael Layzell35418782017-06-07 09:20:25 -04001853 stmt_blockexpr
1854 |
Michael Layzell92639a52017-06-01 00:07:44 -04001855 stmt_expr
1856 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001857 }
David Tolnay939766a2016-09-23 23:48:12 -07001858
Michael Layzell734adb42017-06-07 16:58:31 -04001859 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001860 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001861 attrs: many0!(call!(Attribute::parse_outer)) >>
1862 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001863 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001864 // Only parse braces here; paren and bracket will get parsed as
1865 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001866 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001867 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001868 (Stmt::Macro(Box::new((
1869 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001870 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001871 bang_token: bang,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001872 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001873 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001874 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001875 })],
1876 },
Alex Crichton954046c2017-05-30 21:49:42 -07001877 match semi {
1878 Some(semi) => MacStmtStyle::Semicolon(semi),
1879 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001880 },
David Tolnayeea28d62016-10-25 20:44:08 -07001881 attrs,
1882 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001883 ));
1884
Michael Layzell734adb42017-06-07 16:58:31 -04001885 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001886 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001887 attrs: many0!(call!(Attribute::parse_outer)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001888 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001889 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001890 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001891 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1892 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001893 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001894 let_token: let_,
1895 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001896 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1897 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001898 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001899 ty: ty.map(|p| Box::new(p.1)),
1900 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001901 attrs: attrs,
1902 })))
1903 ));
1904
Michael Layzell734adb42017-06-07 16:58:31 -04001905 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001906 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001907
Michael Layzell734adb42017-06-07 16:58:31 -04001908 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001909 named!(stmt_blockexpr -> Stmt, do_parse!(
1910 attrs: many0!(call!(Attribute::parse_outer)) >>
1911 mut e: expr_nosemi >>
1912 // If the next token is a `.` or a `?` it is special-cased to parse as
1913 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001914 not!(punct!(.)) >>
1915 not!(punct!(?)) >>
1916 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001917 ({
1918 e.attrs = attrs;
1919 if let Some(semi) = semi {
1920 Stmt::Semi(Box::new(e), semi)
1921 } else {
1922 Stmt::Expr(Box::new(e))
1923 }
1924 })
1925 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001926
Michael Layzell734adb42017-06-07 16:58:31 -04001927 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001928 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001929 attrs: many0!(call!(Attribute::parse_outer)) >>
1930 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001931 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001932 ({
1933 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001934 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001935 })
David Tolnay939766a2016-09-23 23:48:12 -07001936 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001937
Michael Layzell734adb42017-06-07 16:58:31 -04001938 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001939 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001940 named!(parse -> Self, alt!(
1941 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1942 |
1943 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1944 |
1945 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1946 |
1947 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1948 |
1949 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1950 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001951 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001952 |
1953 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1954 |
1955 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1956 |
1957 syn!(PatPath) => { Pat::Path }
1958 |
1959 syn!(PatTuple) => { Pat::Tuple }
1960 |
1961 syn!(PatRef) => { Pat::Ref }
1962 |
1963 syn!(PatSlice) => { Pat::Slice }
1964 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001965 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001966
Michael Layzell734adb42017-06-07 16:58:31 -04001967 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001968 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001969 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001970 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001971 |u| PatWild { underscore_token: u }
1972 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001973 }
David Tolnay84aa0752016-10-02 23:01:13 -07001974
Michael Layzell734adb42017-06-07 16:58:31 -04001975 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001976 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001977 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001978 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001979 pat: syn!(Pat) >>
1980 (PatBox {
1981 pat: Box::new(pat),
1982 box_token: boxed,
1983 })
1984 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001985 }
1986
Michael Layzell734adb42017-06-07 16:58:31 -04001987 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001988 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001989 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001990 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001991 mutability: syn!(Mutability) >>
1992 name: alt!(
1993 syn!(Ident)
1994 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001995 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001996 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001997 not!(punct!(<)) >>
1998 not!(punct!(::)) >>
1999 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002000 (PatIdent {
2001 mode: match mode {
2002 Some(mode) => BindingMode::ByRef(mode, mutability),
2003 None => BindingMode::ByValue(mutability),
2004 },
2005 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002006 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002007 subpat: subpat.map(|p| Box::new(p.1)),
2008 })
2009 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002010 }
2011
Michael Layzell734adb42017-06-07 16:58:31 -04002012 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002013 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002014 named!(parse -> Self, do_parse!(
2015 path: syn!(Path) >>
2016 tuple: syn!(PatTuple) >>
2017 (PatTupleStruct {
2018 path: path,
2019 pat: tuple,
2020 })
2021 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002022 }
2023
Michael Layzell734adb42017-06-07 16:58:31 -04002024 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002025 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002026 named!(parse -> Self, do_parse!(
2027 path: syn!(Path) >>
2028 data: braces!(do_parse!(
2029 fields: call!(Delimited::parse_terminated) >>
2030 base: option!(
2031 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002032 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002033 ) >>
2034 (fields, base)
2035 )) >>
2036 (PatStruct {
2037 path: path,
2038 fields: (data.0).0,
2039 brace_token: data.1,
2040 dot2_token: (data.0).1.and_then(|m| m),
2041 })
2042 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002043 }
2044
Michael Layzell734adb42017-06-07 16:58:31 -04002045 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002046 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002047 named!(parse -> Self, alt!(
2048 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002049 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002050 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002051 pat: syn!(Pat) >>
2052 (FieldPat {
2053 ident: ident,
2054 pat: Box::new(pat),
2055 is_shorthand: false,
2056 attrs: Vec::new(),
2057 colon_token: Some(colon),
2058 })
2059 )
2060 |
2061 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002062 boxed: option!(keyword!(box)) >>
2063 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002064 mutability: syn!(Mutability) >>
2065 ident: syn!(Ident) >>
2066 ({
2067 let mut pat: Pat = PatIdent {
2068 mode: if let Some(mode) = mode {
2069 BindingMode::ByRef(mode, mutability)
2070 } else {
2071 BindingMode::ByValue(mutability)
2072 },
2073 ident: ident.clone(),
2074 subpat: None,
2075 at_token: None,
2076 }.into();
2077 if let Some(boxed) = boxed {
2078 pat = PatBox {
2079 pat: Box::new(pat),
2080 box_token: boxed,
2081 }.into();
2082 }
2083 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002084 ident: ident,
2085 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002086 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002087 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002088 colon_token: None,
2089 }
2090 })
2091 )
2092 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002093 }
2094
Michael Layzell734adb42017-06-07 16:58:31 -04002095 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002096 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002097 syn!(Ident)
2098 |
2099 do_parse!(
2100 lit: syn!(Lit) >>
2101 ({
David Tolnay570695e2017-06-03 16:15:13 -07002102 let s = lit.to_string();
2103 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002104 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002105 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002106 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002107 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002108 })
2109 )
2110 ));
2111
Michael Layzell734adb42017-06-07 16:58:31 -04002112 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002113 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002114 named!(parse -> Self, map!(
2115 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002116 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002117 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002118 }
David Tolnay9636c052016-10-02 17:11:17 -07002119
Michael Layzell734adb42017-06-07 16:58:31 -04002120 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002121 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002122 named!(parse -> Self, do_parse!(
2123 data: parens!(do_parse!(
2124 elems: call!(Delimited::parse_terminated) >>
2125 dotdot: map!(cond!(
2126 elems.is_empty() || elems.trailing_delim(),
2127 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002128 dots: punct!(..) >>
2129 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002130 (dots, trailing)
2131 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002132 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002133 rest: cond!(match dotdot {
2134 Some((_, Some(_))) => true,
2135 _ => false,
2136 },
2137 call!(Delimited::parse_terminated)) >>
2138 (elems, dotdot, rest)
2139 )) >>
2140 ({
2141 let ((mut elems, dotdot, rest), parens) = data;
2142 let (dotdot, trailing) = match dotdot {
2143 Some((a, b)) => (Some(a), Some(b)),
2144 None => (None, None),
2145 };
2146 PatTuple {
2147 paren_token: parens,
2148 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2149 dot2_token: dotdot,
2150 comma_token: trailing.and_then(|b| b),
2151 pats: {
2152 if let Some(rest) = rest {
2153 for elem in rest {
2154 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002155 }
Michael Layzell92639a52017-06-01 00:07:44 -04002156 }
2157 elems
2158 },
2159 }
2160 })
2161 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002162 }
David Tolnayfbb73232016-10-03 01:00:06 -07002163
Michael Layzell734adb42017-06-07 16:58:31 -04002164 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002165 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002166 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002167 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002168 mutability: syn!(Mutability) >>
2169 pat: syn!(Pat) >>
2170 (PatRef {
2171 pat: Box::new(pat),
2172 mutbl: mutability,
2173 and_token: and,
2174 })
2175 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002176 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002177
Michael Layzell734adb42017-06-07 16:58:31 -04002178 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002179 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002180 named!(parse -> Self, do_parse!(
2181 lit: pat_lit_expr >>
2182 (if let ExprKind::Path(_) = lit.node {
2183 return parse_error(); // these need to be parsed by pat_path
2184 } else {
2185 PatLit {
2186 expr: Box::new(lit),
2187 }
2188 })
2189 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002190 }
David Tolnaye1310902016-10-29 23:40:00 -07002191
Michael Layzell734adb42017-06-07 16:58:31 -04002192 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002193 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002194 named!(parse -> Self, do_parse!(
2195 lo: pat_lit_expr >>
2196 limits: syn!(RangeLimits) >>
2197 hi: pat_lit_expr >>
2198 (PatRange {
2199 lo: Box::new(lo),
2200 hi: Box::new(hi),
2201 limits: limits,
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")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002207 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002208 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002209 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002210 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002211 |
Alex Crichton954046c2017-05-30 21:49:42 -07002212 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002213 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002214 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002215 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002216 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002217 expr: Box::new(v.into())
2218 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002219 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002220 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002221 })
2222 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002223
Michael Layzell734adb42017-06-07 16:58:31 -04002224 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002225 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002226 named!(parse -> Self, map!(
2227 brackets!(do_parse!(
2228 before: call!(Delimited::parse_terminated) >>
2229 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002230 dots: punct!(..) >>
2231 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002232 (dots, trailing)
2233 )) >>
2234 after: cond!(
2235 match middle {
2236 Some((_, ref trailing)) => trailing.is_some(),
2237 _ => false,
2238 },
2239 call!(Delimited::parse_terminated)
2240 ) >>
2241 (before, middle, after)
2242 )),
2243 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002244 let mut before: Delimited<Pat, Token![,]> = before;
2245 let after: Option<Delimited<Pat, Token![,]>> = after;
2246 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002247 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002248 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002249 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002250 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002251 }),
2252 bracket_token: brackets,
2253 middle: middle.and_then(|_| {
2254 if !before.is_empty() && !before.trailing_delim() {
2255 Some(Box::new(before.pop().unwrap().into_item()))
2256 } else {
2257 None
2258 }
2259 }),
2260 front: before,
2261 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002262 }
Alex Crichton954046c2017-05-30 21:49:42 -07002263 }
Michael Layzell92639a52017-06-01 00:07:44 -04002264 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002265 }
David Tolnay435a9a82016-10-29 13:47:20 -07002266
Michael Layzell734adb42017-06-07 16:58:31 -04002267 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002268 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002269 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002270 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002271 |
2272 epsilon!() => { |_| CaptureBy::Ref }
2273 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002274 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002275}
2276
David Tolnayf4bbbd92016-09-23 14:41:55 -07002277#[cfg(feature = "printing")]
2278mod printing {
2279 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002280 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002281 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002282 use quote::{Tokens, ToTokens};
2283
Michael Layzell3936ceb2017-07-08 00:28:36 -04002284 /// If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2285 /// before appending it to `Tokens`.
2286 #[cfg(feature = "full")]
2287 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2288 if let ExprKind::Struct(_) = e.node {
2289 tokens::Paren::default().surround(tokens, |tokens| {
2290 e.to_tokens(tokens);
2291 });
2292 } else {
2293 e.to_tokens(tokens);
2294 }
2295 }
2296
David Tolnayf4bbbd92016-09-23 14:41:55 -07002297 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002298 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002299 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002300 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002301 self.node.to_tokens(tokens)
2302 }
Michael Layzell734adb42017-06-07 16:58:31 -04002303
2304 #[cfg(not(feature = "full"))]
2305 fn to_tokens(&self, tokens: &mut Tokens) {
2306 self.node.to_tokens(tokens)
2307 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002308 }
2309
Michael Layzell734adb42017-06-07 16:58:31 -04002310 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002311 impl ToTokens for ExprBox {
2312 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002313 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002314 self.expr.to_tokens(tokens);
2315 }
2316 }
2317
Michael Layzell734adb42017-06-07 16:58:31 -04002318 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002319 impl ToTokens for ExprInPlace {
2320 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002321 match self.kind {
2322 InPlaceKind::Arrow(ref arrow) => {
2323 self.place.to_tokens(tokens);
2324 arrow.to_tokens(tokens);
2325 self.value.to_tokens(tokens);
2326 }
2327 InPlaceKind::In(ref _in) => {
2328 _in.to_tokens(tokens);
2329 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002330 // NOTE: The second operand must be in a block, add one if
2331 // it is not present.
2332 if let ExprKind::Block(_) = self.value.node {
2333 self.value.to_tokens(tokens);
2334 } else {
2335 tokens::Brace::default().surround(tokens, |tokens| {
2336 self.value.to_tokens(tokens);
2337 })
2338 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002339 }
2340 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002341 }
2342 }
2343
Michael Layzell734adb42017-06-07 16:58:31 -04002344 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002345 impl ToTokens for ExprArray {
2346 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002347 self.bracket_token.surround(tokens, |tokens| {
2348 self.exprs.to_tokens(tokens);
2349 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002350 }
2351 }
2352
2353 impl ToTokens for ExprCall {
2354 fn to_tokens(&self, tokens: &mut Tokens) {
2355 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002356 self.paren_token.surround(tokens, |tokens| {
2357 self.args.to_tokens(tokens);
2358 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002359 }
2360 }
2361
Michael Layzell734adb42017-06-07 16:58:31 -04002362 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002363 impl ToTokens for ExprMethodCall {
2364 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002365 self.expr.to_tokens(tokens);
2366 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002367 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002368 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002369 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2370 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002371 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002372 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002373 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002374 self.paren_token.surround(tokens, |tokens| {
2375 self.args.to_tokens(tokens);
2376 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002377 }
2378 }
2379
Michael Layzell734adb42017-06-07 16:58:31 -04002380 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002381 impl ToTokens for ExprTup {
2382 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002383 self.paren_token.surround(tokens, |tokens| {
2384 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002385 // If we only have one argument, we need a trailing comma to
2386 // distinguish ExprTup from ExprParen.
2387 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002388 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002389 }
2390 // XXX: Not sure how to handle this, but we never parse it yet.
2391 // Is this for an expression like (0,)? Can't we use the
2392 // trailing delimiter on Delimited for that? (,) isn't a valid
2393 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002394 self.lone_comma.to_tokens(tokens);
2395 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002396 }
2397 }
2398
2399 impl ToTokens for ExprBinary {
2400 fn to_tokens(&self, tokens: &mut Tokens) {
2401 self.left.to_tokens(tokens);
2402 self.op.to_tokens(tokens);
2403 self.right.to_tokens(tokens);
2404 }
2405 }
2406
2407 impl ToTokens for ExprUnary {
2408 fn to_tokens(&self, tokens: &mut Tokens) {
2409 self.op.to_tokens(tokens);
2410 self.expr.to_tokens(tokens);
2411 }
2412 }
2413
2414 impl ToTokens for ExprCast {
2415 fn to_tokens(&self, tokens: &mut Tokens) {
2416 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002417 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002418 self.ty.to_tokens(tokens);
2419 }
2420 }
2421
2422 impl ToTokens for ExprType {
2423 fn to_tokens(&self, tokens: &mut Tokens) {
2424 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002425 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002426 self.ty.to_tokens(tokens);
2427 }
2428 }
2429
Michael Layzell734adb42017-06-07 16:58:31 -04002430 #[cfg(feature = "full")]
Michael Layzell3936ceb2017-07-08 00:28:36 -04002431 fn maybe_wrap_else(tokens: &mut Tokens,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002432 else_token: &Option<Token![else]>,
Michael Layzell3936ceb2017-07-08 00:28:36 -04002433 if_false: &Option<Box<Expr>>)
2434 {
2435 if let Some(ref if_false) = *if_false {
Alex Crichton259ee532017-07-14 06:51:02 -07002436 TokensOrDefault(&else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002437
2438 // If we are not one of the valid expressions to exist in an else
2439 // clause, wrap ourselves in a block.
2440 match if_false.node {
2441 ExprKind::If(_) |
2442 ExprKind::IfLet(_) |
2443 ExprKind::Block(_) => {
2444 if_false.to_tokens(tokens);
2445 }
2446 _ => {
2447 tokens::Brace::default().surround(tokens, |tokens| {
2448 if_false.to_tokens(tokens);
2449 });
2450 }
2451 }
2452 }
2453 }
2454
2455 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002456 impl ToTokens for ExprIf {
2457 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002458 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002459 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002460 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002461 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002462 }
2463 }
2464
Michael Layzell734adb42017-06-07 16:58:31 -04002465 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002466 impl ToTokens for ExprIfLet {
2467 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002468 self.if_token.to_tokens(tokens);
2469 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002470 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002471 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002472 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002473 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002474 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002475 }
2476 }
2477
Michael Layzell734adb42017-06-07 16:58:31 -04002478 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002479 impl ToTokens for ExprWhile {
2480 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002481 if self.label.is_some() {
2482 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002483 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002484 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002485 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002486 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002487 self.body.to_tokens(tokens);
2488 }
2489 }
2490
Michael Layzell734adb42017-06-07 16:58:31 -04002491 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002492 impl ToTokens for ExprWhileLet {
2493 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002494 if self.label.is_some() {
2495 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002496 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002497 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002498 self.while_token.to_tokens(tokens);
2499 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002500 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002501 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002502 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002503 self.body.to_tokens(tokens);
2504 }
2505 }
2506
Michael Layzell734adb42017-06-07 16:58:31 -04002507 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002508 impl ToTokens for ExprForLoop {
2509 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002510 if self.label.is_some() {
2511 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002512 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002513 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002514 self.for_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.in_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 ExprLoop {
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.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002530 self.body.to_tokens(tokens);
2531 }
2532 }
2533
Michael Layzell734adb42017-06-07 16:58:31 -04002534 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002535 impl ToTokens for ExprMatch {
2536 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002537 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002538 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002539 self.brace_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002540 for (i, arm) in self.arms.iter().enumerate() {
2541 arm.to_tokens(tokens);
2542 // Ensure that we have a comma after a non-block arm, except
2543 // for the last one.
2544 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002545 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002546 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002547 }
2548 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002549 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002550 }
2551 }
2552
Michael Layzell734adb42017-06-07 16:58:31 -04002553 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002554 impl ToTokens for ExprCatch {
2555 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002556 self.do_token.to_tokens(tokens);
2557 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 self.block.to_tokens(tokens);
2559 }
2560 }
2561
Michael Layzell734adb42017-06-07 16:58:31 -04002562 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002563 impl ToTokens for ExprYield {
2564 fn to_tokens(&self, tokens: &mut Tokens) {
2565 self.yield_token.to_tokens(tokens);
2566 self.expr.to_tokens(tokens);
2567 }
2568 }
2569
2570 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002571 impl ToTokens for ExprClosure {
2572 fn to_tokens(&self, tokens: &mut Tokens) {
2573 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002574 self.or1_token.to_tokens(tokens);
2575 for item in self.decl.inputs.iter() {
2576 match **item.item() {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002577 FnArg::Captured(ArgCaptured { ref pat, ty: Type::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002578 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002579 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002580 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002581 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002582 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002583 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002584 self.or2_token.to_tokens(tokens);
2585 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002586 self.body.to_tokens(tokens);
2587 }
2588 }
2589
Michael Layzell734adb42017-06-07 16:58:31 -04002590 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002591 impl ToTokens for ExprUnsafe {
2592 fn to_tokens(&self, tokens: &mut Tokens) {
2593 self.unsafe_token.to_tokens(tokens);
2594 self.block.to_tokens(tokens);
2595 }
2596 }
2597
2598 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002599 impl ToTokens for ExprBlock {
2600 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002601 self.block.to_tokens(tokens);
2602 }
2603 }
2604
Michael Layzell734adb42017-06-07 16:58:31 -04002605 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002606 impl ToTokens for ExprAssign {
2607 fn to_tokens(&self, tokens: &mut Tokens) {
2608 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002609 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002610 self.right.to_tokens(tokens);
2611 }
2612 }
2613
Michael Layzell734adb42017-06-07 16:58:31 -04002614 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 impl ToTokens for ExprAssignOp {
2616 fn to_tokens(&self, tokens: &mut Tokens) {
2617 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002618 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002619 self.right.to_tokens(tokens);
2620 }
2621 }
2622
Michael Layzell734adb42017-06-07 16:58:31 -04002623 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002624 impl ToTokens for ExprField {
2625 fn to_tokens(&self, tokens: &mut Tokens) {
2626 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002627 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002628 // XXX: I don't think we can do anything if someone shoves a
2629 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002630 self.field.to_tokens(tokens);
2631 }
2632 }
2633
Michael Layzell734adb42017-06-07 16:58:31 -04002634 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002635 impl ToTokens for ExprTupField {
2636 fn to_tokens(&self, tokens: &mut Tokens) {
2637 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002638 self.dot_token.to_tokens(tokens);
2639 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002640 }
2641 }
2642
2643 impl ToTokens for ExprIndex {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
2645 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002646 self.bracket_token.surround(tokens, |tokens| {
2647 self.index.to_tokens(tokens);
2648 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002649 }
2650 }
2651
Michael Layzell734adb42017-06-07 16:58:31 -04002652 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 impl ToTokens for ExprRange {
2654 fn to_tokens(&self, tokens: &mut Tokens) {
2655 self.from.to_tokens(tokens);
2656 self.limits.to_tokens(tokens);
2657 self.to.to_tokens(tokens);
2658 }
2659 }
2660
2661 impl ToTokens for ExprPath {
2662 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002663 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002664 }
2665 }
2666
Michael Layzell734adb42017-06-07 16:58:31 -04002667 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002668 impl ToTokens for ExprAddrOf {
2669 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002670 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 self.mutbl.to_tokens(tokens);
2672 self.expr.to_tokens(tokens);
2673 }
2674 }
2675
Michael Layzell734adb42017-06-07 16:58:31 -04002676 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002677 impl ToTokens for ExprBreak {
2678 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002679 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002680 self.label.to_tokens(tokens);
2681 self.expr.to_tokens(tokens);
2682 }
2683 }
2684
Michael Layzell734adb42017-06-07 16:58:31 -04002685 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002686 impl ToTokens for ExprContinue {
2687 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002688 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002689 self.label.to_tokens(tokens);
2690 }
2691 }
2692
Michael Layzell734adb42017-06-07 16:58:31 -04002693 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002694 impl ToTokens for ExprRet {
2695 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002696 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002697 self.expr.to_tokens(tokens);
2698 }
2699 }
2700
Michael Layzell734adb42017-06-07 16:58:31 -04002701 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002702 impl ToTokens for ExprStruct {
2703 fn to_tokens(&self, tokens: &mut Tokens) {
2704 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002705 self.brace_token.surround(tokens, |tokens| {
2706 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002707 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002708 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002709 self.rest.to_tokens(tokens);
2710 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002711 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002712 }
2713 }
2714
Michael Layzell734adb42017-06-07 16:58:31 -04002715 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002716 impl ToTokens for ExprRepeat {
2717 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002718 self.bracket_token.surround(tokens, |tokens| {
2719 self.expr.to_tokens(tokens);
2720 self.semi_token.to_tokens(tokens);
2721 self.amt.to_tokens(tokens);
2722 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002723 }
2724 }
2725
Michael Layzell93c36282017-06-04 20:43:14 -04002726 impl ToTokens for ExprGroup {
2727 fn to_tokens(&self, tokens: &mut Tokens) {
2728 self.group_token.surround(tokens, |tokens| {
2729 self.expr.to_tokens(tokens);
2730 });
2731 }
2732 }
2733
Alex Crichton62a0a592017-05-22 13:58:53 -07002734 impl ToTokens for ExprParen {
2735 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002736 self.paren_token.surround(tokens, |tokens| {
2737 self.expr.to_tokens(tokens);
2738 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002739 }
2740 }
2741
Michael Layzell734adb42017-06-07 16:58:31 -04002742 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002743 impl ToTokens for ExprTry {
2744 fn to_tokens(&self, tokens: &mut Tokens) {
2745 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002746 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002747 }
2748 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002749
Michael Layzell734adb42017-06-07 16:58:31 -04002750 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002751 impl ToTokens for FieldValue {
2752 fn to_tokens(&self, tokens: &mut Tokens) {
2753 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002754 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2755 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002756 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002757 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002758 self.expr.to_tokens(tokens);
2759 }
David Tolnay055a7042016-10-02 19:23:54 -07002760 }
2761 }
2762
Michael Layzell734adb42017-06-07 16:58:31 -04002763 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002764 impl ToTokens for Arm {
2765 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002766 tokens.append_all(&self.attrs);
2767 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002768 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002769 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002770 self.guard.to_tokens(tokens);
2771 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002772 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002773 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002774 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002775 }
2776 }
2777
Michael Layzell734adb42017-06-07 16:58:31 -04002778 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002779 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002780 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002781 self.underscore_token.to_tokens(tokens);
2782 }
2783 }
2784
Michael Layzell734adb42017-06-07 16:58:31 -04002785 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002786 impl ToTokens for PatIdent {
2787 fn to_tokens(&self, tokens: &mut Tokens) {
2788 self.mode.to_tokens(tokens);
2789 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002790 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002791 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002792 self.subpat.to_tokens(tokens);
2793 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002794 }
2795 }
2796
Michael Layzell734adb42017-06-07 16:58:31 -04002797 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002798 impl ToTokens for PatStruct {
2799 fn to_tokens(&self, tokens: &mut Tokens) {
2800 self.path.to_tokens(tokens);
2801 self.brace_token.surround(tokens, |tokens| {
2802 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002803 // NOTE: We need a comma before the dot2 token if it is present.
2804 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002805 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002806 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002807 self.dot2_token.to_tokens(tokens);
2808 });
2809 }
2810 }
2811
Michael Layzell734adb42017-06-07 16:58:31 -04002812 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002813 impl ToTokens for PatTupleStruct {
2814 fn to_tokens(&self, tokens: &mut Tokens) {
2815 self.path.to_tokens(tokens);
2816 self.pat.to_tokens(tokens);
2817 }
2818 }
2819
Michael Layzell734adb42017-06-07 16:58:31 -04002820 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002821 impl ToTokens for PatPath {
2822 fn to_tokens(&self, tokens: &mut Tokens) {
2823 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2824 }
2825 }
2826
Michael Layzell734adb42017-06-07 16:58:31 -04002827 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002828 impl ToTokens for PatTuple {
2829 fn to_tokens(&self, tokens: &mut Tokens) {
2830 self.paren_token.surround(tokens, |tokens| {
2831 for (i, token) in self.pats.iter().enumerate() {
2832 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002833 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2834 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002835 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002836 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002837 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002838
2839 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002840 // Ensure there is a comma before the .. token.
2841 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002842 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002843 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002844 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002845 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002846 });
2847 }
2848 }
2849
Michael Layzell734adb42017-06-07 16:58:31 -04002850 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002851 impl ToTokens for PatBox {
2852 fn to_tokens(&self, tokens: &mut Tokens) {
2853 self.box_token.to_tokens(tokens);
2854 self.pat.to_tokens(tokens);
2855 }
2856 }
2857
Michael Layzell734adb42017-06-07 16:58:31 -04002858 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002859 impl ToTokens for PatRef {
2860 fn to_tokens(&self, tokens: &mut Tokens) {
2861 self.and_token.to_tokens(tokens);
2862 self.mutbl.to_tokens(tokens);
2863 self.pat.to_tokens(tokens);
2864 }
2865 }
2866
Michael Layzell734adb42017-06-07 16:58:31 -04002867 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002868 impl ToTokens for PatLit {
2869 fn to_tokens(&self, tokens: &mut Tokens) {
2870 self.expr.to_tokens(tokens);
2871 }
2872 }
2873
Michael Layzell734adb42017-06-07 16:58:31 -04002874 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002875 impl ToTokens for PatRange {
2876 fn to_tokens(&self, tokens: &mut Tokens) {
2877 self.lo.to_tokens(tokens);
2878 self.limits.to_tokens(tokens);
2879 self.hi.to_tokens(tokens);
2880 }
2881 }
2882
Michael Layzell734adb42017-06-07 16:58:31 -04002883 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002884 impl ToTokens for PatSlice {
2885 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002886 // XXX: This is a mess, and it will be so easy to screw it up. How
2887 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002888 self.bracket_token.surround(tokens, |tokens| {
2889 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002890
2891 // If we need a comma before the middle or standalone .. token,
2892 // then make sure it's present.
2893 if !self.front.empty_or_trailing() &&
2894 (self.middle.is_some() || self.dot2_token.is_some())
2895 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002896 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002897 }
2898
2899 // If we have an identifier, we always need a .. token.
2900 if self.middle.is_some() {
2901 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002902 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002903 } else if self.dot2_token.is_some() {
2904 self.dot2_token.to_tokens(tokens);
2905 }
2906
2907 // Make sure we have a comma before the back half.
2908 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002909 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002910 self.back.to_tokens(tokens);
2911 } else {
2912 self.comma_token.to_tokens(tokens);
2913 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002914 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002915 }
2916 }
2917
Michael Layzell734adb42017-06-07 16:58:31 -04002918 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002919 impl ToTokens for RangeLimits {
2920 fn to_tokens(&self, tokens: &mut Tokens) {
2921 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002922 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2923 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002924 }
2925 }
2926 }
2927
Michael Layzell734adb42017-06-07 16:58:31 -04002928 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002929 impl ToTokens for FieldPat {
2930 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002931 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002932 if !self.is_shorthand {
2933 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002934 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002935 }
2936 self.pat.to_tokens(tokens);
2937 }
2938 }
2939
Michael Layzell734adb42017-06-07 16:58:31 -04002940 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002941 impl ToTokens for BindingMode {
2942 fn to_tokens(&self, tokens: &mut Tokens) {
2943 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002944 BindingMode::ByRef(ref t, ref m) => {
2945 t.to_tokens(tokens);
2946 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002947 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002948 BindingMode::ByValue(ref m) => {
2949 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002950 }
2951 }
2952 }
2953 }
David Tolnay42602292016-10-01 22:25:45 -07002954
Michael Layzell734adb42017-06-07 16:58:31 -04002955 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002956 impl ToTokens for CaptureBy {
2957 fn to_tokens(&self, tokens: &mut Tokens) {
2958 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002959 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002960 CaptureBy::Ref => {
2961 // nothing
2962 }
David Tolnay89e05672016-10-02 14:39:42 -07002963 }
2964 }
2965 }
2966
Michael Layzell734adb42017-06-07 16:58:31 -04002967 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002968 impl ToTokens for Block {
2969 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002970 self.brace_token.surround(tokens, |tokens| {
2971 tokens.append_all(&self.stmts);
2972 });
David Tolnay42602292016-10-01 22:25:45 -07002973 }
2974 }
2975
Michael Layzell734adb42017-06-07 16:58:31 -04002976 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002977 impl ToTokens for Stmt {
2978 fn to_tokens(&self, tokens: &mut Tokens) {
2979 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002980 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002981 Stmt::Item(ref item) => item.to_tokens(tokens),
2982 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002983 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002984 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002985 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002986 }
David Tolnaydecf28d2017-11-11 11:56:45 -08002987 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002988 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002989 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002990 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002991 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002992 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002993 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2994 // no semicolon
2995 }
David Tolnay13b3d352016-10-03 00:31:15 -07002996 }
2997 }
David Tolnay42602292016-10-01 22:25:45 -07002998 }
2999 }
3000 }
David Tolnay191e0582016-10-02 18:31:09 -07003001
Michael Layzell734adb42017-06-07 16:58:31 -04003002 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003003 impl ToTokens for Local {
3004 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003005 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003006 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003007 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003008 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003009 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003010 self.ty.to_tokens(tokens);
3011 }
3012 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003013 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003014 self.init.to_tokens(tokens);
3015 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003016 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003017 }
3018 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003019}