blob: a0505a4a4c3cf96473eb0cd113eb26129a045977 [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)`.
David Tolnay05362582017-12-26 01:33:57 -050073 pub Tuple(ExprTuple #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080074 pub args: Delimited<Expr, Token![,]>,
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 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500555 /// ```rust
556 /// # #![feature(dotdoteq_in_patterns)]
557 /// #
558 /// # fn main() {
559 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500561 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500563 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500565 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700566 /// ```
567 pub struct Arm {
568 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800569 pub pats: Delimited<Pat, Token![|]>,
570 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800572 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800574 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700575 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700576}
577
Michael Layzell734adb42017-06-07 16:58:31 -0400578#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700579ast_enum! {
580 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700581 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700582 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800583 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 Ref,
585 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700586}
587
Michael Layzell734adb42017-06-07 16:58:31 -0400588#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700589ast_enum! {
590 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700591 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700592 pub enum RangeLimits {
593 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800594 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700595 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800596 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700597 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700598}
599
Michael Layzell734adb42017-06-07 16:58:31 -0400600#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700601ast_struct! {
602 /// A single field in a struct pattern
603 ///
604 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
605 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
606 /// except `is_shorthand` is true
607 pub struct FieldPat {
608 /// The identifier for the field
609 pub ident: Ident,
610 /// The pattern the field is destructured to
611 pub pat: Box<Pat>,
612 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800613 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700614 pub attrs: Vec<Attribute>,
615 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700616}
617
Michael Layzell734adb42017-06-07 16:58:31 -0400618#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700619ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700620 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700621 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800622 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700623 ByValue(Mutability),
624 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700625}
626
Michael Layzell734adb42017-06-07 16:58:31 -0400627#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400628ast_enum! {
629 #[cfg_attr(feature = "clone-impls", derive(Copy))]
630 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800631 Arrow(Token![<-]),
632 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400633 }
634}
635
Michael Layzell3936ceb2017-07-08 00:28:36 -0400636#[cfg(any(feature = "parsing", feature = "printing"))]
637#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700638fn arm_expr_requires_comma(expr: &Expr) -> bool {
639 // see https://github.com/rust-lang/rust/blob/eb8f2586e
640 // /src/libsyntax/parse/classify.rs#L17-L37
641 match expr.node {
Nika Layzell640832a2017-12-04 13:37:09 -0500642 ExprKind::Unsafe(..) |
Alex Crichton03b30272017-08-28 09:35:24 -0700643 ExprKind::Block(..) |
644 ExprKind::If(..) |
645 ExprKind::IfLet(..) |
646 ExprKind::Match(..) |
647 ExprKind::While(..) |
648 ExprKind::WhileLet(..) |
649 ExprKind::Loop(..) |
650 ExprKind::ForLoop(..) |
651 ExprKind::Catch(..) => false,
652 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400653 }
654}
655
David Tolnayb9c8e322016-09-23 20:48:37 -0700656#[cfg(feature = "parsing")]
657pub mod parsing {
658 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700659 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700660
Michael Layzell734adb42017-06-07 16:58:31 -0400661 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700662 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500663 use synom::Synom;
664 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400665 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500666 use parse_error;
667 use PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700668
David Tolnaybcf26022017-12-25 22:10:52 -0500669 // When we're parsing expressions which occur before blocks, like in an if
670 // statement's condition, we cannot parse a struct literal.
671 //
672 // Struct literals are ambiguous in certain positions
673 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700674 macro_rules! ambiguous_expr {
675 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700676 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700677 };
678 }
679
David Tolnaybcf26022017-12-25 22:10:52 -0500680 // When we are parsing an optional suffix expression, we cannot allow blocks
681 // if structs are not allowed.
682 //
683 // Example:
684 //
685 // if break {} {}
686 //
687 // is ambiguous between:
688 //
689 // if (break {}) {}
690 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400691 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400692 macro_rules! opt_ambiguous_expr {
693 ($i:expr, $allow_struct:ident) => {
694 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
695 };
696 }
697
Alex Crichton954046c2017-05-30 21:49:42 -0700698 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400699 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700700
701 fn description() -> Option<&'static str> {
702 Some("expression")
703 }
704 }
705
Michael Layzell734adb42017-06-07 16:58:31 -0400706 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700707 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
708
David Tolnaybcf26022017-12-25 22:10:52 -0500709 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400710 #[cfg(feature = "full")]
711 fn ambiguous_expr(i: Cursor,
712 allow_struct: bool,
713 allow_block: bool)
714 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400715 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700716 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400717 call!(assign_expr, allow_struct, allow_block),
718 ExprKind::into
719 )
720 }
721
Michael Layzell734adb42017-06-07 16:58:31 -0400722 #[cfg(not(feature = "full"))]
723 fn ambiguous_expr(i: Cursor,
724 allow_struct: bool,
725 allow_block: bool)
726 -> PResult<Expr> {
727 map!(
728 i,
729 // NOTE: We intentionally skip assign_expr, placement_expr, and
730 // range_expr, as they are not parsed in non-full mode.
731 call!(or_expr, allow_struct, allow_block),
732 ExprKind::into
733 )
734 }
735
David Tolnaybcf26022017-12-25 22:10:52 -0500736 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400737 macro_rules! binop {
738 (
739 $name: ident,
740 $next: ident,
741 $submac: ident!( $($args:tt)* )
742 ) => {
743 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
744 mut e: call!($next, allow_struct, allow_block) >>
745 many0!(do_parse!(
746 op: $submac!($($args)*) >>
747 rhs: call!($next, allow_struct, true) >>
748 ({
749 e = ExprBinary {
750 left: Box::new(e.into()),
751 op: op,
752 right: Box::new(rhs.into()),
753 }.into();
754 })
755 )) >>
756 (e)
757 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700758 }
David Tolnay54e854d2016-10-24 12:03:30 -0700759 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700760
David Tolnaybcf26022017-12-25 22:10:52 -0500761 // <placement> = <placement> ..
762 // <placement> += <placement> ..
763 // <placement> -= <placement> ..
764 // <placement> *= <placement> ..
765 // <placement> /= <placement> ..
766 // <placement> %= <placement> ..
767 // <placement> ^= <placement> ..
768 // <placement> &= <placement> ..
769 // <placement> |= <placement> ..
770 // <placement> <<= <placement> ..
771 // <placement> >>= <placement> ..
772 //
773 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400774 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400775 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
776 mut e: call!(placement_expr, allow_struct, allow_block) >>
777 alt!(
778 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800779 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400780 // Recurse into self to parse right-associative operator.
781 rhs: call!(assign_expr, allow_struct, true) >>
782 ({
783 e = ExprAssign {
784 left: Box::new(e.into()),
785 eq_token: eq,
786 right: Box::new(rhs.into()),
787 }.into();
788 })
789 )
790 |
791 do_parse!(
792 op: call!(BinOp::parse_assign_op) >>
793 // Recurse into self to parse right-associative operator.
794 rhs: call!(assign_expr, allow_struct, true) >>
795 ({
796 e = ExprAssignOp {
797 left: Box::new(e.into()),
798 op: op,
799 right: Box::new(rhs.into()),
800 }.into();
801 })
802 )
803 |
804 epsilon!()
805 ) >>
806 (e)
807 ));
808
David Tolnaybcf26022017-12-25 22:10:52 -0500809 // <range> <- <range> ..
810 //
811 // NOTE: The `in place { expr }` version of this syntax is parsed in
812 // `atom_expr`, not here.
813 //
814 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400815 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400816 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
817 mut e: call!(range_expr, allow_struct, allow_block) >>
818 alt!(
819 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800820 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400821 // Recurse into self to parse right-associative operator.
822 rhs: call!(placement_expr, allow_struct, true) >>
823 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400824 e = ExprInPlace {
825 // op: BinOp::Place(larrow),
826 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400827 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400828 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400829 }.into();
830 })
831 )
832 |
833 epsilon!()
834 ) >>
835 (e)
836 ));
837
David Tolnaybcf26022017-12-25 22:10:52 -0500838 // <or> ... <or> ..
839 // <or> .. <or> ..
840 // <or> ..
841 //
842 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
843 // rules are for parsing these expressions are, but this is not correct.
844 // For example, `a .. b .. c` is not a legal expression. It should not
845 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
846 //
847 // NOTE: The form of ranges which don't include a preceding expression are
848 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400849 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400850 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
851 mut e: call!(or_expr, allow_struct, allow_block) >>
852 many0!(do_parse!(
853 limits: syn!(RangeLimits) >>
854 // We don't want to allow blocks here if we don't allow structs. See
855 // the reasoning for `opt_ambiguous_expr!` above.
856 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
857 ({
858 e = ExprRange {
859 from: Some(Box::new(e.into())),
860 limits: limits,
861 to: hi.map(|e| Box::new(e.into())),
862 }.into();
863 })
864 )) >>
865 (e)
866 ));
867
David Tolnaybcf26022017-12-25 22:10:52 -0500868 // <and> || <and> ...
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
David Tolnaybcf26022017-12-25 22:10:52 -0500871 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800872 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400873
David Tolnaybcf26022017-12-25 22:10:52 -0500874 // <bitor> == <bitor> ...
875 // <bitor> != <bitor> ...
876 // <bitor> >= <bitor> ...
877 // <bitor> <= <bitor> ...
878 // <bitor> > <bitor> ...
879 // <bitor> < <bitor> ...
880 //
881 // NOTE: This operator appears to be parsed as left-associative, but errors
882 // if it is used in a non-associative manner.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400883 binop!(compare_expr, bitor_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800884 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400885 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800886 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400887 |
888 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800889 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400890 |
891 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800892 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400893 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400894 do_parse!(
895 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800896 not!(punct!(<-)) >>
897 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400898 (BinOp::Lt(t))
899 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400900 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800901 punct!(>) => { BinOp::Gt }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902 ));
903
David Tolnaybcf26022017-12-25 22:10:52 -0500904 // <bitxor> | <bitxor> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400905 binop!(bitor_expr, bitxor_expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800906 not!(punct!(||)) >>
907 not!(punct!(|=)) >>
908 t: punct!(|) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400909 (BinOp::BitOr(t))
910 ));
911
David Tolnaybcf26022017-12-25 22:10:52 -0500912 // <bitand> ^ <bitand> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400913 binop!(bitxor_expr, bitand_expr, do_parse!(
914 // NOTE: Make sure we aren't looking at ^=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800915 not!(punct!(^=)) >>
916 t: punct!(^) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400917 (BinOp::BitXor(t))
918 ));
919
David Tolnaybcf26022017-12-25 22:10:52 -0500920 // <shift> & <shift> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400921 binop!(bitand_expr, shift_expr, do_parse!(
922 // NOTE: Make sure we aren't looking at && or &=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800923 not!(punct!(&&)) >>
924 not!(punct!(&=)) >>
925 t: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400926 (BinOp::BitAnd(t))
927 ));
928
David Tolnaybcf26022017-12-25 22:10:52 -0500929 // <arith> << <arith> ...
930 // <arith> >> <arith> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400931 binop!(shift_expr, arith_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800932 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400933 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800934 punct!(>>) => { BinOp::Shr }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400935 ));
936
David Tolnaybcf26022017-12-25 22:10:52 -0500937 // <term> + <term> ...
938 // <term> - <term> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400939 binop!(arith_expr, term_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800940 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400941 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800942 punct!(-) => { BinOp::Sub }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400943 ));
944
David Tolnaybcf26022017-12-25 22:10:52 -0500945 // <cast> * <cast> ...
946 // <cast> / <cast> ...
947 // <cast> % <cast> ...
Michael Layzellb78f3b52017-06-04 19:03:03 -0400948 binop!(term_expr, cast_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800949 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400950 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800951 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400952 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800953 punct!(%) => { BinOp::Rem }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400954 ));
955
David Tolnaybcf26022017-12-25 22:10:52 -0500956 // <unary> as <ty>
957 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400958 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
959 mut e: call!(unary_expr, allow_struct, allow_block) >>
960 many0!(alt!(
961 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800962 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400963 // We can't accept `A + B` in cast expressions, as it's
964 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800965 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400966 ({
967 e = ExprCast {
968 expr: Box::new(e.into()),
969 as_token: as_,
970 ty: Box::new(ty),
971 }.into();
972 })
973 )
974 |
975 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800976 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400977 // We can't accept `A + B` in cast expressions, as it's
978 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800979 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400980 ({
981 e = ExprType {
982 expr: Box::new(e.into()),
983 colon_token: colon,
984 ty: Box::new(ty),
985 }.into();
986 })
987 )
988 )) >>
989 (e)
990 ));
991
David Tolnaybcf26022017-12-25 22:10:52 -0500992 // <UnOp> <trailer>
993 // & <trailer>
994 // &mut <trailer>
995 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -0400996 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400997 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
998 do_parse!(
999 op: syn!(UnOp) >>
1000 expr: call!(unary_expr, allow_struct, true) >>
1001 (ExprUnary {
1002 op: op,
1003 expr: Box::new(expr.into()),
1004 }.into())
1005 )
1006 |
1007 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001008 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001009 mutability: syn!(Mutability) >>
1010 expr: call!(unary_expr, allow_struct, true) >>
1011 (ExprAddrOf {
1012 and_token: and,
1013 mutbl: mutability,
1014 expr: Box::new(expr.into()),
1015 }.into())
1016 )
1017 |
1018 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001019 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001020 expr: call!(unary_expr, allow_struct, true) >>
1021 (ExprBox {
1022 box_token: box_,
1023 expr: Box::new(expr.into()),
1024 }.into())
1025 )
1026 |
1027 call!(trailer_expr, allow_struct, allow_block)
1028 ));
1029
Michael Layzell734adb42017-06-07 16:58:31 -04001030 // XXX: This duplication is ugly
1031 #[cfg(not(feature = "full"))]
1032 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1033 do_parse!(
1034 op: syn!(UnOp) >>
1035 expr: call!(unary_expr, allow_struct, true) >>
1036 (ExprUnary {
1037 op: op,
1038 expr: Box::new(expr.into()),
1039 }.into())
1040 )
1041 |
1042 call!(trailer_expr, allow_struct, allow_block)
1043 ));
1044
David Tolnaybcf26022017-12-25 22:10:52 -05001045 // <atom> (..<args>) ...
1046 // <atom> . <ident> (..<args>) ...
1047 // <atom> . <ident> ...
1048 // <atom> . <lit> ...
1049 // <atom> [ <expr> ] ...
1050 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001051 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001052 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1053 mut e: call!(atom_expr, allow_struct, allow_block) >>
1054 many0!(alt!(
1055 tap!(args: and_call => {
1056 let (args, paren) = args;
1057 e = ExprCall {
1058 func: Box::new(e.into()),
1059 args: args,
1060 paren_token: paren,
1061 }.into();
1062 })
1063 |
1064 tap!(more: and_method_call => {
1065 let mut call = more;
1066 call.expr = Box::new(e.into());
1067 e = call.into();
1068 })
1069 |
1070 tap!(field: and_field => {
1071 let (field, token) = field;
1072 e = ExprField {
1073 expr: Box::new(e.into()),
1074 field: field,
1075 dot_token: token,
1076 }.into();
1077 })
1078 |
1079 tap!(field: and_tup_field => {
1080 let (field, token) = field;
1081 e = ExprTupField {
1082 expr: Box::new(e.into()),
1083 field: field,
1084 dot_token: token,
1085 }.into();
1086 })
1087 |
1088 tap!(i: and_index => {
1089 let (i, token) = i;
1090 e = ExprIndex {
1091 expr: Box::new(e.into()),
1092 bracket_token: token,
1093 index: Box::new(i),
1094 }.into();
1095 })
1096 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001097 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001098 e = ExprTry {
1099 expr: Box::new(e.into()),
1100 question_token: question,
1101 }.into();
1102 })
1103 )) >>
1104 (e)
1105 ));
1106
Michael Layzell734adb42017-06-07 16:58:31 -04001107 // XXX: Duplication == ugly
1108 #[cfg(not(feature = "full"))]
1109 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1110 mut e: call!(atom_expr, allow_struct, allow_block) >>
1111 many0!(alt!(
1112 tap!(args: and_call => {
1113 let (args, paren) = args;
1114 e = ExprCall {
1115 func: Box::new(e.into()),
1116 args: args,
1117 paren_token: paren,
1118 }.into();
1119 })
1120 |
1121 tap!(i: and_index => {
1122 let (i, token) = i;
1123 e = ExprIndex {
1124 expr: Box::new(e.into()),
1125 bracket_token: token,
1126 index: Box::new(i),
1127 }.into();
1128 })
1129 )) >>
1130 (e)
1131 ));
1132
David Tolnaybcf26022017-12-25 22:10:52 -05001133 // Parse all atomic expressions which don't have to worry about precidence
1134 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001135 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001136 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001137 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1138 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001139 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1140 |
1141 // must be before expr_path
1142 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1143 |
1144 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1145 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001146 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001147 |
1148 call!(expr_break, allow_struct) // must be before expr_path
1149 |
1150 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1151 |
1152 call!(expr_ret, allow_struct) // must be before expr_path
1153 |
1154 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1155 syn!(ExprInPlace) => { ExprKind::InPlace }
1156 |
1157 syn!(ExprArray) => { ExprKind::Array }
1158 |
David Tolnay05362582017-12-26 01:33:57 -05001159 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001160 |
1161 syn!(ExprIf) => { ExprKind::If }
1162 |
1163 syn!(ExprIfLet) => { ExprKind::IfLet }
1164 |
1165 syn!(ExprWhile) => { ExprKind::While }
1166 |
1167 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1168 |
1169 syn!(ExprForLoop) => { ExprKind::ForLoop }
1170 |
1171 syn!(ExprLoop) => { ExprKind::Loop }
1172 |
1173 syn!(ExprMatch) => { ExprKind::Match }
1174 |
1175 syn!(ExprCatch) => { ExprKind::Catch }
1176 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001177 syn!(ExprYield) => { ExprKind::Yield }
1178 |
Nika Layzell640832a2017-12-04 13:37:09 -05001179 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1180 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001181 call!(expr_closure, allow_struct)
1182 |
1183 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1184 |
1185 // NOTE: This is the prefix-form of range
1186 call!(expr_range, allow_struct)
1187 |
1188 syn!(ExprPath) => { ExprKind::Path }
1189 |
1190 syn!(ExprRepeat) => { ExprKind::Repeat }
1191 ));
1192
Michael Layzell734adb42017-06-07 16:58:31 -04001193 #[cfg(not(feature = "full"))]
1194 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1195 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1196 |
1197 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1198 |
1199 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1200 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001201 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001202 |
1203 syn!(ExprPath) => { ExprKind::Path }
1204 ));
1205
1206
1207 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001208 named!(expr_nosemi -> Expr, map!(alt!(
1209 syn!(ExprIf) => { ExprKind::If }
1210 |
1211 syn!(ExprIfLet) => { ExprKind::IfLet }
1212 |
1213 syn!(ExprWhile) => { ExprKind::While }
1214 |
1215 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1216 |
1217 syn!(ExprForLoop) => { ExprKind::ForLoop }
1218 |
1219 syn!(ExprLoop) => { ExprKind::Loop }
1220 |
1221 syn!(ExprMatch) => { ExprKind::Match }
1222 |
1223 syn!(ExprCatch) => { ExprKind::Catch }
1224 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001225 syn!(ExprYield) => { ExprKind::Yield }
1226 |
Nika Layzell640832a2017-12-04 13:37:09 -05001227 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1228 |
Michael Layzell35418782017-06-07 09:20:25 -04001229 syn!(ExprBlock) => { ExprKind::Block }
1230 ), Expr::from));
1231
Michael Layzell93c36282017-06-04 20:43:14 -04001232 impl Synom for ExprGroup {
1233 named!(parse -> Self, do_parse!(
1234 e: grouped!(syn!(Expr)) >>
1235 (ExprGroup {
1236 expr: Box::new(e.0),
1237 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001238 })
Michael Layzell93c36282017-06-04 20:43:14 -04001239 ));
1240 }
1241
Alex Crichton954046c2017-05-30 21:49:42 -07001242 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001243 named!(parse -> Self, do_parse!(
1244 e: parens!(syn!(Expr)) >>
1245 (ExprParen {
1246 expr: Box::new(e.0),
1247 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001248 })
Michael Layzell92639a52017-06-01 00:07:44 -04001249 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001250 }
David Tolnay89e05672016-10-02 14:39:42 -07001251
Michael Layzell734adb42017-06-07 16:58:31 -04001252 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001253 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001254 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001255 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001256 place: expr_no_struct >>
1257 value: braces!(call!(Block::parse_within)) >>
1258 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001259 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001260 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001261 value: Box::new(Expr {
1262 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001263 block: Block {
1264 stmts: value.0,
1265 brace_token: value.1,
1266 },
1267 }.into(),
1268 attrs: Vec::new(),
1269 }),
1270 })
1271 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001272 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001273
Michael Layzell734adb42017-06-07 16:58:31 -04001274 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001275 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001276 named!(parse -> Self, do_parse!(
1277 elems: brackets!(call!(Delimited::parse_terminated)) >>
1278 (ExprArray {
1279 exprs: elems.0,
1280 bracket_token: elems.1,
1281 })
1282 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001283 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001284
David Tolnayf8db7ba2017-11-11 22:52:16 -08001285 named!(and_call -> (Delimited<Expr, Token![,]>, tokens::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001286 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001287
Michael Layzell734adb42017-06-07 16:58:31 -04001288 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001289 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001290 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001291 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001292 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001293 colon2: punct!(::) >>
1294 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001295 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001296 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001297 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001298 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001299 args: parens!(call!(Delimited::parse_terminated)) >>
1300 ({
1301 let (colon2, lt, tys, gt) = match typarams {
1302 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1303 None => (None, None, None, None),
1304 };
1305 ExprMethodCall {
1306 // this expr will get overwritten after being returned
1307 expr: Box::new(ExprKind::Lit(Lit {
1308 span: Span::default(),
1309 value: LitKind::Bool(false),
1310 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001311
Alex Crichton954046c2017-05-30 21:49:42 -07001312 method: method,
1313 args: args.0,
1314 paren_token: args.1,
1315 dot_token: dot,
1316 lt_token: lt,
1317 gt_token: gt,
1318 colon2_token: colon2,
1319 typarams: tys.unwrap_or_default(),
1320 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001321 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001322 ));
1323
Michael Layzell734adb42017-06-07 16:58:31 -04001324 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001325 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001326 named!(parse -> Self, do_parse!(
1327 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001328 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001329 args: elems.0,
1330 paren_token: elems.1,
1331 lone_comma: None, // TODO: parse this
1332 })
1333 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001334 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001335
Michael Layzell734adb42017-06-07 16:58:31 -04001336 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001337 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001338 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001339 if_: keyword!(if) >>
1340 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001341 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001342 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001343 cond: expr_no_struct >>
1344 then_block: braces!(call!(Block::parse_within)) >>
1345 else_block: option!(else_block) >>
1346 (ExprIfLet {
1347 pat: Box::new(pat),
1348 let_token: let_,
1349 eq_token: eq,
1350 expr: Box::new(cond),
1351 if_true: Block {
1352 stmts: then_block.0,
1353 brace_token: then_block.1,
1354 },
1355 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001356 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001357 if_false: else_block.map(|p| Box::new(p.1.into())),
1358 })
1359 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001360 }
1361
Michael Layzell734adb42017-06-07 16:58:31 -04001362 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001363 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001364 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001365 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001366 cond: expr_no_struct >>
1367 then_block: braces!(call!(Block::parse_within)) >>
1368 else_block: option!(else_block) >>
1369 (ExprIf {
1370 cond: Box::new(cond),
1371 if_true: Block {
1372 stmts: then_block.0,
1373 brace_token: then_block.1,
1374 },
1375 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001376 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001377 if_false: else_block.map(|p| Box::new(p.1.into())),
1378 })
1379 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001380 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001381
Michael Layzell734adb42017-06-07 16:58:31 -04001382 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001383 named!(else_block -> (Token![else], ExprKind), do_parse!(
1384 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001385 expr: alt!(
1386 syn!(ExprIf) => { ExprKind::If }
1387 |
1388 syn!(ExprIfLet) => { ExprKind::IfLet }
1389 |
1390 do_parse!(
1391 else_block: braces!(call!(Block::parse_within)) >>
1392 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001393 block: Block {
1394 stmts: else_block.0,
1395 brace_token: else_block.1,
1396 },
1397 }))
David Tolnay939766a2016-09-23 23:48:12 -07001398 )
Alex Crichton954046c2017-05-30 21:49:42 -07001399 ) >>
1400 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001401 ));
1402
David Tolnaybb6feae2016-10-02 21:25:20 -07001403
Michael Layzell734adb42017-06-07 16:58:31 -04001404 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001405 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001406 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001407 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1408 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001409 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001410 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001411 expr: expr_no_struct >>
1412 loop_block: syn!(Block) >>
1413 (ExprForLoop {
1414 for_token: for_,
1415 in_token: in_,
1416 pat: Box::new(pat),
1417 expr: Box::new(expr),
1418 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001419 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001420 label: lbl.map(|p| p.0),
1421 })
1422 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001423 }
Gregory Katze5f35682016-09-27 14:20:55 -04001424
Michael Layzell734adb42017-06-07 16:58:31 -04001425 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001426 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001427 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001428 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1429 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001430 loop_block: syn!(Block) >>
1431 (ExprLoop {
1432 loop_token: loop_,
1433 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001434 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001435 label: lbl.map(|p| p.0),
1436 })
1437 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001438 }
1439
Michael Layzell734adb42017-06-07 16:58:31 -04001440 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001441 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001442 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001443 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001444 obj: expr_no_struct >>
Alex Crichton03b30272017-08-28 09:35:24 -07001445 res: braces!(many0!(syn!(Arm))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001446 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001447 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001448 ExprMatch {
1449 expr: Box::new(obj),
1450 match_token: match_,
1451 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001452 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001453 }
1454 })
1455 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001456 }
David Tolnay1978c672016-10-27 22:05:52 -07001457
Michael Layzell734adb42017-06-07 16:58:31 -04001458 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001459 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001460 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001461 do_: keyword!(do) >>
1462 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001463 catch_block: syn!(Block) >>
1464 (ExprCatch {
1465 block: catch_block,
1466 do_token: do_,
1467 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001468 })
Michael Layzell92639a52017-06-01 00:07:44 -04001469 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001470 }
Arnavion02ef13f2017-04-25 00:54:31 -07001471
Michael Layzell734adb42017-06-07 16:58:31 -04001472 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001473 impl Synom for ExprYield {
1474 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001475 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001476 expr: option!(syn!(Expr)) >>
1477 (ExprYield {
1478 yield_token: yield_,
1479 expr: expr.map(Box::new),
1480 })
1481 ));
1482 }
1483
1484 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001485 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001486 named!(parse -> Self, do_parse!(
1487 attrs: many0!(call!(Attribute::parse_outer)) >>
1488 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001489 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1490 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001491 body: do_parse!(
1492 expr: alt!(expr_nosemi | syn!(Expr)) >>
1493 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1494 map!(input_end!(), |_| None)
1495 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001496 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001497 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001498 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001499 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001500 ) >>
1501 (Arm {
1502 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001503 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001504 attrs: attrs,
1505 pats: pats,
1506 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001507 body: Box::new(body.0),
1508 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001509 })
1510 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001511 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001512
Michael Layzell734adb42017-06-07 16:58:31 -04001513 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001514 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001515 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001516 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001517 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001518 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001519 ret_and_body: alt!(
1520 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001521 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001522 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001523 body: syn!(Block) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001524 (ReturnType::Type(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001525 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001526 block: body,
1527 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001528 )
1529 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001530 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001531 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001532 (ExprClosure {
1533 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001534 or1_token: or1,
1535 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001536 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001537 inputs: inputs,
1538 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001539 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001540 dot_tokens: None,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001541 fn_token: <Token![fn]>::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001542 generics: Generics::default(),
1543 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001544 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001545 body: Box::new(ret_and_body.1),
1546 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001547 ));
1548
Michael Layzell734adb42017-06-07 16:58:31 -04001549 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001550 named!(fn_arg -> FnArg, do_parse!(
1551 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001552 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001553 ({
1554 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001555 (<Token![:]>::default(), TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001556 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001557 }.into())
1558 });
1559 ArgCaptured {
1560 pat: pat,
1561 colon_token: colon,
1562 ty: ty,
1563 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001564 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001565 ));
1566
Michael Layzell734adb42017-06-07 16:58:31 -04001567 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001568 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001569 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001570 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1571 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001572 cond: expr_no_struct >>
1573 while_block: syn!(Block) >>
1574 (ExprWhile {
1575 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001576 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001577 cond: Box::new(cond),
1578 body: while_block,
1579 label: lbl.map(|p| p.0),
1580 })
1581 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001582 }
1583
Michael Layzell734adb42017-06-07 16:58:31 -04001584 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001585 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001586 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001587 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1588 while_: keyword!(while) >>
1589 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001590 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001591 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001592 value: expr_no_struct >>
1593 while_block: syn!(Block) >>
1594 (ExprWhileLet {
1595 eq_token: eq,
1596 let_token: let_,
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 pat: Box::new(pat),
1600 expr: Box::new(value),
1601 body: while_block,
1602 label: lbl.map(|p| p.0),
1603 })
1604 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001605 }
1606
Michael Layzell734adb42017-06-07 16:58:31 -04001607 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001608 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001609 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001610 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001611 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001612 (ExprContinue {
1613 continue_token: cont,
1614 label: lbl,
1615 })
1616 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001617 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001618
Michael Layzell734adb42017-06-07 16:58:31 -04001619 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001620 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001621 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001622 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001623 // We can't allow blocks after a `break` expression when we wouldn't
1624 // allow structs, as this expression is ambiguous.
1625 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001626 (ExprBreak {
1627 label: lbl,
1628 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001629 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001630 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001631 ));
1632
Michael Layzell734adb42017-06-07 16:58:31 -04001633 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001634 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001635 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001636 // NOTE: return is greedy and eats blocks after it even when in a
1637 // position where structs are not allowed, such as in if statement
1638 // conditions. For example:
1639 //
David Tolnaybcf26022017-12-25 22:10:52 -05001640 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001641 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001642 (ExprRet {
1643 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001644 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001645 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001646 ));
1647
Michael Layzell734adb42017-06-07 16:58:31 -04001648 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001649 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001650 named!(parse -> Self, do_parse!(
1651 path: syn!(Path) >>
1652 data: braces!(do_parse!(
1653 fields: call!(Delimited::parse_terminated) >>
1654 base: option!(
1655 cond!(fields.is_empty() || fields.trailing_delim(),
1656 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001657 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001658 base: syn!(Expr) >>
1659 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001660 )
Michael Layzell92639a52017-06-01 00:07:44 -04001661 )
1662 ) >>
1663 (fields, base)
1664 )) >>
1665 ({
1666 let ((fields, base), brace) = data;
1667 let (dots, rest) = match base.and_then(|b| b) {
1668 Some((dots, base)) => (Some(dots), Some(base)),
1669 None => (None, None),
1670 };
1671 ExprStruct {
1672 brace_token: brace,
1673 path: path,
1674 fields: fields,
1675 dot2_token: dots,
1676 rest: rest.map(Box::new),
1677 }
1678 })
1679 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001680 }
1681
Michael Layzell734adb42017-06-07 16:58:31 -04001682 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001683 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001684 named!(parse -> Self, alt!(
1685 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001686 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001687 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001688 value: syn!(Expr) >>
1689 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001690 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001691 expr: value,
1692 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001693 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001694 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001695 })
Michael Layzell92639a52017-06-01 00:07:44 -04001696 )
1697 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001698 map!(syn!(Ident), |name| FieldValue {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001699 ident: name,
Michael Layzell92639a52017-06-01 00:07:44 -04001700 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1701 is_shorthand: true,
1702 attrs: Vec::new(),
1703 colon_token: None,
1704 })
1705 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001706 }
David Tolnay055a7042016-10-02 19:23:54 -07001707
Michael Layzell734adb42017-06-07 16:58:31 -04001708 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001709 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001710 named!(parse -> Self, do_parse!(
1711 data: brackets!(do_parse!(
1712 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001713 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001714 times: syn!(Expr) >>
1715 (value, semi, times)
1716 )) >>
1717 (ExprRepeat {
1718 expr: Box::new((data.0).0),
1719 amt: Box::new((data.0).2),
1720 bracket_token: data.1,
1721 semi_token: (data.0).1,
1722 })
1723 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001724 }
David Tolnay055a7042016-10-02 19:23:54 -07001725
Michael Layzell734adb42017-06-07 16:58:31 -04001726 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001727 impl Synom for ExprUnsafe {
1728 named!(parse -> Self, do_parse!(
1729 unsafe_: keyword!(unsafe) >>
1730 b: syn!(Block) >>
1731 (ExprUnsafe {
1732 unsafe_token: unsafe_,
1733 block: b,
1734 })
1735 ));
1736 }
1737
1738 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001739 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001740 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001741 b: syn!(Block) >>
1742 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001743 block: b,
1744 })
1745 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001746 }
David Tolnay89e05672016-10-02 14:39:42 -07001747
Michael Layzell734adb42017-06-07 16:58:31 -04001748 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001749 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001750 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001751 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001752 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001753 ));
1754
Michael Layzell734adb42017-06-07 16:58:31 -04001755 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001756 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001757 named!(parse -> Self, alt!(
1758 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001759 punct!(..=) => { RangeLimits::Closed }
1760 |
1761 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001762 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001763 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001764 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001765 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001766 }
David Tolnay438c9052016-10-07 23:24:48 -07001767
Alex Crichton954046c2017-05-30 21:49:42 -07001768 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001769 named!(parse -> Self, do_parse!(
1770 pair: qpath >>
1771 (ExprPath {
1772 qself: pair.0,
1773 path: pair.1,
1774 })
1775 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001776 }
David Tolnay42602292016-10-01 22:25:45 -07001777
Michael Layzell734adb42017-06-07 16:58:31 -04001778 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001779 named!(and_field -> (Ident, Token![.]),
1780 map!(tuple!(punct!(.), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001781
Michael Layzell734adb42017-06-07 16:58:31 -04001782 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001783 named!(and_tup_field -> (Lit, Token![.]),
1784 map!(tuple!(punct!(.), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001785
Alex Crichton954046c2017-05-30 21:49:42 -07001786 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001787
Michael Layzell734adb42017-06-07 16:58:31 -04001788 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001789 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001790 named!(parse -> Self, do_parse!(
1791 stmts: braces!(call!(Block::parse_within)) >>
1792 (Block {
1793 stmts: stmts.0,
1794 brace_token: stmts.1,
1795 })
1796 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001797 }
David Tolnay939766a2016-09-23 23:48:12 -07001798
Michael Layzell734adb42017-06-07 16:58:31 -04001799 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001800 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001801 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001802 many0!(punct!(;)) >>
1803 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001804 last: option!(do_parse!(
1805 attrs: many0!(call!(Attribute::parse_outer)) >>
1806 mut e: syn!(Expr) >>
1807 ({
1808 e.attrs = attrs;
1809 Stmt::Expr(Box::new(e))
1810 })
1811 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001812 (match last {
1813 None => standalone,
1814 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001815 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001816 standalone
1817 }
1818 })
1819 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001820 }
1821
Michael Layzell734adb42017-06-07 16:58:31 -04001822 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001823 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001824 named!(parse -> Self, alt!(
1825 stmt_mac
1826 |
1827 stmt_local
1828 |
1829 stmt_item
1830 |
Michael Layzell35418782017-06-07 09:20:25 -04001831 stmt_blockexpr
1832 |
Michael Layzell92639a52017-06-01 00:07:44 -04001833 stmt_expr
1834 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001835 }
David Tolnay939766a2016-09-23 23:48:12 -07001836
Michael Layzell734adb42017-06-07 16:58:31 -04001837 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001838 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001839 attrs: many0!(call!(Attribute::parse_outer)) >>
1840 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001841 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001842 // Only parse braces here; paren and bracket will get parsed as
1843 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001844 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001845 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001846 (Stmt::Macro(Box::new((
1847 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001848 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001849 bang_token: bang,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001850 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001851 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001852 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001853 })],
1854 },
Alex Crichton954046c2017-05-30 21:49:42 -07001855 match semi {
1856 Some(semi) => MacStmtStyle::Semicolon(semi),
1857 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001858 },
David Tolnayeea28d62016-10-25 20:44:08 -07001859 attrs,
1860 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001861 ));
1862
Michael Layzell734adb42017-06-07 16:58:31 -04001863 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001864 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001865 attrs: many0!(call!(Attribute::parse_outer)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001866 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001867 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001868 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001869 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1870 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001871 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001872 let_token: let_,
1873 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001874 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1875 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001876 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001877 ty: ty.map(|p| Box::new(p.1)),
1878 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001879 attrs: attrs,
1880 })))
1881 ));
1882
Michael Layzell734adb42017-06-07 16:58:31 -04001883 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001884 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001885
Michael Layzell734adb42017-06-07 16:58:31 -04001886 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001887 named!(stmt_blockexpr -> Stmt, do_parse!(
1888 attrs: many0!(call!(Attribute::parse_outer)) >>
1889 mut e: expr_nosemi >>
1890 // If the next token is a `.` or a `?` it is special-cased to parse as
1891 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001892 not!(punct!(.)) >>
1893 not!(punct!(?)) >>
1894 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001895 ({
1896 e.attrs = attrs;
1897 if let Some(semi) = semi {
1898 Stmt::Semi(Box::new(e), semi)
1899 } else {
1900 Stmt::Expr(Box::new(e))
1901 }
1902 })
1903 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001904
Michael Layzell734adb42017-06-07 16:58:31 -04001905 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001906 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001907 attrs: many0!(call!(Attribute::parse_outer)) >>
1908 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001909 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001910 ({
1911 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001912 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001913 })
David Tolnay939766a2016-09-23 23:48:12 -07001914 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001915
Michael Layzell734adb42017-06-07 16:58:31 -04001916 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001917 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001918 named!(parse -> Self, alt!(
1919 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1920 |
1921 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1922 |
1923 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1924 |
1925 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1926 |
1927 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1928 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001929 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001930 |
1931 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1932 |
1933 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1934 |
1935 syn!(PatPath) => { Pat::Path }
1936 |
1937 syn!(PatTuple) => { Pat::Tuple }
1938 |
1939 syn!(PatRef) => { Pat::Ref }
1940 |
1941 syn!(PatSlice) => { Pat::Slice }
1942 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001943 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001944
Michael Layzell734adb42017-06-07 16:58:31 -04001945 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001946 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001947 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001948 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001949 |u| PatWild { underscore_token: u }
1950 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001951 }
David Tolnay84aa0752016-10-02 23:01:13 -07001952
Michael Layzell734adb42017-06-07 16:58:31 -04001953 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001954 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001955 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001956 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001957 pat: syn!(Pat) >>
1958 (PatBox {
1959 pat: Box::new(pat),
1960 box_token: boxed,
1961 })
1962 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001963 }
1964
Michael Layzell734adb42017-06-07 16:58:31 -04001965 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001966 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001967 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001968 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001969 mutability: syn!(Mutability) >>
1970 name: alt!(
1971 syn!(Ident)
1972 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001973 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001974 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001975 not!(punct!(<)) >>
1976 not!(punct!(::)) >>
1977 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001978 (PatIdent {
1979 mode: match mode {
1980 Some(mode) => BindingMode::ByRef(mode, mutability),
1981 None => BindingMode::ByValue(mutability),
1982 },
1983 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001984 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001985 subpat: subpat.map(|p| Box::new(p.1)),
1986 })
1987 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001988 }
1989
Michael Layzell734adb42017-06-07 16:58:31 -04001990 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001991 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001992 named!(parse -> Self, do_parse!(
1993 path: syn!(Path) >>
1994 tuple: syn!(PatTuple) >>
1995 (PatTupleStruct {
1996 path: path,
1997 pat: tuple,
1998 })
1999 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002000 }
2001
Michael Layzell734adb42017-06-07 16:58:31 -04002002 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002003 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002004 named!(parse -> Self, do_parse!(
2005 path: syn!(Path) >>
2006 data: braces!(do_parse!(
2007 fields: call!(Delimited::parse_terminated) >>
2008 base: option!(
2009 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002010 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002011 ) >>
2012 (fields, base)
2013 )) >>
2014 (PatStruct {
2015 path: path,
2016 fields: (data.0).0,
2017 brace_token: data.1,
2018 dot2_token: (data.0).1.and_then(|m| m),
2019 })
2020 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002021 }
2022
Michael Layzell734adb42017-06-07 16:58:31 -04002023 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002024 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002025 named!(parse -> Self, alt!(
2026 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002027 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002028 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002029 pat: syn!(Pat) >>
2030 (FieldPat {
2031 ident: ident,
2032 pat: Box::new(pat),
2033 is_shorthand: false,
2034 attrs: Vec::new(),
2035 colon_token: Some(colon),
2036 })
2037 )
2038 |
2039 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002040 boxed: option!(keyword!(box)) >>
2041 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002042 mutability: syn!(Mutability) >>
2043 ident: syn!(Ident) >>
2044 ({
2045 let mut pat: Pat = PatIdent {
2046 mode: if let Some(mode) = mode {
2047 BindingMode::ByRef(mode, mutability)
2048 } else {
2049 BindingMode::ByValue(mutability)
2050 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002051 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002052 subpat: None,
2053 at_token: None,
2054 }.into();
2055 if let Some(boxed) = boxed {
2056 pat = PatBox {
2057 pat: Box::new(pat),
2058 box_token: boxed,
2059 }.into();
2060 }
2061 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002062 ident: ident,
2063 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002064 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002065 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002066 colon_token: None,
2067 }
2068 })
2069 )
2070 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002071 }
2072
Michael Layzell734adb42017-06-07 16:58:31 -04002073 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002074 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002075 syn!(Ident)
2076 |
2077 do_parse!(
2078 lit: syn!(Lit) >>
2079 ({
David Tolnay570695e2017-06-03 16:15:13 -07002080 let s = lit.to_string();
2081 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002082 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002083 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002084 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002085 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002086 })
2087 )
2088 ));
2089
Michael Layzell734adb42017-06-07 16:58:31 -04002090 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002091 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002092 named!(parse -> Self, map!(
2093 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002094 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002095 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002096 }
David Tolnay9636c052016-10-02 17:11:17 -07002097
Michael Layzell734adb42017-06-07 16:58:31 -04002098 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002099 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002100 named!(parse -> Self, do_parse!(
2101 data: parens!(do_parse!(
2102 elems: call!(Delimited::parse_terminated) >>
2103 dotdot: map!(cond!(
2104 elems.is_empty() || elems.trailing_delim(),
2105 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002106 dots: punct!(..) >>
2107 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002108 (dots, trailing)
2109 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002110 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002111 rest: cond!(match dotdot {
2112 Some((_, Some(_))) => true,
2113 _ => false,
2114 },
2115 call!(Delimited::parse_terminated)) >>
2116 (elems, dotdot, rest)
2117 )) >>
2118 ({
2119 let ((mut elems, dotdot, rest), parens) = data;
2120 let (dotdot, trailing) = match dotdot {
2121 Some((a, b)) => (Some(a), Some(b)),
2122 None => (None, None),
2123 };
2124 PatTuple {
2125 paren_token: parens,
2126 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2127 dot2_token: dotdot,
2128 comma_token: trailing.and_then(|b| b),
2129 pats: {
2130 if let Some(rest) = rest {
2131 for elem in rest {
2132 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002133 }
Michael Layzell92639a52017-06-01 00:07:44 -04002134 }
2135 elems
2136 },
2137 }
2138 })
2139 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002140 }
David Tolnayfbb73232016-10-03 01:00:06 -07002141
Michael Layzell734adb42017-06-07 16:58:31 -04002142 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002143 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002144 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002145 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002146 mutability: syn!(Mutability) >>
2147 pat: syn!(Pat) >>
2148 (PatRef {
2149 pat: Box::new(pat),
2150 mutbl: mutability,
2151 and_token: and,
2152 })
2153 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002154 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002155
Michael Layzell734adb42017-06-07 16:58:31 -04002156 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002157 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002158 named!(parse -> Self, do_parse!(
2159 lit: pat_lit_expr >>
2160 (if let ExprKind::Path(_) = lit.node {
2161 return parse_error(); // these need to be parsed by pat_path
2162 } else {
2163 PatLit {
2164 expr: Box::new(lit),
2165 }
2166 })
2167 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002168 }
David Tolnaye1310902016-10-29 23:40:00 -07002169
Michael Layzell734adb42017-06-07 16:58:31 -04002170 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002171 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002172 named!(parse -> Self, do_parse!(
2173 lo: pat_lit_expr >>
2174 limits: syn!(RangeLimits) >>
2175 hi: pat_lit_expr >>
2176 (PatRange {
2177 lo: Box::new(lo),
2178 hi: Box::new(hi),
2179 limits: limits,
2180 })
2181 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002182 }
David Tolnaye1310902016-10-29 23:40:00 -07002183
Michael Layzell734adb42017-06-07 16:58:31 -04002184 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002185 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002186 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002187 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002188 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002189 |
Alex Crichton954046c2017-05-30 21:49:42 -07002190 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002191 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002192 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002193 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002194 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002195 expr: Box::new(v.into())
2196 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002197 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002198 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002199 })
2200 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002201
Michael Layzell734adb42017-06-07 16:58:31 -04002202 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002203 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002204 named!(parse -> Self, map!(
2205 brackets!(do_parse!(
2206 before: call!(Delimited::parse_terminated) >>
2207 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002208 dots: punct!(..) >>
2209 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002210 (dots, trailing)
2211 )) >>
2212 after: cond!(
2213 match middle {
2214 Some((_, ref trailing)) => trailing.is_some(),
2215 _ => false,
2216 },
2217 call!(Delimited::parse_terminated)
2218 ) >>
2219 (before, middle, after)
2220 )),
2221 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002222 let mut before: Delimited<Pat, Token![,]> = before;
2223 let after: Option<Delimited<Pat, Token![,]>> = after;
2224 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002225 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002226 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002227 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002228 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002229 }),
2230 bracket_token: brackets,
2231 middle: middle.and_then(|_| {
2232 if !before.is_empty() && !before.trailing_delim() {
2233 Some(Box::new(before.pop().unwrap().into_item()))
2234 } else {
2235 None
2236 }
2237 }),
2238 front: before,
2239 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002240 }
Alex Crichton954046c2017-05-30 21:49:42 -07002241 }
Michael Layzell92639a52017-06-01 00:07:44 -04002242 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002243 }
David Tolnay435a9a82016-10-29 13:47:20 -07002244
Michael Layzell734adb42017-06-07 16:58:31 -04002245 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002246 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002247 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002248 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002249 |
2250 epsilon!() => { |_| CaptureBy::Ref }
2251 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002252 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002253}
2254
David Tolnayf4bbbd92016-09-23 14:41:55 -07002255#[cfg(feature = "printing")]
2256mod printing {
2257 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002258 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002259 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002260 use quote::{Tokens, ToTokens};
2261
David Tolnaybcf26022017-12-25 22:10:52 -05002262 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2263 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002264 #[cfg(feature = "full")]
2265 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2266 if let ExprKind::Struct(_) = e.node {
2267 tokens::Paren::default().surround(tokens, |tokens| {
2268 e.to_tokens(tokens);
2269 });
2270 } else {
2271 e.to_tokens(tokens);
2272 }
2273 }
2274
David Tolnayf4bbbd92016-09-23 14:41:55 -07002275 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002276 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002277 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002278 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002279 self.node.to_tokens(tokens)
2280 }
Michael Layzell734adb42017-06-07 16:58:31 -04002281
2282 #[cfg(not(feature = "full"))]
2283 fn to_tokens(&self, tokens: &mut Tokens) {
2284 self.node.to_tokens(tokens)
2285 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002286 }
2287
Michael Layzell734adb42017-06-07 16:58:31 -04002288 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002289 impl ToTokens for ExprBox {
2290 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002291 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002292 self.expr.to_tokens(tokens);
2293 }
2294 }
2295
Michael Layzell734adb42017-06-07 16:58:31 -04002296 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002297 impl ToTokens for ExprInPlace {
2298 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002299 match self.kind {
2300 InPlaceKind::Arrow(ref arrow) => {
2301 self.place.to_tokens(tokens);
2302 arrow.to_tokens(tokens);
2303 self.value.to_tokens(tokens);
2304 }
2305 InPlaceKind::In(ref _in) => {
2306 _in.to_tokens(tokens);
2307 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002308 // NOTE: The second operand must be in a block, add one if
2309 // it is not present.
2310 if let ExprKind::Block(_) = self.value.node {
2311 self.value.to_tokens(tokens);
2312 } else {
2313 tokens::Brace::default().surround(tokens, |tokens| {
2314 self.value.to_tokens(tokens);
2315 })
2316 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002317 }
2318 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002319 }
2320 }
2321
Michael Layzell734adb42017-06-07 16:58:31 -04002322 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002323 impl ToTokens for ExprArray {
2324 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002325 self.bracket_token.surround(tokens, |tokens| {
2326 self.exprs.to_tokens(tokens);
2327 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002328 }
2329 }
2330
2331 impl ToTokens for ExprCall {
2332 fn to_tokens(&self, tokens: &mut Tokens) {
2333 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002334 self.paren_token.surround(tokens, |tokens| {
2335 self.args.to_tokens(tokens);
2336 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002337 }
2338 }
2339
Michael Layzell734adb42017-06-07 16:58:31 -04002340 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002341 impl ToTokens for ExprMethodCall {
2342 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002343 self.expr.to_tokens(tokens);
2344 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002345 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002346 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002347 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2348 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002349 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002350 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002351 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002352 self.paren_token.surround(tokens, |tokens| {
2353 self.args.to_tokens(tokens);
2354 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002355 }
2356 }
2357
Michael Layzell734adb42017-06-07 16:58:31 -04002358 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002359 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002360 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002361 self.paren_token.surround(tokens, |tokens| {
2362 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002363 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002364 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002365 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002366 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002367 }
2368 // XXX: Not sure how to handle this, but we never parse it yet.
2369 // Is this for an expression like (0,)? Can't we use the
2370 // trailing delimiter on Delimited for that? (,) isn't a valid
2371 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002372 self.lone_comma.to_tokens(tokens);
2373 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002374 }
2375 }
2376
2377 impl ToTokens for ExprBinary {
2378 fn to_tokens(&self, tokens: &mut Tokens) {
2379 self.left.to_tokens(tokens);
2380 self.op.to_tokens(tokens);
2381 self.right.to_tokens(tokens);
2382 }
2383 }
2384
2385 impl ToTokens for ExprUnary {
2386 fn to_tokens(&self, tokens: &mut Tokens) {
2387 self.op.to_tokens(tokens);
2388 self.expr.to_tokens(tokens);
2389 }
2390 }
2391
2392 impl ToTokens for ExprCast {
2393 fn to_tokens(&self, tokens: &mut Tokens) {
2394 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002395 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002396 self.ty.to_tokens(tokens);
2397 }
2398 }
2399
2400 impl ToTokens for ExprType {
2401 fn to_tokens(&self, tokens: &mut Tokens) {
2402 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002403 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002404 self.ty.to_tokens(tokens);
2405 }
2406 }
2407
Michael Layzell734adb42017-06-07 16:58:31 -04002408 #[cfg(feature = "full")]
Michael Layzell3936ceb2017-07-08 00:28:36 -04002409 fn maybe_wrap_else(tokens: &mut Tokens,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002410 else_token: &Option<Token![else]>,
Michael Layzell3936ceb2017-07-08 00:28:36 -04002411 if_false: &Option<Box<Expr>>)
2412 {
2413 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002414 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002415
2416 // If we are not one of the valid expressions to exist in an else
2417 // clause, wrap ourselves in a block.
2418 match if_false.node {
2419 ExprKind::If(_) |
2420 ExprKind::IfLet(_) |
2421 ExprKind::Block(_) => {
2422 if_false.to_tokens(tokens);
2423 }
2424 _ => {
2425 tokens::Brace::default().surround(tokens, |tokens| {
2426 if_false.to_tokens(tokens);
2427 });
2428 }
2429 }
2430 }
2431 }
2432
2433 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002434 impl ToTokens for ExprIf {
2435 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002436 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002437 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002438 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002439 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002440 }
2441 }
2442
Michael Layzell734adb42017-06-07 16:58:31 -04002443 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002444 impl ToTokens for ExprIfLet {
2445 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002446 self.if_token.to_tokens(tokens);
2447 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002448 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002449 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002450 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002451 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002452 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002453 }
2454 }
2455
Michael Layzell734adb42017-06-07 16:58:31 -04002456 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002457 impl ToTokens for ExprWhile {
2458 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002459 if self.label.is_some() {
2460 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002461 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002462 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002463 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002464 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002465 self.body.to_tokens(tokens);
2466 }
2467 }
2468
Michael Layzell734adb42017-06-07 16:58:31 -04002469 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002470 impl ToTokens for ExprWhileLet {
2471 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002472 if self.label.is_some() {
2473 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002474 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002475 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002476 self.while_token.to_tokens(tokens);
2477 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002478 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002479 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002480 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002481 self.body.to_tokens(tokens);
2482 }
2483 }
2484
Michael Layzell734adb42017-06-07 16:58:31 -04002485 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002486 impl ToTokens for ExprForLoop {
2487 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002488 if self.label.is_some() {
2489 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002490 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002491 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002492 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002493 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002494 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002495 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002496 self.body.to_tokens(tokens);
2497 }
2498 }
2499
Michael Layzell734adb42017-06-07 16:58:31 -04002500 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002501 impl ToTokens for ExprLoop {
2502 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002503 if self.label.is_some() {
2504 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002505 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002506 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002507 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002508 self.body.to_tokens(tokens);
2509 }
2510 }
2511
Michael Layzell734adb42017-06-07 16:58:31 -04002512 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002513 impl ToTokens for ExprMatch {
2514 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002515 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002516 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002517 self.brace_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002518 for (i, arm) in self.arms.iter().enumerate() {
2519 arm.to_tokens(tokens);
2520 // Ensure that we have a comma after a non-block arm, except
2521 // for the last one.
2522 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002523 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002524 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002525 }
2526 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002527 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002528 }
2529 }
2530
Michael Layzell734adb42017-06-07 16:58:31 -04002531 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002532 impl ToTokens for ExprCatch {
2533 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002534 self.do_token.to_tokens(tokens);
2535 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002536 self.block.to_tokens(tokens);
2537 }
2538 }
2539
Michael Layzell734adb42017-06-07 16:58:31 -04002540 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002541 impl ToTokens for ExprYield {
2542 fn to_tokens(&self, tokens: &mut Tokens) {
2543 self.yield_token.to_tokens(tokens);
2544 self.expr.to_tokens(tokens);
2545 }
2546 }
2547
2548 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002549 impl ToTokens for ExprClosure {
2550 fn to_tokens(&self, tokens: &mut Tokens) {
2551 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002552 self.or1_token.to_tokens(tokens);
2553 for item in self.decl.inputs.iter() {
2554 match **item.item() {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002555 FnArg::Captured(ArgCaptured { ref pat, ty: Type::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002556 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002557 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002558 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002559 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002560 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002561 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002562 self.or2_token.to_tokens(tokens);
2563 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002564 self.body.to_tokens(tokens);
2565 }
2566 }
2567
Michael Layzell734adb42017-06-07 16:58:31 -04002568 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002569 impl ToTokens for ExprUnsafe {
2570 fn to_tokens(&self, tokens: &mut Tokens) {
2571 self.unsafe_token.to_tokens(tokens);
2572 self.block.to_tokens(tokens);
2573 }
2574 }
2575
2576 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002577 impl ToTokens for ExprBlock {
2578 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002579 self.block.to_tokens(tokens);
2580 }
2581 }
2582
Michael Layzell734adb42017-06-07 16:58:31 -04002583 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002584 impl ToTokens for ExprAssign {
2585 fn to_tokens(&self, tokens: &mut Tokens) {
2586 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002587 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002588 self.right.to_tokens(tokens);
2589 }
2590 }
2591
Michael Layzell734adb42017-06-07 16:58:31 -04002592 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002593 impl ToTokens for ExprAssignOp {
2594 fn to_tokens(&self, tokens: &mut Tokens) {
2595 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002596 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002597 self.right.to_tokens(tokens);
2598 }
2599 }
2600
Michael Layzell734adb42017-06-07 16:58:31 -04002601 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002602 impl ToTokens for ExprField {
2603 fn to_tokens(&self, tokens: &mut Tokens) {
2604 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002605 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002606 // XXX: I don't think we can do anything if someone shoves a
2607 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002608 self.field.to_tokens(tokens);
2609 }
2610 }
2611
Michael Layzell734adb42017-06-07 16:58:31 -04002612 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 impl ToTokens for ExprTupField {
2614 fn to_tokens(&self, tokens: &mut Tokens) {
2615 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002616 self.dot_token.to_tokens(tokens);
2617 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002618 }
2619 }
2620
2621 impl ToTokens for ExprIndex {
2622 fn to_tokens(&self, tokens: &mut Tokens) {
2623 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002624 self.bracket_token.surround(tokens, |tokens| {
2625 self.index.to_tokens(tokens);
2626 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002627 }
2628 }
2629
Michael Layzell734adb42017-06-07 16:58:31 -04002630 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002631 impl ToTokens for ExprRange {
2632 fn to_tokens(&self, tokens: &mut Tokens) {
2633 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002634 match self.limits {
2635 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2636 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2637 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002638 self.to.to_tokens(tokens);
2639 }
2640 }
2641
2642 impl ToTokens for ExprPath {
2643 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002644 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002645 }
2646 }
2647
Michael Layzell734adb42017-06-07 16:58:31 -04002648 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002649 impl ToTokens for ExprAddrOf {
2650 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002651 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002652 self.mutbl.to_tokens(tokens);
2653 self.expr.to_tokens(tokens);
2654 }
2655 }
2656
Michael Layzell734adb42017-06-07 16:58:31 -04002657 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002658 impl ToTokens for ExprBreak {
2659 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002660 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002661 self.label.to_tokens(tokens);
2662 self.expr.to_tokens(tokens);
2663 }
2664 }
2665
Michael Layzell734adb42017-06-07 16:58:31 -04002666 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002667 impl ToTokens for ExprContinue {
2668 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002669 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002670 self.label.to_tokens(tokens);
2671 }
2672 }
2673
Michael Layzell734adb42017-06-07 16:58:31 -04002674 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002675 impl ToTokens for ExprRet {
2676 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002677 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002678 self.expr.to_tokens(tokens);
2679 }
2680 }
2681
Michael Layzell734adb42017-06-07 16:58:31 -04002682 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002683 impl ToTokens for ExprStruct {
2684 fn to_tokens(&self, tokens: &mut Tokens) {
2685 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002686 self.brace_token.surround(tokens, |tokens| {
2687 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002688 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002689 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002690 self.rest.to_tokens(tokens);
2691 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002692 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002693 }
2694 }
2695
Michael Layzell734adb42017-06-07 16:58:31 -04002696 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002697 impl ToTokens for ExprRepeat {
2698 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002699 self.bracket_token.surround(tokens, |tokens| {
2700 self.expr.to_tokens(tokens);
2701 self.semi_token.to_tokens(tokens);
2702 self.amt.to_tokens(tokens);
2703 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002704 }
2705 }
2706
Michael Layzell93c36282017-06-04 20:43:14 -04002707 impl ToTokens for ExprGroup {
2708 fn to_tokens(&self, tokens: &mut Tokens) {
2709 self.group_token.surround(tokens, |tokens| {
2710 self.expr.to_tokens(tokens);
2711 });
2712 }
2713 }
2714
Alex Crichton62a0a592017-05-22 13:58:53 -07002715 impl ToTokens for ExprParen {
2716 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002717 self.paren_token.surround(tokens, |tokens| {
2718 self.expr.to_tokens(tokens);
2719 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002720 }
2721 }
2722
Michael Layzell734adb42017-06-07 16:58:31 -04002723 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002724 impl ToTokens for ExprTry {
2725 fn to_tokens(&self, tokens: &mut Tokens) {
2726 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002727 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002728 }
2729 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002730
Michael Layzell734adb42017-06-07 16:58:31 -04002731 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002732 impl ToTokens for FieldValue {
2733 fn to_tokens(&self, tokens: &mut Tokens) {
2734 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002735 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2736 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002737 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002738 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002739 self.expr.to_tokens(tokens);
2740 }
David Tolnay055a7042016-10-02 19:23:54 -07002741 }
2742 }
2743
Michael Layzell734adb42017-06-07 16:58:31 -04002744 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002745 impl ToTokens for Arm {
2746 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002747 tokens.append_all(&self.attrs);
2748 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002749 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002750 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002751 self.guard.to_tokens(tokens);
2752 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002753 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002754 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002755 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002756 }
2757 }
2758
Michael Layzell734adb42017-06-07 16:58:31 -04002759 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002760 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002761 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002762 self.underscore_token.to_tokens(tokens);
2763 }
2764 }
2765
Michael Layzell734adb42017-06-07 16:58:31 -04002766 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002767 impl ToTokens for PatIdent {
2768 fn to_tokens(&self, tokens: &mut Tokens) {
2769 self.mode.to_tokens(tokens);
2770 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002771 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002772 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002773 self.subpat.to_tokens(tokens);
2774 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -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 PatStruct {
2780 fn to_tokens(&self, tokens: &mut Tokens) {
2781 self.path.to_tokens(tokens);
2782 self.brace_token.surround(tokens, |tokens| {
2783 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002784 // NOTE: We need a comma before the dot2 token if it is present.
2785 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002786 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002787 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002788 self.dot2_token.to_tokens(tokens);
2789 });
2790 }
2791 }
2792
Michael Layzell734adb42017-06-07 16:58:31 -04002793 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002794 impl ToTokens for PatTupleStruct {
2795 fn to_tokens(&self, tokens: &mut Tokens) {
2796 self.path.to_tokens(tokens);
2797 self.pat.to_tokens(tokens);
2798 }
2799 }
2800
Michael Layzell734adb42017-06-07 16:58:31 -04002801 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002802 impl ToTokens for PatPath {
2803 fn to_tokens(&self, tokens: &mut Tokens) {
2804 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2805 }
2806 }
2807
Michael Layzell734adb42017-06-07 16:58:31 -04002808 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002809 impl ToTokens for PatTuple {
2810 fn to_tokens(&self, tokens: &mut Tokens) {
2811 self.paren_token.surround(tokens, |tokens| {
2812 for (i, token) in self.pats.iter().enumerate() {
2813 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002814 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2815 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002816 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002817 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002818 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002819
2820 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002821 // Ensure there is a comma before the .. token.
2822 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002823 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002824 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002825 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002826 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002827 });
2828 }
2829 }
2830
Michael Layzell734adb42017-06-07 16:58:31 -04002831 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002832 impl ToTokens for PatBox {
2833 fn to_tokens(&self, tokens: &mut Tokens) {
2834 self.box_token.to_tokens(tokens);
2835 self.pat.to_tokens(tokens);
2836 }
2837 }
2838
Michael Layzell734adb42017-06-07 16:58:31 -04002839 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002840 impl ToTokens for PatRef {
2841 fn to_tokens(&self, tokens: &mut Tokens) {
2842 self.and_token.to_tokens(tokens);
2843 self.mutbl.to_tokens(tokens);
2844 self.pat.to_tokens(tokens);
2845 }
2846 }
2847
Michael Layzell734adb42017-06-07 16:58:31 -04002848 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002849 impl ToTokens for PatLit {
2850 fn to_tokens(&self, tokens: &mut Tokens) {
2851 self.expr.to_tokens(tokens);
2852 }
2853 }
2854
Michael Layzell734adb42017-06-07 16:58:31 -04002855 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002856 impl ToTokens for PatRange {
2857 fn to_tokens(&self, tokens: &mut Tokens) {
2858 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002859 match self.limits {
2860 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2861 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2862 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002863 self.hi.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 PatSlice {
2869 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002870 // XXX: This is a mess, and it will be so easy to screw it up. How
2871 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002872 self.bracket_token.surround(tokens, |tokens| {
2873 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002874
2875 // If we need a comma before the middle or standalone .. token,
2876 // then make sure it's present.
2877 if !self.front.empty_or_trailing() &&
2878 (self.middle.is_some() || self.dot2_token.is_some())
2879 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002880 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002881 }
2882
2883 // If we have an identifier, we always need a .. token.
2884 if self.middle.is_some() {
2885 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002886 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002887 } else if self.dot2_token.is_some() {
2888 self.dot2_token.to_tokens(tokens);
2889 }
2890
2891 // Make sure we have a comma before the back half.
2892 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002893 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002894 self.back.to_tokens(tokens);
2895 } else {
2896 self.comma_token.to_tokens(tokens);
2897 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002898 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002899 }
2900 }
2901
Michael Layzell734adb42017-06-07 16:58:31 -04002902 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002903 impl ToTokens for FieldPat {
2904 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002905 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002906 if !self.is_shorthand {
2907 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002908 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002909 }
2910 self.pat.to_tokens(tokens);
2911 }
2912 }
2913
Michael Layzell734adb42017-06-07 16:58:31 -04002914 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002915 impl ToTokens for BindingMode {
2916 fn to_tokens(&self, tokens: &mut Tokens) {
2917 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002918 BindingMode::ByRef(ref t, ref m) => {
2919 t.to_tokens(tokens);
2920 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002921 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002922 BindingMode::ByValue(ref m) => {
2923 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002924 }
2925 }
2926 }
2927 }
David Tolnay42602292016-10-01 22:25:45 -07002928
Michael Layzell734adb42017-06-07 16:58:31 -04002929 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002930 impl ToTokens for CaptureBy {
2931 fn to_tokens(&self, tokens: &mut Tokens) {
2932 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002933 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002934 CaptureBy::Ref => {
2935 // nothing
2936 }
David Tolnay89e05672016-10-02 14:39:42 -07002937 }
2938 }
2939 }
2940
Michael Layzell734adb42017-06-07 16:58:31 -04002941 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002942 impl ToTokens for Block {
2943 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002944 self.brace_token.surround(tokens, |tokens| {
2945 tokens.append_all(&self.stmts);
2946 });
David Tolnay42602292016-10-01 22:25:45 -07002947 }
2948 }
2949
Michael Layzell734adb42017-06-07 16:58:31 -04002950 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002951 impl ToTokens for Stmt {
2952 fn to_tokens(&self, tokens: &mut Tokens) {
2953 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002954 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002955 Stmt::Item(ref item) => item.to_tokens(tokens),
2956 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002957 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002958 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002959 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002960 }
David Tolnaydecf28d2017-11-11 11:56:45 -08002961 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002962 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002963 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002964 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002965 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002966 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002967 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2968 // no semicolon
2969 }
David Tolnay13b3d352016-10-03 00:31:15 -07002970 }
2971 }
David Tolnay42602292016-10-01 22:25:45 -07002972 }
2973 }
2974 }
David Tolnay191e0582016-10-02 18:31:09 -07002975
Michael Layzell734adb42017-06-07 16:58:31 -04002976 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002977 impl ToTokens for Local {
2978 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002979 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002980 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002981 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002982 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002983 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002984 self.ty.to_tokens(tokens);
2985 }
2986 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002987 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002988 self.init.to_tokens(tokens);
2989 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002990 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002991 }
2992 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002993}