blob: 0ed97972628e0144b29ccb4c7cec7092c73cd04a [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.
27 pub Box(ExprBox {
28 pub expr: Box<Expr>,
Alex Crichton954046c2017-05-30 21:49:42 -070029 pub box_token: tokens::Box_,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Alex Crichton62a0a592017-05-22 13:58:53 -070032 /// E.g. 'place <- val'.
33 pub InPlace(ExprInPlace {
34 pub place: Box<Expr>,
35 pub value: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070036 pub in_token: tokens::In,
Alex Crichton62a0a592017-05-22 13:58:53 -070037 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
40 pub Array(ExprArray {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub exprs: Delimited<Expr, tokens::Comma>,
42 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>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 pub args: Delimited<Expr, tokens::Comma>,
49 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.
55 /// The vector of `Ty`s are the ascripted type parameters for the method
56 /// (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])`.
60 pub MethodCall(ExprMethodCall {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070063 pub typarams: Delimited<Ty, tokens::Comma>,
64 pub args: Delimited<Expr, tokens::Comma>,
65 pub paren_token: tokens::Paren,
66 pub dot_token: tokens::Dot,
67 pub lt_token: Option<tokens::Lt>,
68 pub colon2_token: Option<tokens::Colon2>,
69 pub gt_token: Option<tokens::Gt>,
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)`.
73 pub Tup(ExprTup {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070074 pub args: Delimited<Expr, tokens::Comma>,
75 pub paren_token: tokens::Paren,
76 pub lone_comma: Option<tokens::Comma>,
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>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070098 pub as_token: tokens::As,
Alex Crichton62a0a592017-05-22 13:58:53 -070099 pub ty: Box<Ty>,
100 }),
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>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 pub ty: Box<Ty>,
107 }),
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 }`
112 pub If(ExprIf {
113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 pub if_token: tokens::If,
117 pub else_token: Option<tokens::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.
125 pub IfLet(ExprIfLet {
126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700130 pub if_token: tokens::If,
131 pub let_token: tokens::Let,
132 pub eq_token: tokens::Eq,
133 pub else_token: Option<tokens::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 }`
139 pub While(ExprWhile {
140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 pub colon_token: Option<tokens::Colon>,
144 pub while_token: tokens::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.
152 pub WhileLet(ExprWhileLet {
153 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>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700157 pub colon_token: Option<tokens::Colon>,
158 pub while_token: tokens::While,
159 pub let_token: tokens::Let,
160 pub eq_token: tokens::Eq,
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.
168 pub ForLoop(ExprForLoop {
169 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>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700173 pub for_token: tokens::For,
174 pub colon_token: Option<tokens::Colon>,
175 pub in_token: tokens::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 }`
181 pub Loop(ExprLoop {
182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700184 pub loop_token: tokens::Loop,
185 pub colon_token: Option<tokens::Colon>,
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.
189 pub Match(ExprMatch {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 pub match_token: tokens::Match,
191 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`)
197 pub Closure(ExprClosure {
198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201 pub or1_token: tokens::Or,
202 pub or2_token: tokens::Or,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// A block (`{ ... }` or `unsafe { ... }`)
206 pub Block(ExprBlock {
207 pub unsafety: Unsafety,
208 pub block: Block,
209 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700210
Alex Crichton62a0a592017-05-22 13:58:53 -0700211 /// An assignment (`a = foo()`)
212 pub Assign(ExprAssign {
213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700215 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500217
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 /// An assignment with an operator
219 ///
220 /// For example, `a += 1`.
221 pub AssignOp(ExprAssignOp {
222 pub op: BinOp,
223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// Access of a named struct field (`obj.foo`)
228 pub Field(ExprField {
229 pub expr: Box<Expr>,
230 pub field: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500233
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 /// Access of an unnamed field of a struct or tuple-struct
235 ///
236 /// For example, `foo.0`.
237 pub TupField(ExprTupField {
238 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700239 pub field: Lit,
240 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500242
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 /// An indexing operation (`foo[2]`)
244 pub Index(ExprIndex {
245 pub expr: Box<Expr>,
246 pub index: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500249
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
251 pub Range(ExprRange {
252 pub from: Option<Box<Expr>>,
253 pub to: Option<Box<Expr>>,
254 pub limits: RangeLimits,
255 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700256
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 /// Variable reference, possibly containing `::` and/or type
258 /// parameters, e.g. foo::bar::<baz>.
259 ///
260 /// Optionally "qualified",
261 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
262 pub Path(ExprPath {
263 pub qself: Option<QSelf>,
264 pub path: Path,
265 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700266
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 /// A referencing operation (`&a` or `&mut a`)
268 pub AddrOf(ExprAddrOf {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 pub and_token: tokens::And,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub mutbl: Mutability,
271 pub expr: Box<Expr>,
272 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500273
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 /// A `break`, with an optional label to break, and an optional expression
275 pub Break(ExprBreak {
David Tolnay63e3dee2017-06-03 20:13:17 -0700276 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700278 pub break_token: tokens::Break,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500280
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// A `continue`, with an optional label
282 pub Continue(ExprContinue {
David Tolnay63e3dee2017-06-03 20:13:17 -0700283 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 pub continue_token: tokens::Continue,
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500286
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 /// A `return`, with an optional value to be returned
288 pub Ret(ExprRet {
289 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 pub return_token: tokens::Return,
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700292
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 /// A macro invocation; pre-expansion
294 pub Mac(Mac),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700295
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 /// A struct literal expression.
297 ///
298 /// For example, `Foo {x: 1, y: 2}`, or
299 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
300 pub Struct(ExprStruct {
301 pub path: Path,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 pub fields: Delimited<FieldValue, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub rest: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700304 pub dot2_token: Option<tokens::Dot2>,
305 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700307
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 /// An array literal constructed from one repeated element.
309 ///
310 /// For example, `[1; 5]`. The first expression is the element
311 /// to be repeated; the second is the number of times to repeat it.
312 pub Repeat(ExprRepeat {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 pub bracket_token: tokens::Bracket,
314 pub semi_token: tokens::Semi,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub expr: Box<Expr>,
316 pub amt: Box<Expr>,
317 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700318
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 /// No-op: used solely so we can pretty-print faithfully
320 pub Paren(ExprParen {
321 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700322 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700324
Alex Crichton62a0a592017-05-22 13:58:53 -0700325 /// `expr?`
326 pub Try(ExprTry {
327 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700328 pub question_token: tokens::Question,
Alex Crichton62a0a592017-05-22 13:58:53 -0700329 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700330
Alex Crichton62a0a592017-05-22 13:58:53 -0700331 /// A catch expression.
332 ///
333 /// E.g. `do catch { block }`
334 pub Catch(ExprCatch {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700335 pub do_token: tokens::Do,
336 pub catch_token: tokens::Catch,
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 pub block: Block,
338 }),
339 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700340}
341
Alex Crichton62a0a592017-05-22 13:58:53 -0700342ast_struct! {
343 /// A field-value pair in a struct literal.
344 pub struct FieldValue {
345 /// Name of the field.
346 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500347
Alex Crichton62a0a592017-05-22 13:58:53 -0700348 /// Value of the field.
349 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500350
Alex Crichton62a0a592017-05-22 13:58:53 -0700351 /// Whether this is a shorthand field, e.g. `Struct { x }`
352 /// instead of `Struct { x: x }`.
353 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500354
Alex Crichton62a0a592017-05-22 13:58:53 -0700355 /// Attributes tagged on the field.
356 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700357
358 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700359 }
David Tolnay055a7042016-10-02 19:23:54 -0700360}
361
Alex Crichton62a0a592017-05-22 13:58:53 -0700362ast_struct! {
363 /// A Block (`{ .. }`).
364 ///
365 /// E.g. `{ .. }` as in `fn foo() { .. }`
366 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700367 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700368 /// Statements in a block
369 pub stmts: Vec<Stmt>,
370 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700371}
372
Alex Crichton62a0a592017-05-22 13:58:53 -0700373ast_enum! {
374 /// A statement, usually ending in a semicolon.
375 pub enum Stmt {
376 /// A local (let) binding.
377 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700378
Alex Crichton62a0a592017-05-22 13:58:53 -0700379 /// An item definition.
380 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700381
Alex Crichton62a0a592017-05-22 13:58:53 -0700382 /// Expr without trailing semicolon.
383 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700384
Alex Crichton62a0a592017-05-22 13:58:53 -0700385 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700386 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700387
Alex Crichton62a0a592017-05-22 13:58:53 -0700388 /// Macro invocation.
389 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
390 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391}
392
Alex Crichton62a0a592017-05-22 13:58:53 -0700393ast_enum! {
394 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700395 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700396 pub enum MacStmtStyle {
397 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
398 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700399 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500400
Alex Crichton62a0a592017-05-22 13:58:53 -0700401 /// The macro statement had braces; e.g. foo! { ... }
402 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500403
Alex Crichton62a0a592017-05-22 13:58:53 -0700404 /// The macro statement had parentheses or brackets and no semicolon; e.g.
405 /// `foo!(...)`. All of these will end up being converted into macro
406 /// expressions.
407 NoBraces,
408 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700409}
410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411ast_struct! {
412 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
413 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700414 pub let_token: tokens::Let,
415 pub colon_token: Option<tokens::Colon>,
416 pub eq_token: Option<tokens::Eq>,
417 pub semi_token: tokens::Semi,
418
Alex Crichton62a0a592017-05-22 13:58:53 -0700419 pub pat: Box<Pat>,
420 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500421
Alex Crichton62a0a592017-05-22 13:58:53 -0700422 /// Initializer expression to set the value, if any
423 pub init: Option<Box<Expr>>,
424 pub attrs: Vec<Attribute>,
425 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700426}
427
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700428ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700429 // Clippy false positive
430 // https://github.com/Manishearth/rust-clippy/issues/1241
431 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
432 pub enum Pat {
433 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700434 pub Wild(PatWild {
435 pub underscore_token: tokens::Underscore,
436 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700437
Alex Crichton62a0a592017-05-22 13:58:53 -0700438 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
439 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
440 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
441 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700442 pub Ident(PatIdent {
443 pub mode: BindingMode,
444 pub ident: Ident,
445 pub subpat: Option<Box<Pat>>,
446 pub at_token: Option<tokens::At>,
447 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700448
Alex Crichton62a0a592017-05-22 13:58:53 -0700449 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
450 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700451 pub Struct(PatStruct {
452 pub path: Path,
453 pub fields: Delimited<FieldPat, tokens::Comma>,
454 pub brace_token: tokens::Brace,
455 pub dot2_token: Option<tokens::Dot2>,
456 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700457
Alex Crichton62a0a592017-05-22 13:58:53 -0700458 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
459 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
460 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700461 pub TupleStruct(PatTupleStruct {
462 pub path: Path,
463 pub pat: PatTuple,
464 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700465
Alex Crichton62a0a592017-05-22 13:58:53 -0700466 /// A possibly qualified path pattern.
467 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
468 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
469 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700470 pub Path(PatPath {
471 pub qself: Option<QSelf>,
472 pub path: Path,
473 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700474
Alex Crichton62a0a592017-05-22 13:58:53 -0700475 /// A tuple pattern `(a, b)`.
476 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
477 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700478 pub Tuple(PatTuple {
479 pub pats: Delimited<Pat, tokens::Comma>,
480 pub dots_pos: Option<usize>,
481 pub paren_token: tokens::Paren,
482 pub dot2_token: Option<tokens::Dot2>,
483 pub comma_token: Option<tokens::Comma>,
484 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700485 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700486 pub Box(PatBox {
487 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700488 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700489 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700491 pub Ref(PatRef {
492 pub pat: Box<Pat>,
493 pub mutbl: Mutability,
494 pub and_token: tokens::And,
495 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700496 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700497 pub Lit(PatLit {
498 pub expr: Box<Expr>,
499 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700500 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700501 pub Range(PatRange {
502 pub lo: Box<Expr>,
503 pub hi: Box<Expr>,
504 pub limits: RangeLimits,
505 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700506 /// `[a, b, ..i, y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700507 pub Slice(PatSlice {
508 pub front: Delimited<Pat, tokens::Comma>,
509 pub middle: Option<Box<Pat>>,
510 pub back: Delimited<Pat, tokens::Comma>,
511 pub dot2_token: Option<tokens::Dot2>,
512 pub comma_token: Option<tokens::Comma>,
513 pub bracket_token: tokens::Bracket,
514 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700515 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700516 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700517 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700518}
519
Alex Crichton62a0a592017-05-22 13:58:53 -0700520ast_struct! {
521 /// An arm of a 'match'.
522 ///
523 /// E.g. `0...10 => { println!("match!") }` as in
524 ///
525 /// ```rust,ignore
526 /// match n {
527 /// 0...10 => { println!("match!") },
528 /// // ..
529 /// }
530 /// ```
531 pub struct Arm {
532 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700533 pub pats: Delimited<Pat, tokens::Or>,
534 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700535 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700537 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700540}
541
Alex Crichton62a0a592017-05-22 13:58:53 -0700542ast_enum! {
543 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700544 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700545 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700547 Ref,
548 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700549}
550
Alex Crichton62a0a592017-05-22 13:58:53 -0700551ast_enum! {
552 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700553 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 pub enum RangeLimits {
555 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700557 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700559 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700560}
561
Alex Crichton62a0a592017-05-22 13:58:53 -0700562ast_struct! {
563 /// A single field in a struct pattern
564 ///
565 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
566 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
567 /// except `is_shorthand` is true
568 pub struct FieldPat {
569 /// The identifier for the field
570 pub ident: Ident,
571 /// The pattern the field is destructured to
572 pub pat: Box<Pat>,
573 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700574 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700575 pub attrs: Vec<Attribute>,
576 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700577}
578
Alex Crichton62a0a592017-05-22 13:58:53 -0700579ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700580 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700582 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700583 ByValue(Mutability),
584 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700585}
586
David Tolnayb9c8e322016-09-23 20:48:37 -0700587#[cfg(feature = "parsing")]
588pub mod parsing {
589 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700590 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700591
Michael Layzell92639a52017-06-01 00:07:44 -0400592 use proc_macro2::{TokenStream, TokenKind, Delimiter};
593 use synom::{PResult, Cursor, Synom, parse_error};
Alex Crichton954046c2017-05-30 21:49:42 -0700594 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700595
David Tolnayaf2557e2016-10-24 11:52:21 -0700596 // Struct literals are ambiguous in certain positions
597 // https://github.com/rust-lang/rfcs/pull/92
598 macro_rules! named_ambiguous_expr {
599 ($name:ident -> $o:ty, $allow_struct:ident, $submac:ident!( $($args:tt)* )) => {
Michael Layzell92639a52017-06-01 00:07:44 -0400600 fn $name(i: $crate::synom::Cursor, $allow_struct: bool)
601 -> $crate::synom::PResult<$o> {
David Tolnayaf2557e2016-10-24 11:52:21 -0700602 $submac!(i, $($args)*)
603 }
604 };
605 }
606
607 macro_rules! ambiguous_expr {
608 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700609 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700610 };
611 }
612
Alex Crichton954046c2017-05-30 21:49:42 -0700613 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400614 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700615
616 fn description() -> Option<&'static str> {
617 Some("expression")
618 }
619 }
620
David Tolnayaf2557e2016-10-24 11:52:21 -0700621
622 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
623
David Tolnay02a8d472017-02-19 12:59:44 -0800624 #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
Michael Layzell92639a52017-06-01 00:07:44 -0400625 fn ambiguous_expr(i: Cursor,
Michael Layzell416724e2017-05-24 21:12:34 -0400626 allow_struct: bool,
627 allow_block: bool)
Michael Layzell92639a52017-06-01 00:07:44 -0400628 -> PResult<Expr> {
Alex Crichton954046c2017-05-30 21:49:42 -0700629 do_parse! {
David Tolnay54e854d2016-10-24 12:03:30 -0700630 i,
631 mut e: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700632 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
David Tolnay54e854d2016-10-24 12:03:30 -0700633 |
Alex Crichton954046c2017-05-30 21:49:42 -0700634 // must be before expr_path
635 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
David Tolnay54e854d2016-10-24 12:03:30 -0700636 |
Alex Crichton954046c2017-05-30 21:49:42 -0700637 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
David Tolnay54e854d2016-10-24 12:03:30 -0700638 |
Alex Crichton954046c2017-05-30 21:49:42 -0700639 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
David Tolnay54e854d2016-10-24 12:03:30 -0700640 |
David Tolnay5d55ef72016-12-21 20:20:04 -0500641 call!(expr_break, allow_struct) // must be before expr_path
David Tolnay54e854d2016-10-24 12:03:30 -0700642 |
Alex Crichton954046c2017-05-30 21:49:42 -0700643 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
David Tolnay54e854d2016-10-24 12:03:30 -0700644 |
645 call!(expr_ret, allow_struct) // must be before expr_path
646 |
647 call!(expr_box, allow_struct)
648 |
Alex Crichton954046c2017-05-30 21:49:42 -0700649 syn!(ExprInPlace) => { ExprKind::InPlace }
David Tolnay6696c3e2016-10-30 11:45:10 -0700650 |
Alex Crichton954046c2017-05-30 21:49:42 -0700651 syn!(ExprArray) => { ExprKind::Array }
David Tolnay54e854d2016-10-24 12:03:30 -0700652 |
Alex Crichton954046c2017-05-30 21:49:42 -0700653 syn!(ExprTup) => { ExprKind::Tup }
David Tolnay54e854d2016-10-24 12:03:30 -0700654 |
655 call!(expr_unary, allow_struct)
656 |
Alex Crichton954046c2017-05-30 21:49:42 -0700657 syn!(ExprIf) => { ExprKind::If }
David Tolnay54e854d2016-10-24 12:03:30 -0700658 |
Alex Crichton954046c2017-05-30 21:49:42 -0700659 syn!(ExprIfLet) => { ExprKind::IfLet }
David Tolnay54e854d2016-10-24 12:03:30 -0700660 |
Alex Crichton954046c2017-05-30 21:49:42 -0700661 syn!(ExprWhile) => { ExprKind::While }
David Tolnay54e854d2016-10-24 12:03:30 -0700662 |
Alex Crichton954046c2017-05-30 21:49:42 -0700663 syn!(ExprWhileLet) => { ExprKind::WhileLet }
David Tolnay54e854d2016-10-24 12:03:30 -0700664 |
Alex Crichton954046c2017-05-30 21:49:42 -0700665 syn!(ExprForLoop) => { ExprKind::ForLoop }
David Tolnay54e854d2016-10-24 12:03:30 -0700666 |
Alex Crichton954046c2017-05-30 21:49:42 -0700667 syn!(ExprLoop) => { ExprKind::Loop }
668 |
669 syn!(ExprMatch) => { ExprKind::Match }
670 |
671 syn!(ExprCatch) => { ExprKind::Catch }
Arnavion02ef13f2017-04-25 00:54:31 -0700672 |
David Tolnay54e854d2016-10-24 12:03:30 -0700673 call!(expr_closure, allow_struct)
674 |
Alex Crichton954046c2017-05-30 21:49:42 -0700675 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
David Tolnay54e854d2016-10-24 12:03:30 -0700676 |
677 call!(expr_range, allow_struct)
678 |
Alex Crichton954046c2017-05-30 21:49:42 -0700679 syn!(ExprPath) => { ExprKind::Path }
David Tolnay54e854d2016-10-24 12:03:30 -0700680 |
681 call!(expr_addr_of, allow_struct)
682 |
Alex Crichton954046c2017-05-30 21:49:42 -0700683 syn!(ExprRepeat) => { ExprKind::Repeat }
David Tolnay54e854d2016-10-24 12:03:30 -0700684 ) >>
685 many0!(alt!(
686 tap!(args: and_call => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700687 let (args, paren) = args;
Alex Crichton62a0a592017-05-22 13:58:53 -0700688 e = ExprCall {
689 func: Box::new(e.into()),
690 args: args,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700691 paren_token: paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700692 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700693 })
694 |
695 tap!(more: and_method_call => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700696 let mut call = more;
697 call.expr = Box::new(e.into());
698 e = call.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700699 })
700 |
701 tap!(more: call!(and_binary, allow_struct) => {
702 let (op, other) = more;
Alex Crichton62a0a592017-05-22 13:58:53 -0700703 e = ExprBinary {
704 op: op,
705 left: Box::new(e.into()),
706 right: Box::new(other),
707 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700708 })
709 |
710 tap!(ty: and_cast => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700711 let (ty, token) = ty;
Alex Crichton62a0a592017-05-22 13:58:53 -0700712 e = ExprCast {
713 expr: Box::new(e.into()),
714 ty: Box::new(ty),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700715 as_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700716 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700717 })
718 |
719 tap!(ty: and_ascription => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700720 let (ty, token) = ty;
Alex Crichton62a0a592017-05-22 13:58:53 -0700721 e = ExprType {
722 expr: Box::new(e.into()),
723 ty: Box::new(ty),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700724 colon_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700725 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700726 })
727 |
728 tap!(v: call!(and_assign, allow_struct) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700729 let (v, token) = v;
Alex Crichton62a0a592017-05-22 13:58:53 -0700730 e = ExprAssign {
731 left: Box::new(e.into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700732 eq_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700733 right: Box::new(v),
734 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700735 })
736 |
737 tap!(more: call!(and_assign_op, allow_struct) => {
738 let (op, v) = more;
Alex Crichton62a0a592017-05-22 13:58:53 -0700739 e = ExprAssignOp {
740 op: op,
741 left: Box::new(e.into()),
742 right: Box::new(v),
743 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700744 })
745 |
746 tap!(field: and_field => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700747 let (field, token) = field;
Alex Crichton62a0a592017-05-22 13:58:53 -0700748 e = ExprField {
749 expr: Box::new(e.into()),
750 field: field,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700751 dot_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700752 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700753 })
754 |
755 tap!(field: and_tup_field => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700756 let (field, token) = field;
Alex Crichton62a0a592017-05-22 13:58:53 -0700757 e = ExprTupField {
758 expr: Box::new(e.into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700759 field: field,
760 dot_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700761 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700762 })
763 |
764 tap!(i: and_index => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700765 let (i, token) = i;
Alex Crichton62a0a592017-05-22 13:58:53 -0700766 e = ExprIndex {
767 expr: Box::new(e.into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700768 bracket_token: token,
Alex Crichton62a0a592017-05-22 13:58:53 -0700769 index: Box::new(i),
770 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700771 })
772 |
773 tap!(more: call!(and_range, allow_struct) => {
774 let (limits, hi) = more;
Alex Crichton62a0a592017-05-22 13:58:53 -0700775 e = ExprRange {
776 from: Some(Box::new(e.into())),
777 to: hi.map(Box::new),
778 limits: limits,
779 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700780 })
781 |
Alex Crichton954046c2017-05-30 21:49:42 -0700782 tap!(question: syn!(Question) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700783 e = ExprTry {
784 expr: Box::new(e.into()),
Alex Crichton954046c2017-05-30 21:49:42 -0700785 question_token: question,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700786 }.into();
David Tolnay54e854d2016-10-24 12:03:30 -0700787 })
788 )) >>
David Tolnay7184b132016-10-30 10:06:37 -0700789 (e.into())
Alex Crichton954046c2017-05-30 21:49:42 -0700790 }
David Tolnay54e854d2016-10-24 12:03:30 -0700791 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700792
Alex Crichton954046c2017-05-30 21:49:42 -0700793 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -0400794 named!(parse -> Self, do_parse!(
795 e: parens!(syn!(Expr)) >>
796 (ExprParen {
797 expr: Box::new(e.0),
798 paren_token: e.1,
799 }.into())
800 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700801 }
David Tolnay89e05672016-10-02 14:39:42 -0700802
David Tolnay7184b132016-10-30 10:06:37 -0700803 named_ambiguous_expr!(expr_box -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700804 box_: syn!(Box_) >>
David Tolnayaf2557e2016-10-24 11:52:21 -0700805 inner: ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700806 (ExprBox {
807 expr: Box::new(inner),
Alex Crichton954046c2017-05-30 21:49:42 -0700808 box_token: box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700809 }.into())
David Tolnayb9c8e322016-09-23 20:48:37 -0700810 ));
David Tolnayfa0edf22016-09-23 22:58:24 -0700811
Alex Crichton954046c2017-05-30 21:49:42 -0700812 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -0400813 named!(parse -> Self, do_parse!(
814 in_: syn!(In) >>
815 place: expr_no_struct >>
816 value: braces!(call!(Block::parse_within)) >>
817 (ExprInPlace {
818 in_token: in_,
819 place: Box::new(place),
820 value: Box::new(Expr {
821 node: ExprBlock {
822 unsafety: Unsafety::Normal,
823 block: Block {
824 stmts: value.0,
825 brace_token: value.1,
826 },
827 }.into(),
828 attrs: Vec::new(),
829 }),
830 })
831 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700832 }
David Tolnay6696c3e2016-10-30 11:45:10 -0700833
Alex Crichton954046c2017-05-30 21:49:42 -0700834 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -0400835 named!(parse -> Self, do_parse!(
836 elems: brackets!(call!(Delimited::parse_terminated)) >>
837 (ExprArray {
838 exprs: elems.0,
839 bracket_token: elems.1,
840 })
841 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700842 }
David Tolnayfa0edf22016-09-23 22:58:24 -0700843
Alex Crichton954046c2017-05-30 21:49:42 -0700844 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
845 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -0700846
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700847 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700848 dot: syn!(Dot) >>
849 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700850 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700851 colon2: syn!(Colon2) >>
852 lt: syn!(Lt) >>
853 tys: call!(Delimited::parse_terminated) >>
854 gt: syn!(Gt) >>
855 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -0700856 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700857 args: parens!(call!(Delimited::parse_terminated)) >>
858 ({
859 let (colon2, lt, tys, gt) = match typarams {
860 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
861 None => (None, None, None, None),
862 };
863 ExprMethodCall {
864 // this expr will get overwritten after being returned
865 expr: Box::new(ExprKind::Lit(Lit {
866 span: Span::default(),
867 value: LitKind::Bool(false),
868 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700869
Alex Crichton954046c2017-05-30 21:49:42 -0700870 method: method,
871 args: args.0,
872 paren_token: args.1,
873 dot_token: dot,
874 lt_token: lt,
875 gt_token: gt,
876 colon2_token: colon2,
877 typarams: tys.unwrap_or_default(),
878 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700879 })
David Tolnayfa0edf22016-09-23 22:58:24 -0700880 ));
881
Alex Crichton954046c2017-05-30 21:49:42 -0700882 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -0400883 named!(parse -> Self, do_parse!(
884 elems: parens!(call!(Delimited::parse_terminated)) >>
885 (ExprTup {
886 args: elems.0,
887 paren_token: elems.1,
888 lone_comma: None, // TODO: parse this
889 })
890 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700891 }
David Tolnayfa0edf22016-09-23 22:58:24 -0700892
David Tolnayaf2557e2016-10-24 11:52:21 -0700893 named_ambiguous_expr!(and_binary -> (BinOp, Expr), allow_struct, tuple!(
Alex Crichton954046c2017-05-30 21:49:42 -0700894 call!(BinOp::parse_binop),
David Tolnayaf2557e2016-10-24 11:52:21 -0700895 ambiguous_expr!(allow_struct)
896 ));
David Tolnayfa0edf22016-09-23 22:58:24 -0700897
David Tolnay7184b132016-10-30 10:06:37 -0700898 named_ambiguous_expr!(expr_unary -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -0700899 operator: syn!(UnOp) >>
David Tolnayaf2557e2016-10-24 11:52:21 -0700900 operand: ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -0700901 (ExprUnary { op: operator, expr: Box::new(operand) }.into())
David Tolnayfa0edf22016-09-23 22:58:24 -0700902 ));
David Tolnay939766a2016-09-23 23:48:12 -0700903
Alex Crichton954046c2017-05-30 21:49:42 -0700904 named!(and_cast -> (Ty, As), do_parse!(
905 as_: syn!(As) >>
906 ty: syn!(Ty) >>
907 (ty, as_)
David Tolnay939766a2016-09-23 23:48:12 -0700908 ));
909
Alex Crichton954046c2017-05-30 21:49:42 -0700910 named!(and_ascription -> (Ty, Colon),
911 map!(tuple!(syn!(Colon), syn!(Ty)), |(a, b)| (b, a)));
David Tolnay939766a2016-09-23 23:48:12 -0700912
Alex Crichton954046c2017-05-30 21:49:42 -0700913 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -0400914 named!(parse -> Self, do_parse!(
915 if_: syn!(If) >>
916 let_: syn!(Let) >>
917 pat: syn!(Pat) >>
918 eq: syn!(Eq) >>
919 cond: expr_no_struct >>
920 then_block: braces!(call!(Block::parse_within)) >>
921 else_block: option!(else_block) >>
922 (ExprIfLet {
923 pat: Box::new(pat),
924 let_token: let_,
925 eq_token: eq,
926 expr: Box::new(cond),
927 if_true: Block {
928 stmts: then_block.0,
929 brace_token: then_block.1,
930 },
931 if_token: if_,
932 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
933 if_false: else_block.map(|p| Box::new(p.1.into())),
934 })
935 ));
David Tolnay29f9ce12016-10-02 20:58:40 -0700936 }
937
Alex Crichton954046c2017-05-30 21:49:42 -0700938 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -0400939 named!(parse -> Self, do_parse!(
940 if_: syn!(If) >>
941 cond: expr_no_struct >>
942 then_block: braces!(call!(Block::parse_within)) >>
943 else_block: option!(else_block) >>
944 (ExprIf {
945 cond: Box::new(cond),
946 if_true: Block {
947 stmts: then_block.0,
948 brace_token: then_block.1,
949 },
950 if_token: if_,
951 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
952 if_false: else_block.map(|p| Box::new(p.1.into())),
953 })
954 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700955 }
David Tolnaybb6feae2016-10-02 21:25:20 -0700956
Alex Crichton954046c2017-05-30 21:49:42 -0700957 named!(else_block -> (Else, ExprKind), do_parse!(
958 else_: syn!(Else) >>
959 expr: alt!(
960 syn!(ExprIf) => { ExprKind::If }
961 |
962 syn!(ExprIfLet) => { ExprKind::IfLet }
963 |
964 do_parse!(
965 else_block: braces!(call!(Block::parse_within)) >>
966 (ExprKind::Block(ExprBlock {
967 unsafety: Unsafety::Normal,
968 block: Block {
969 stmts: else_block.0,
970 brace_token: else_block.1,
971 },
972 }))
David Tolnay939766a2016-09-23 23:48:12 -0700973 )
Alex Crichton954046c2017-05-30 21:49:42 -0700974 ) >>
975 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -0700976 ));
977
David Tolnaybb6feae2016-10-02 21:25:20 -0700978
Alex Crichton954046c2017-05-30 21:49:42 -0700979 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -0400980 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -0700981 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400982 for_: syn!(For) >>
983 pat: syn!(Pat) >>
984 in_: syn!(In) >>
985 expr: expr_no_struct >>
986 loop_block: syn!(Block) >>
987 (ExprForLoop {
988 for_token: for_,
989 in_token: in_,
990 pat: Box::new(pat),
991 expr: Box::new(expr),
992 body: loop_block,
993 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
994 label: lbl.map(|p| p.0),
995 })
996 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700997 }
Gregory Katze5f35682016-09-27 14:20:55 -0400998
Alex Crichton954046c2017-05-30 21:49:42 -0700999 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001000 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001001 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001002 loop_: syn!(Loop) >>
1003 loop_block: syn!(Block) >>
1004 (ExprLoop {
1005 loop_token: loop_,
1006 body: loop_block,
1007 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1008 label: lbl.map(|p| p.0),
1009 })
1010 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001011 }
1012
1013 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001014 named!(parse -> Self, do_parse!(
1015 match_: syn!(Match) >>
1016 obj: expr_no_struct >>
1017 res: braces!(do_parse!(
1018 mut arms: many0!(do_parse!(
1019 arm: syn!(Arm) >>
1020 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1021 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1022 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001023 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001024 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001025 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001026 arms.extend(last_arm);
1027 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001028 })
Michael Layzell92639a52017-06-01 00:07:44 -04001029 )) >>
1030 ({
1031 let (mut arms, brace) = res;
1032 ExprMatch {
1033 expr: Box::new(obj),
1034 match_token: match_,
1035 brace_token: brace,
1036 arms: {
1037 for arm in &mut arms {
1038 if arm_requires_comma(arm) {
1039 arm.comma = Some(tokens::Comma::default());
1040 }
1041 }
1042 arms
1043 },
1044 }
1045 })
1046 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001047 }
David Tolnay1978c672016-10-27 22:05:52 -07001048
Alex Crichton954046c2017-05-30 21:49:42 -07001049 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001050 named!(parse -> Self, do_parse!(
1051 do_: syn!(Do) >>
1052 catch_: syn!(Catch) >>
1053 catch_block: syn!(Block) >>
1054 (ExprCatch {
1055 block: catch_block,
1056 do_token: do_,
1057 catch_token: catch_,
1058 }.into())
1059 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001060 }
Arnavion02ef13f2017-04-25 00:54:31 -07001061
David Tolnay1978c672016-10-27 22:05:52 -07001062 fn arm_requires_comma(arm: &Arm) -> bool {
Alex Crichton62a0a592017-05-22 13:58:53 -07001063 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
David Tolnay1978c672016-10-27 22:05:52 -07001064 false
1065 } else {
1066 true
1067 }
1068 }
1069
Alex Crichton954046c2017-05-30 21:49:42 -07001070 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001071 named!(parse -> Self, do_parse!(
1072 attrs: many0!(call!(Attribute::parse_outer)) >>
1073 pats: call!(Delimited::parse_separated_nonempty) >>
1074 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1075 rocket: syn!(Rocket) >>
1076 body: alt!(
1077 map!(syn!(Block), |blk| {
1078 ExprKind::Block(ExprBlock {
1079 unsafety: Unsafety::Normal,
1080 block: blk,
1081 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001082 })
Michael Layzell92639a52017-06-01 00:07:44 -04001083 |
1084 syn!(Expr)
1085 ) >>
1086 (Arm {
1087 rocket_token: rocket,
1088 if_token: guard.as_ref().map(|p| If((p.0).0)),
1089 attrs: attrs,
1090 pats: pats,
1091 guard: guard.map(|p| Box::new(p.1)),
1092 body: Box::new(body),
1093 comma: None,
1094 })
1095 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001096 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001097
David Tolnay7184b132016-10-30 10:06:37 -07001098 named_ambiguous_expr!(expr_closure -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001099 capture: syn!(CaptureBy) >>
1100 or1: syn!(Or) >>
1101 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1102 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001103 ret_and_body: alt!(
1104 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001105 arrow: syn!(RArrow) >>
1106 ty: syn!(Ty) >>
1107 body: syn!(Block) >>
1108 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001109 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001110 unsafety: Unsafety::Normal,
1111 block: body,
1112 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001113 )
1114 |
David Tolnay58af3552016-12-22 16:58:07 -05001115 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001116 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001117 (ExprClosure {
1118 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001119 or1_token: or1,
1120 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001121 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001122 inputs: inputs,
1123 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001124 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001125 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001126 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001127 generics: Generics::default(),
1128 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001129 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001130 body: Box::new(ret_and_body.1),
1131 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001132 ));
1133
Alex Crichton954046c2017-05-30 21:49:42 -07001134 named!(fn_arg -> FnArg, do_parse!(
1135 pat: syn!(Pat) >>
1136 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1137 ({
1138 let (colon, ty) = ty.unwrap_or_else(|| {
1139 (Colon::default(), TyInfer {
1140 underscore_token: Underscore::default(),
1141 }.into())
1142 });
1143 ArgCaptured {
1144 pat: pat,
1145 colon_token: colon,
1146 ty: ty,
1147 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001148 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001149 ));
1150
Alex Crichton954046c2017-05-30 21:49:42 -07001151 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001152 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001153 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001154 while_: syn!(While) >>
1155 cond: expr_no_struct >>
1156 while_block: syn!(Block) >>
1157 (ExprWhile {
1158 while_token: while_,
1159 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1160 cond: Box::new(cond),
1161 body: while_block,
1162 label: lbl.map(|p| p.0),
1163 })
1164 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001165 }
1166
1167 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001168 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001169 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001170 while_: syn!(While) >>
1171 let_: syn!(Let) >>
1172 pat: syn!(Pat) >>
1173 eq: syn!(Eq) >>
1174 value: expr_no_struct >>
1175 while_block: syn!(Block) >>
1176 (ExprWhileLet {
1177 eq_token: eq,
1178 let_token: let_,
1179 while_token: while_,
1180 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1181 pat: Box::new(pat),
1182 expr: Box::new(value),
1183 body: while_block,
1184 label: lbl.map(|p| p.0),
1185 })
1186 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001187 }
1188
1189 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001190 named!(parse -> Self, do_parse!(
1191 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001192 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001193 (ExprContinue {
1194 continue_token: cont,
1195 label: lbl,
1196 })
1197 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001198 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001199
David Tolnay5d55ef72016-12-21 20:20:04 -05001200 named_ambiguous_expr!(expr_break -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001201 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001202 lbl: option!(syn!(Lifetime)) >>
David Tolnay5d55ef72016-12-21 20:20:04 -05001203 val: option!(call!(ambiguous_expr, allow_struct, false)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001204 (ExprBreak {
1205 label: lbl,
1206 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001207 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001208 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001209 ));
1210
David Tolnay7184b132016-10-30 10:06:37 -07001211 named_ambiguous_expr!(expr_ret -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001212 return_: syn!(Return) >>
David Tolnayaf2557e2016-10-24 11:52:21 -07001213 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001214 (ExprRet {
1215 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001216 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001217 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001218 ));
1219
Alex Crichton954046c2017-05-30 21:49:42 -07001220 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001221 named!(parse -> Self, do_parse!(
1222 path: syn!(Path) >>
1223 data: braces!(do_parse!(
1224 fields: call!(Delimited::parse_terminated) >>
1225 base: option!(
1226 cond!(fields.is_empty() || fields.trailing_delim(),
1227 do_parse!(
1228 dots: syn!(Dot2) >>
1229 base: syn!(Expr) >>
1230 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001231 )
Michael Layzell92639a52017-06-01 00:07:44 -04001232 )
1233 ) >>
1234 (fields, base)
1235 )) >>
1236 ({
1237 let ((fields, base), brace) = data;
1238 let (dots, rest) = match base.and_then(|b| b) {
1239 Some((dots, base)) => (Some(dots), Some(base)),
1240 None => (None, None),
1241 };
1242 ExprStruct {
1243 brace_token: brace,
1244 path: path,
1245 fields: fields,
1246 dot2_token: dots,
1247 rest: rest.map(Box::new),
1248 }
1249 })
1250 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001251 }
1252
1253 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001254 named!(parse -> Self, alt!(
1255 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001256 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001257 colon: syn!(Colon) >>
1258 value: syn!(Expr) >>
1259 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001260 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001261 expr: value,
1262 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001263 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001264 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001265 })
Michael Layzell92639a52017-06-01 00:07:44 -04001266 )
1267 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001268 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001269 ident: name.clone(),
1270 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1271 is_shorthand: true,
1272 attrs: Vec::new(),
1273 colon_token: None,
1274 })
1275 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001276 }
David Tolnay055a7042016-10-02 19:23:54 -07001277
Alex Crichton954046c2017-05-30 21:49:42 -07001278 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001279 named!(parse -> Self, do_parse!(
1280 data: brackets!(do_parse!(
1281 value: syn!(Expr) >>
1282 semi: syn!(Semi) >>
1283 times: syn!(Expr) >>
1284 (value, semi, times)
1285 )) >>
1286 (ExprRepeat {
1287 expr: Box::new((data.0).0),
1288 amt: Box::new((data.0).2),
1289 bracket_token: data.1,
1290 semi_token: (data.0).1,
1291 })
1292 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001293 }
David Tolnay055a7042016-10-02 19:23:54 -07001294
Alex Crichton954046c2017-05-30 21:49:42 -07001295 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001296 named!(parse -> Self, do_parse!(
1297 rules: syn!(Unsafety) >>
1298 b: syn!(Block) >>
1299 (ExprBlock {
1300 unsafety: rules,
1301 block: b,
1302 })
1303 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001304 }
David Tolnay89e05672016-10-02 14:39:42 -07001305
David Tolnay7184b132016-10-30 10:06:37 -07001306 named_ambiguous_expr!(expr_range -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001307 limits: syn!(RangeLimits) >>
David Tolnayaf2557e2016-10-24 11:52:21 -07001308 hi: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001309 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001310 ));
1311
Alex Crichton954046c2017-05-30 21:49:42 -07001312 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001313 named!(parse -> Self, alt!(
1314 // Must come before Dot2
1315 syn!(Dot3) => { RangeLimits::Closed }
1316 |
1317 syn!(Dot2) => { RangeLimits::HalfOpen }
1318 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001319 }
David Tolnay438c9052016-10-07 23:24:48 -07001320
Alex Crichton954046c2017-05-30 21:49:42 -07001321 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001322 named!(parse -> Self, do_parse!(
1323 pair: qpath >>
1324 (ExprPath {
1325 qself: pair.0,
1326 path: pair.1,
1327 })
1328 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001329 }
David Tolnay42602292016-10-01 22:25:45 -07001330
David Tolnay7184b132016-10-30 10:06:37 -07001331 named_ambiguous_expr!(expr_addr_of -> ExprKind, allow_struct, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001332 and: syn!(And) >>
1333 mutability: syn!(Mutability) >>
David Tolnayaf2557e2016-10-24 11:52:21 -07001334 expr: ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001335 (ExprAddrOf {
1336 mutbl: mutability,
1337 expr: Box::new(expr),
Alex Crichton954046c2017-05-30 21:49:42 -07001338 and_token: and,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001339 }.into())
David Tolnay3c2467c2016-10-02 17:55:08 -07001340 ));
1341
Alex Crichton954046c2017-05-30 21:49:42 -07001342 named_ambiguous_expr!(and_assign -> (Expr, Eq), allow_struct,
1343 map!(
1344 tuple!(syn!(Eq), ambiguous_expr!(allow_struct)),
1345 |(a, b)| (b, a)
1346 )
1347 );
David Tolnay438c9052016-10-07 23:24:48 -07001348
David Tolnayaf2557e2016-10-24 11:52:21 -07001349 named_ambiguous_expr!(and_assign_op -> (BinOp, Expr), allow_struct, tuple!(
Alex Crichton954046c2017-05-30 21:49:42 -07001350 call!(BinOp::parse_assign_op),
David Tolnayaf2557e2016-10-24 11:52:21 -07001351 ambiguous_expr!(allow_struct)
1352 ));
David Tolnay438c9052016-10-07 23:24:48 -07001353
Alex Crichton954046c2017-05-30 21:49:42 -07001354 named!(and_field -> (Ident, Dot),
1355 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001356
Alex Crichton954046c2017-05-30 21:49:42 -07001357 named!(and_tup_field -> (Lit, Dot),
1358 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001359
Alex Crichton954046c2017-05-30 21:49:42 -07001360 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001361
David Tolnayaf2557e2016-10-24 11:52:21 -07001362 named_ambiguous_expr!(and_range -> (RangeLimits, Option<Expr>), allow_struct, tuple!(
Alex Crichton954046c2017-05-30 21:49:42 -07001363 syn!(RangeLimits),
David Tolnay54e854d2016-10-24 12:03:30 -07001364 option!(call!(ambiguous_expr, allow_struct, false))
David Tolnayaf2557e2016-10-24 11:52:21 -07001365 ));
David Tolnay438c9052016-10-07 23:24:48 -07001366
Alex Crichton954046c2017-05-30 21:49:42 -07001367 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001368 named!(parse -> Self, do_parse!(
1369 stmts: braces!(call!(Block::parse_within)) >>
1370 (Block {
1371 stmts: stmts.0,
1372 brace_token: stmts.1,
1373 })
1374 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001375 }
David Tolnay939766a2016-09-23 23:48:12 -07001376
Alex Crichton954046c2017-05-30 21:49:42 -07001377 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001378 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1379 many0!(syn!(Semi)) >>
1380 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1381 last: option!(syn!(Expr)) >>
1382 (match last {
1383 None => standalone,
1384 Some(last) => {
1385 standalone.push(Stmt::Expr(Box::new(last)));
1386 standalone
1387 }
1388 })
1389 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001390 }
1391
1392 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001393 named!(parse -> Self, alt!(
1394 stmt_mac
1395 |
1396 stmt_local
1397 |
1398 stmt_item
1399 |
1400 stmt_expr
1401 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001402 }
David Tolnay939766a2016-09-23 23:48:12 -07001403
David Tolnay13b3d352016-10-03 00:31:15 -07001404 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001405 attrs: many0!(call!(Attribute::parse_outer)) >>
1406 what: syn!(Path) >>
1407 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001408 // Only parse braces here; paren and bracket will get parsed as
1409 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001410 data: braces!(syn!(TokenStream)) >>
1411 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001412 (Stmt::Mac(Box::new((
1413 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001414 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001415 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001416 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001417 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001418 span: ((data.1).0).0,
1419 kind: TokenKind::Sequence(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001420 })],
1421 },
Alex Crichton954046c2017-05-30 21:49:42 -07001422 match semi {
1423 Some(semi) => MacStmtStyle::Semicolon(semi),
1424 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001425 },
David Tolnayeea28d62016-10-25 20:44:08 -07001426 attrs,
1427 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001428 ));
1429
David Tolnay191e0582016-10-02 18:31:09 -07001430 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001431 attrs: many0!(call!(Attribute::parse_outer)) >>
1432 let_: syn!(Let) >>
1433 pat: syn!(Pat) >>
1434 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1435 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1436 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001437 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001438 let_token: let_,
1439 semi_token: semi,
1440 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1441 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001442 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001443 ty: ty.map(|p| Box::new(p.1)),
1444 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001445 attrs: attrs,
1446 })))
1447 ));
1448
Alex Crichton954046c2017-05-30 21:49:42 -07001449 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001450
David Tolnaycfe55022016-10-02 22:02:27 -07001451 fn requires_semi(e: &Expr) -> bool {
David Tolnay7184b132016-10-30 10:06:37 -07001452 match e.node {
Alex Crichton62a0a592017-05-22 13:58:53 -07001453 ExprKind::If(_) |
1454 ExprKind::IfLet(_) |
1455 ExprKind::While(_) |
1456 ExprKind::WhileLet(_) |
1457 ExprKind::ForLoop(_) |
1458 ExprKind::Loop(_) |
1459 ExprKind::Match(_) |
1460 ExprKind::Block(_) => false,
David Tolnaycfe55022016-10-02 22:02:27 -07001461
1462 _ => true,
1463 }
1464 }
1465
1466 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001467 attrs: many0!(call!(Attribute::parse_outer)) >>
1468 mut e: syn!(Expr) >>
1469 semi: option!(syn!(Semi)) >>
David Tolnay7184b132016-10-30 10:06:37 -07001470 ({
1471 e.attrs = attrs;
Alex Crichton954046c2017-05-30 21:49:42 -07001472 if let Some(s) = semi {
1473 Stmt::Semi(Box::new(e), s)
David Tolnay092dcb02016-10-30 10:14:14 -07001474 } else if requires_semi(&e) {
Michael Layzell92639a52017-06-01 00:07:44 -04001475 return parse_error();
David Tolnay7184b132016-10-30 10:06:37 -07001476 } else {
1477 Stmt::Expr(Box::new(e))
1478 }
David Tolnaycfe55022016-10-02 22:02:27 -07001479 })
David Tolnay939766a2016-09-23 23:48:12 -07001480 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001481
Alex Crichton954046c2017-05-30 21:49:42 -07001482 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001483 named!(parse -> Self, alt!(
1484 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1485 |
1486 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1487 |
1488 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1489 |
1490 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1491 |
1492 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1493 |
1494 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1495 |
1496 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1497 |
1498 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1499 |
1500 syn!(PatPath) => { Pat::Path }
1501 |
1502 syn!(PatTuple) => { Pat::Tuple }
1503 |
1504 syn!(PatRef) => { Pat::Ref }
1505 |
1506 syn!(PatSlice) => { Pat::Slice }
1507 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001508 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001509
Alex Crichton954046c2017-05-30 21:49:42 -07001510 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001511 named!(parse -> Self, map!(
1512 syn!(Underscore),
1513 |u| PatWild { underscore_token: u }
1514 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001515 }
David Tolnay84aa0752016-10-02 23:01:13 -07001516
Alex Crichton954046c2017-05-30 21:49:42 -07001517 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001518 named!(parse -> Self, do_parse!(
1519 boxed: syn!(Box_) >>
1520 pat: syn!(Pat) >>
1521 (PatBox {
1522 pat: Box::new(pat),
1523 box_token: boxed,
1524 })
1525 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001526 }
1527
1528 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001529 named!(parse -> Self, do_parse!(
1530 mode: option!(syn!(Ref)) >>
1531 mutability: syn!(Mutability) >>
1532 name: alt!(
1533 syn!(Ident)
1534 |
1535 syn!(Self_) => { Into::into }
1536 ) >>
1537 not!(syn!(Lt)) >>
1538 not!(syn!(Colon2)) >>
1539 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1540 (PatIdent {
1541 mode: match mode {
1542 Some(mode) => BindingMode::ByRef(mode, mutability),
1543 None => BindingMode::ByValue(mutability),
1544 },
1545 ident: name,
1546 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1547 subpat: subpat.map(|p| Box::new(p.1)),
1548 })
1549 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001550 }
1551
1552 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001553 named!(parse -> Self, do_parse!(
1554 path: syn!(Path) >>
1555 tuple: syn!(PatTuple) >>
1556 (PatTupleStruct {
1557 path: path,
1558 pat: tuple,
1559 })
1560 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001561 }
1562
1563 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001564 named!(parse -> Self, do_parse!(
1565 path: syn!(Path) >>
1566 data: braces!(do_parse!(
1567 fields: call!(Delimited::parse_terminated) >>
1568 base: option!(
1569 cond!(fields.is_empty() || fields.trailing_delim(),
1570 syn!(Dot2))
1571 ) >>
1572 (fields, base)
1573 )) >>
1574 (PatStruct {
1575 path: path,
1576 fields: (data.0).0,
1577 brace_token: data.1,
1578 dot2_token: (data.0).1.and_then(|m| m),
1579 })
1580 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001581 }
1582
1583 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04001584 named!(parse -> Self, alt!(
1585 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001586 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001587 colon: syn!(Colon) >>
1588 pat: syn!(Pat) >>
1589 (FieldPat {
1590 ident: ident,
1591 pat: Box::new(pat),
1592 is_shorthand: false,
1593 attrs: Vec::new(),
1594 colon_token: Some(colon),
1595 })
1596 )
1597 |
1598 do_parse!(
1599 boxed: option!(syn!(Box_)) >>
1600 mode: option!(syn!(Ref)) >>
1601 mutability: syn!(Mutability) >>
1602 ident: syn!(Ident) >>
1603 ({
1604 let mut pat: Pat = PatIdent {
1605 mode: if let Some(mode) = mode {
1606 BindingMode::ByRef(mode, mutability)
1607 } else {
1608 BindingMode::ByValue(mutability)
1609 },
1610 ident: ident.clone(),
1611 subpat: None,
1612 at_token: None,
1613 }.into();
1614 if let Some(boxed) = boxed {
1615 pat = PatBox {
1616 pat: Box::new(pat),
1617 box_token: boxed,
1618 }.into();
1619 }
1620 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07001621 ident: ident,
1622 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04001623 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07001624 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001625 colon_token: None,
1626 }
1627 })
1628 )
1629 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001630 }
1631
David Tolnay570695e2017-06-03 16:15:13 -07001632 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07001633 syn!(Ident)
1634 |
1635 do_parse!(
1636 lit: syn!(Lit) >>
1637 ({
David Tolnay570695e2017-06-03 16:15:13 -07001638 let s = lit.to_string();
1639 if s.parse::<usize>().is_ok() {
Alex Crichton954046c2017-05-30 21:49:42 -07001640 Ident::new(s.into(), lit.span)
1641 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04001642 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07001643 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07001644 })
1645 )
1646 ));
1647
Alex Crichton954046c2017-05-30 21:49:42 -07001648 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001649 named!(parse -> Self, map!(
1650 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07001651 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04001652 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001653 }
David Tolnay9636c052016-10-02 17:11:17 -07001654
Alex Crichton954046c2017-05-30 21:49:42 -07001655 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001656 named!(parse -> Self, do_parse!(
1657 data: parens!(do_parse!(
1658 elems: call!(Delimited::parse_terminated) >>
1659 dotdot: map!(cond!(
1660 elems.is_empty() || elems.trailing_delim(),
1661 option!(do_parse!(
1662 dots: syn!(Dot2) >>
1663 trailing: option!(syn!(Comma)) >>
1664 (dots, trailing)
1665 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07001666 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001667 rest: cond!(match dotdot {
1668 Some((_, Some(_))) => true,
1669 _ => false,
1670 },
1671 call!(Delimited::parse_terminated)) >>
1672 (elems, dotdot, rest)
1673 )) >>
1674 ({
1675 let ((mut elems, dotdot, rest), parens) = data;
1676 let (dotdot, trailing) = match dotdot {
1677 Some((a, b)) => (Some(a), Some(b)),
1678 None => (None, None),
1679 };
1680 PatTuple {
1681 paren_token: parens,
1682 dots_pos: dotdot.as_ref().map(|_| elems.len()),
1683 dot2_token: dotdot,
1684 comma_token: trailing.and_then(|b| b),
1685 pats: {
1686 if let Some(rest) = rest {
1687 for elem in rest {
1688 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07001689 }
Michael Layzell92639a52017-06-01 00:07:44 -04001690 }
1691 elems
1692 },
1693 }
1694 })
1695 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001696 }
David Tolnayfbb73232016-10-03 01:00:06 -07001697
Alex Crichton954046c2017-05-30 21:49:42 -07001698 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04001699 named!(parse -> Self, do_parse!(
1700 and: syn!(And) >>
1701 mutability: syn!(Mutability) >>
1702 pat: syn!(Pat) >>
1703 (PatRef {
1704 pat: Box::new(pat),
1705 mutbl: mutability,
1706 and_token: and,
1707 })
1708 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001709 }
David Tolnayffdb97f2016-10-03 01:28:33 -07001710
Alex Crichton954046c2017-05-30 21:49:42 -07001711 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04001712 named!(parse -> Self, do_parse!(
1713 lit: pat_lit_expr >>
1714 (if let ExprKind::Path(_) = lit.node {
1715 return parse_error(); // these need to be parsed by pat_path
1716 } else {
1717 PatLit {
1718 expr: Box::new(lit),
1719 }
1720 })
1721 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001722 }
David Tolnaye1310902016-10-29 23:40:00 -07001723
Alex Crichton954046c2017-05-30 21:49:42 -07001724 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04001725 named!(parse -> Self, do_parse!(
1726 lo: pat_lit_expr >>
1727 limits: syn!(RangeLimits) >>
1728 hi: pat_lit_expr >>
1729 (PatRange {
1730 lo: Box::new(lo),
1731 hi: Box::new(hi),
1732 limits: limits,
1733 })
1734 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001735 }
David Tolnaye1310902016-10-29 23:40:00 -07001736
David Tolnay2cfddc62016-10-30 01:03:27 -07001737 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001738 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07001739 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07001740 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07001741 |
Alex Crichton954046c2017-05-30 21:49:42 -07001742 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07001743 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001744 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07001745 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001746 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07001747 expr: Box::new(v.into())
1748 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001749 } else {
David Tolnay7184b132016-10-30 10:06:37 -07001750 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001751 })
1752 ));
David Tolnay8b308c22016-10-03 01:24:10 -07001753
Alex Crichton954046c2017-05-30 21:49:42 -07001754 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04001755 named!(parse -> Self, map!(
1756 brackets!(do_parse!(
1757 before: call!(Delimited::parse_terminated) >>
1758 middle: option!(do_parse!(
1759 dots: syn!(Dot2) >>
1760 trailing: option!(syn!(Comma)) >>
1761 (dots, trailing)
1762 )) >>
1763 after: cond!(
1764 match middle {
1765 Some((_, ref trailing)) => trailing.is_some(),
1766 _ => false,
1767 },
1768 call!(Delimited::parse_terminated)
1769 ) >>
1770 (before, middle, after)
1771 )),
1772 |((before, middle, after), brackets)| {
1773 let mut before: Delimited<Pat, tokens::Comma> = before;
1774 let after: Option<Delimited<Pat, tokens::Comma>> = after;
1775 let middle: Option<(Dot2, Option<Comma>)> = middle;
1776 PatSlice {
1777 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
1778 comma_token: middle.as_ref().and_then(|m| {
1779 m.1.as_ref().map(|m| Comma(m.0))
1780 }),
1781 bracket_token: brackets,
1782 middle: middle.and_then(|_| {
1783 if !before.is_empty() && !before.trailing_delim() {
1784 Some(Box::new(before.pop().unwrap().into_item()))
1785 } else {
1786 None
1787 }
1788 }),
1789 front: before,
1790 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07001791 }
Alex Crichton954046c2017-05-30 21:49:42 -07001792 }
Michael Layzell92639a52017-06-01 00:07:44 -04001793 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001794 }
David Tolnay435a9a82016-10-29 13:47:20 -07001795
Alex Crichton954046c2017-05-30 21:49:42 -07001796 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04001797 named!(parse -> Self, alt!(
1798 syn!(Move) => { CaptureBy::Value }
1799 |
1800 epsilon!() => { |_| CaptureBy::Ref }
1801 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001802 }
David Tolnayb9c8e322016-09-23 20:48:37 -07001803}
1804
David Tolnayf4bbbd92016-09-23 14:41:55 -07001805#[cfg(feature = "printing")]
1806mod printing {
1807 use super::*;
David Tolnay13b3d352016-10-03 00:31:15 -07001808 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07001809 use quote::{Tokens, ToTokens};
1810
1811 impl ToTokens for Expr {
1812 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07001813 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07001814 self.node.to_tokens(tokens)
1815 }
1816 }
1817
1818 impl ToTokens for ExprBox {
1819 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001820 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001821 self.expr.to_tokens(tokens);
1822 }
1823 }
1824
1825 impl ToTokens for ExprInPlace {
1826 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001827 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001828 self.place.to_tokens(tokens);
1829 self.value.to_tokens(tokens);
1830 }
1831 }
1832
1833 impl ToTokens for ExprArray {
1834 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001835 self.bracket_token.surround(tokens, |tokens| {
1836 self.exprs.to_tokens(tokens);
1837 })
Alex Crichton62a0a592017-05-22 13:58:53 -07001838 }
1839 }
1840
1841 impl ToTokens for ExprCall {
1842 fn to_tokens(&self, tokens: &mut Tokens) {
1843 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001844 self.paren_token.surround(tokens, |tokens| {
1845 self.args.to_tokens(tokens);
1846 })
Alex Crichton62a0a592017-05-22 13:58:53 -07001847 }
1848 }
1849
1850 impl ToTokens for ExprMethodCall {
1851 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001852 self.expr.to_tokens(tokens);
1853 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001854 self.method.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001855 self.colon2_token.to_tokens(tokens);
1856 self.lt_token.to_tokens(tokens);
1857 self.typarams.to_tokens(tokens);
1858 self.gt_token.to_tokens(tokens);
1859 self.paren_token.surround(tokens, |tokens| {
1860 self.args.to_tokens(tokens);
1861 });
Alex Crichton62a0a592017-05-22 13:58:53 -07001862 }
1863 }
1864
1865 impl ToTokens for ExprTup {
1866 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001867 self.paren_token.surround(tokens, |tokens| {
1868 self.args.to_tokens(tokens);
1869 self.lone_comma.to_tokens(tokens);
1870 })
Alex Crichton62a0a592017-05-22 13:58:53 -07001871 }
1872 }
1873
1874 impl ToTokens for ExprBinary {
1875 fn to_tokens(&self, tokens: &mut Tokens) {
1876 self.left.to_tokens(tokens);
1877 self.op.to_tokens(tokens);
1878 self.right.to_tokens(tokens);
1879 }
1880 }
1881
1882 impl ToTokens for ExprUnary {
1883 fn to_tokens(&self, tokens: &mut Tokens) {
1884 self.op.to_tokens(tokens);
1885 self.expr.to_tokens(tokens);
1886 }
1887 }
1888
1889 impl ToTokens for ExprCast {
1890 fn to_tokens(&self, tokens: &mut Tokens) {
1891 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001892 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001893 self.ty.to_tokens(tokens);
1894 }
1895 }
1896
1897 impl ToTokens for ExprType {
1898 fn to_tokens(&self, tokens: &mut Tokens) {
1899 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001900 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001901 self.ty.to_tokens(tokens);
1902 }
1903 }
1904
1905 impl ToTokens for ExprIf {
1906 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001907 self.if_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001908 self.cond.to_tokens(tokens);
1909 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001910 self.else_token.to_tokens(tokens);
1911 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001912 }
1913 }
1914
1915 impl ToTokens for ExprIfLet {
1916 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001917 self.if_token.to_tokens(tokens);
1918 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001919 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001920 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001921 self.expr.to_tokens(tokens);
1922 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001923 self.else_token.to_tokens(tokens);
1924 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001925 }
1926 }
1927
1928 impl ToTokens for ExprWhile {
1929 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001930 self.label.to_tokens(tokens);
1931 self.colon_token.to_tokens(tokens);
1932 self.while_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001933 self.cond.to_tokens(tokens);
1934 self.body.to_tokens(tokens);
1935 }
1936 }
1937
1938 impl ToTokens for ExprWhileLet {
1939 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001940 self.label.to_tokens(tokens);
1941 self.colon_token.to_tokens(tokens);
1942 self.while_token.to_tokens(tokens);
1943 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001944 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001945 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001946 self.expr.to_tokens(tokens);
1947 self.body.to_tokens(tokens);
1948 }
1949 }
1950
1951 impl ToTokens for ExprForLoop {
1952 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001953 self.label.to_tokens(tokens);
1954 self.colon_token.to_tokens(tokens);
1955 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001956 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001957 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001958 self.expr.to_tokens(tokens);
1959 self.body.to_tokens(tokens);
1960 }
1961 }
1962
1963 impl ToTokens for ExprLoop {
1964 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001965 self.label.to_tokens(tokens);
1966 self.colon_token.to_tokens(tokens);
1967 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001968 self.body.to_tokens(tokens);
1969 }
1970 }
1971
1972 impl ToTokens for ExprMatch {
1973 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001974 self.match_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001975 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001976 self.brace_token.surround(tokens, |tokens| {
1977 tokens.append_all(&self.arms);
1978 });
Alex Crichton62a0a592017-05-22 13:58:53 -07001979 }
1980 }
1981
1982 impl ToTokens for ExprCatch {
1983 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001984 self.do_token.to_tokens(tokens);
1985 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07001986 self.block.to_tokens(tokens);
1987 }
1988 }
1989
1990 impl ToTokens for ExprClosure {
1991 fn to_tokens(&self, tokens: &mut Tokens) {
1992 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001993 self.or1_token.to_tokens(tokens);
1994 for item in self.decl.inputs.iter() {
1995 match **item.item() {
1996 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07001997 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07001998 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001999 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002000 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002001 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002002 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002003 self.or2_token.to_tokens(tokens);
2004 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002005 self.body.to_tokens(tokens);
2006 }
2007 }
2008
2009 impl ToTokens for ExprBlock {
2010 fn to_tokens(&self, tokens: &mut Tokens) {
2011 self.unsafety.to_tokens(tokens);
2012 self.block.to_tokens(tokens);
2013 }
2014 }
2015
2016 impl ToTokens for ExprAssign {
2017 fn to_tokens(&self, tokens: &mut Tokens) {
2018 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002019 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002020 self.right.to_tokens(tokens);
2021 }
2022 }
2023
2024 impl ToTokens for ExprAssignOp {
2025 fn to_tokens(&self, tokens: &mut Tokens) {
2026 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002027 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002028 self.right.to_tokens(tokens);
2029 }
2030 }
2031
2032 impl ToTokens for ExprField {
2033 fn to_tokens(&self, tokens: &mut Tokens) {
2034 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002035 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002036 self.field.to_tokens(tokens);
2037 }
2038 }
2039
2040 impl ToTokens for ExprTupField {
2041 fn to_tokens(&self, tokens: &mut Tokens) {
2042 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002043 self.dot_token.to_tokens(tokens);
2044 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002045 }
2046 }
2047
2048 impl ToTokens for ExprIndex {
2049 fn to_tokens(&self, tokens: &mut Tokens) {
2050 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002051 self.bracket_token.surround(tokens, |tokens| {
2052 self.index.to_tokens(tokens);
2053 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002054 }
2055 }
2056
2057 impl ToTokens for ExprRange {
2058 fn to_tokens(&self, tokens: &mut Tokens) {
2059 self.from.to_tokens(tokens);
2060 self.limits.to_tokens(tokens);
2061 self.to.to_tokens(tokens);
2062 }
2063 }
2064
2065 impl ToTokens for ExprPath {
2066 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002067 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002068 }
2069 }
2070
2071 impl ToTokens for ExprAddrOf {
2072 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002073 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002074 self.mutbl.to_tokens(tokens);
2075 self.expr.to_tokens(tokens);
2076 }
2077 }
2078
2079 impl ToTokens for ExprBreak {
2080 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002081 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002082 self.label.to_tokens(tokens);
2083 self.expr.to_tokens(tokens);
2084 }
2085 }
2086
2087 impl ToTokens for ExprContinue {
2088 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002089 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002090 self.label.to_tokens(tokens);
2091 }
2092 }
2093
2094 impl ToTokens for ExprRet {
2095 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002096 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002097 self.expr.to_tokens(tokens);
2098 }
2099 }
2100
2101 impl ToTokens for ExprStruct {
2102 fn to_tokens(&self, tokens: &mut Tokens) {
2103 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002104 self.brace_token.surround(tokens, |tokens| {
2105 self.fields.to_tokens(tokens);
2106 self.dot2_token.to_tokens(tokens);
2107 self.rest.to_tokens(tokens);
2108 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002109 }
2110 }
2111
2112 impl ToTokens for ExprRepeat {
2113 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002114 self.bracket_token.surround(tokens, |tokens| {
2115 self.expr.to_tokens(tokens);
2116 self.semi_token.to_tokens(tokens);
2117 self.amt.to_tokens(tokens);
2118 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002119 }
2120 }
2121
2122 impl ToTokens for ExprParen {
2123 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002124 self.paren_token.surround(tokens, |tokens| {
2125 self.expr.to_tokens(tokens);
2126 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002127 }
2128 }
2129
2130 impl ToTokens for ExprTry {
2131 fn to_tokens(&self, tokens: &mut Tokens) {
2132 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002133 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002134 }
2135 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002136
David Tolnay055a7042016-10-02 19:23:54 -07002137 impl ToTokens for FieldValue {
2138 fn to_tokens(&self, tokens: &mut Tokens) {
2139 self.ident.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002140 if !self.is_shorthand {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002141 self.colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002142 self.expr.to_tokens(tokens);
2143 }
David Tolnay055a7042016-10-02 19:23:54 -07002144 }
2145 }
2146
David Tolnayb4ad3b52016-10-01 21:58:13 -07002147 impl ToTokens for Arm {
2148 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002149 tokens.append_all(&self.attrs);
2150 self.pats.to_tokens(tokens);
2151 self.if_token.to_tokens(tokens);
2152 self.guard.to_tokens(tokens);
2153 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002154 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002155 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002156 }
2157 }
2158
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002159 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002160 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002161 self.underscore_token.to_tokens(tokens);
2162 }
2163 }
2164
2165 impl ToTokens for PatIdent {
2166 fn to_tokens(&self, tokens: &mut Tokens) {
2167 self.mode.to_tokens(tokens);
2168 self.ident.to_tokens(tokens);
2169 self.at_token.to_tokens(tokens);
2170 self.subpat.to_tokens(tokens);
2171 }
2172 }
2173
2174 impl ToTokens for PatStruct {
2175 fn to_tokens(&self, tokens: &mut Tokens) {
2176 self.path.to_tokens(tokens);
2177 self.brace_token.surround(tokens, |tokens| {
2178 self.fields.to_tokens(tokens);
2179 self.dot2_token.to_tokens(tokens);
2180 });
2181 }
2182 }
2183
2184 impl ToTokens for PatTupleStruct {
2185 fn to_tokens(&self, tokens: &mut Tokens) {
2186 self.path.to_tokens(tokens);
2187 self.pat.to_tokens(tokens);
2188 }
2189 }
2190
2191 impl ToTokens for PatPath {
2192 fn to_tokens(&self, tokens: &mut Tokens) {
2193 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2194 }
2195 }
2196
2197 impl ToTokens for PatTuple {
2198 fn to_tokens(&self, tokens: &mut Tokens) {
2199 self.paren_token.surround(tokens, |tokens| {
2200 for (i, token) in self.pats.iter().enumerate() {
2201 if Some(i) == self.dots_pos {
2202 self.dot2_token.to_tokens(tokens);
2203 self.comma_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002204 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002205 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002206 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002207
2208 if Some(self.pats.len()) == self.dots_pos {
2209 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002210 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002211 });
2212 }
2213 }
2214
2215 impl ToTokens for PatBox {
2216 fn to_tokens(&self, tokens: &mut Tokens) {
2217 self.box_token.to_tokens(tokens);
2218 self.pat.to_tokens(tokens);
2219 }
2220 }
2221
2222 impl ToTokens for PatRef {
2223 fn to_tokens(&self, tokens: &mut Tokens) {
2224 self.and_token.to_tokens(tokens);
2225 self.mutbl.to_tokens(tokens);
2226 self.pat.to_tokens(tokens);
2227 }
2228 }
2229
2230 impl ToTokens for PatLit {
2231 fn to_tokens(&self, tokens: &mut Tokens) {
2232 self.expr.to_tokens(tokens);
2233 }
2234 }
2235
2236 impl ToTokens for PatRange {
2237 fn to_tokens(&self, tokens: &mut Tokens) {
2238 self.lo.to_tokens(tokens);
2239 self.limits.to_tokens(tokens);
2240 self.hi.to_tokens(tokens);
2241 }
2242 }
2243
2244 impl ToTokens for PatSlice {
2245 fn to_tokens(&self, tokens: &mut Tokens) {
2246 self.bracket_token.surround(tokens, |tokens| {
2247 self.front.to_tokens(tokens);
2248 self.middle.to_tokens(tokens);
2249 self.dot2_token.to_tokens(tokens);
2250 self.comma_token.to_tokens(tokens);
2251 self.back.to_tokens(tokens);
2252 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002253 }
2254 }
2255
Arnavion1992e2f2017-04-25 01:47:46 -07002256 impl ToTokens for RangeLimits {
2257 fn to_tokens(&self, tokens: &mut Tokens) {
2258 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002259 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2260 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002261 }
2262 }
2263 }
2264
David Tolnay8d9e81a2016-10-03 22:36:32 -07002265 impl ToTokens for FieldPat {
2266 fn to_tokens(&self, tokens: &mut Tokens) {
2267 if !self.is_shorthand {
2268 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002269 self.colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002270 }
2271 self.pat.to_tokens(tokens);
2272 }
2273 }
2274
David Tolnayb4ad3b52016-10-01 21:58:13 -07002275 impl ToTokens for BindingMode {
2276 fn to_tokens(&self, tokens: &mut Tokens) {
2277 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002278 BindingMode::ByRef(ref t, ref m) => {
2279 t.to_tokens(tokens);
2280 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002281 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002282 BindingMode::ByValue(ref m) => {
2283 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002284 }
2285 }
2286 }
2287 }
David Tolnay42602292016-10-01 22:25:45 -07002288
David Tolnay89e05672016-10-02 14:39:42 -07002289 impl ToTokens for CaptureBy {
2290 fn to_tokens(&self, tokens: &mut Tokens) {
2291 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002292 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002293 CaptureBy::Ref => {
2294 // nothing
2295 }
David Tolnay89e05672016-10-02 14:39:42 -07002296 }
2297 }
2298 }
2299
David Tolnay42602292016-10-01 22:25:45 -07002300 impl ToTokens for Block {
2301 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002302 self.brace_token.surround(tokens, |tokens| {
2303 tokens.append_all(&self.stmts);
2304 });
David Tolnay42602292016-10-01 22:25:45 -07002305 }
2306 }
2307
David Tolnay42602292016-10-01 22:25:45 -07002308 impl ToTokens for Stmt {
2309 fn to_tokens(&self, tokens: &mut Tokens) {
2310 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002311 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002312 Stmt::Item(ref item) => item.to_tokens(tokens),
2313 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002314 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002315 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002316 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002317 }
David Tolnay13b3d352016-10-03 00:31:15 -07002318 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002319 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002320 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002321 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002322 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002323 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002324 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2325 // no semicolon
2326 }
David Tolnay13b3d352016-10-03 00:31:15 -07002327 }
2328 }
David Tolnay42602292016-10-01 22:25:45 -07002329 }
2330 }
2331 }
David Tolnay191e0582016-10-02 18:31:09 -07002332
2333 impl ToTokens for Local {
2334 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002335 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002336 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002337 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002338 self.colon_token.to_tokens(tokens);
2339 self.ty.to_tokens(tokens);
2340 self.eq_token.to_tokens(tokens);
2341 self.init.to_tokens(tokens);
2342 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002343 }
2344 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002345}