blob: fa7872b59f8d730c4d508707b93e6c44fb233533 [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
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Alex Crichton62a0a592017-05-22 13:58:53 -070033 pub InPlace(ExprInPlace {
34 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
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
Michael Layzell6a5a1642017-06-04 19:35:15 -0400587ast_enum! {
588 #[cfg_attr(feature = "clone-impls", derive(Copy))]
589 pub enum InPlaceKind {
590 Arrow(tokens::LArrow),
591 In(tokens::In),
592 }
593}
594
David Tolnayb9c8e322016-09-23 20:48:37 -0700595#[cfg(feature = "parsing")]
596pub mod parsing {
597 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700598 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700599
Michael Layzell92639a52017-06-01 00:07:44 -0400600 use proc_macro2::{TokenStream, TokenKind, Delimiter};
601 use synom::{PResult, Cursor, Synom, parse_error};
Alex Crichton954046c2017-05-30 21:49:42 -0700602 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700603
Michael Layzellb78f3b52017-06-04 19:03:03 -0400604 /// When we're parsing expressions which occur before blocks, like in
605 /// an if statement's condition, we cannot parse a struct literal.
606 ///
607 /// Struct literals are ambiguous in certain positions
608 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700609 macro_rules! ambiguous_expr {
610 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700611 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700612 };
613 }
614
Michael Layzellb78f3b52017-06-04 19:03:03 -0400615 /// When we are parsing an optional suffix expression, we cannot allow
616 /// blocks if structs are not allowed.
617 ///
618 /// Example:
619 /// ```ignore
620 /// if break { } { }
621 /// // is ambiguous between:
622 /// if (break { }) { }
623 /// // - or -
624 /// if (break) { } { }
625 /// ```
626 macro_rules! opt_ambiguous_expr {
627 ($i:expr, $allow_struct:ident) => {
628 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
629 };
630 }
631
Alex Crichton954046c2017-05-30 21:49:42 -0700632 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400633 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700634
635 fn description() -> Option<&'static str> {
636 Some("expression")
637 }
638 }
639
David Tolnayaf2557e2016-10-24 11:52:21 -0700640
641 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
642
Michael Layzellb78f3b52017-06-04 19:03:03 -0400643 /// Parse an arbitrary expression.
644 pub fn ambiguous_expr(i: Cursor,
645 allow_struct: bool,
646 allow_block: bool)
647 -> PResult<Expr> {
648 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700649 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400650 call!(assign_expr, allow_struct, allow_block),
651 ExprKind::into
652 )
653 }
654
655 /// Parse a left-associative binary operator.
656 macro_rules! binop {
657 (
658 $name: ident,
659 $next: ident,
660 $submac: ident!( $($args:tt)* )
661 ) => {
662 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
663 mut e: call!($next, allow_struct, allow_block) >>
664 many0!(do_parse!(
665 op: $submac!($($args)*) >>
666 rhs: call!($next, allow_struct, true) >>
667 ({
668 e = ExprBinary {
669 left: Box::new(e.into()),
670 op: op,
671 right: Box::new(rhs.into()),
672 }.into();
673 })
674 )) >>
675 (e)
676 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700677 }
David Tolnay54e854d2016-10-24 12:03:30 -0700678 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700679
Michael Layzellb78f3b52017-06-04 19:03:03 -0400680 /// ```ignore
681 /// <placement> = <placement> ..
682 /// <placement> += <placement> ..
683 /// <placement> -= <placement> ..
684 /// <placement> *= <placement> ..
685 /// <placement> /= <placement> ..
686 /// <placement> %= <placement> ..
687 /// <placement> ^= <placement> ..
688 /// <placement> &= <placement> ..
689 /// <placement> |= <placement> ..
690 /// <placement> <<= <placement> ..
691 /// <placement> >>= <placement> ..
692 /// ```
693 ///
694 /// NOTE: This operator is right-associative.
695 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
696 mut e: call!(placement_expr, allow_struct, allow_block) >>
697 alt!(
698 do_parse!(
699 eq: syn!(Eq) >>
700 // Recurse into self to parse right-associative operator.
701 rhs: call!(assign_expr, allow_struct, true) >>
702 ({
703 e = ExprAssign {
704 left: Box::new(e.into()),
705 eq_token: eq,
706 right: Box::new(rhs.into()),
707 }.into();
708 })
709 )
710 |
711 do_parse!(
712 op: call!(BinOp::parse_assign_op) >>
713 // Recurse into self to parse right-associative operator.
714 rhs: call!(assign_expr, allow_struct, true) >>
715 ({
716 e = ExprAssignOp {
717 left: Box::new(e.into()),
718 op: op,
719 right: Box::new(rhs.into()),
720 }.into();
721 })
722 )
723 |
724 epsilon!()
725 ) >>
726 (e)
727 ));
728
729 /// ```ignore
730 /// <range> <- <range> ..
731 /// ```
732 ///
733 /// NOTE: The `in place { expr }` version of this syntax is parsed in
734 /// `atom_expr`, not here.
735 ///
736 /// NOTE: This operator is right-associative.
737 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
738 mut e: call!(range_expr, allow_struct, allow_block) >>
739 alt!(
740 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400741 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400742 // Recurse into self to parse right-associative operator.
743 rhs: call!(placement_expr, allow_struct, true) >>
744 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400745 e = ExprInPlace {
746 // op: BinOp::Place(larrow),
747 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400748 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400749 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400750 }.into();
751 })
752 )
753 |
754 epsilon!()
755 ) >>
756 (e)
757 ));
758
759 /// ```ignore
760 /// <or> ... <or> ..
761 /// <or> .. <or> ..
762 /// <or> ..
763 /// ```
764 ///
765 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
766 /// rules are for parsing these expressions are, but this is not correct.
767 /// For example, `a .. b .. c` is not a legal expression. It should not
768 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
769 ///
770 /// NOTE: The form of ranges which don't include a preceding expression are
771 /// parsed by `atom_expr`, rather than by this function.
772 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
773 mut e: call!(or_expr, allow_struct, allow_block) >>
774 many0!(do_parse!(
775 limits: syn!(RangeLimits) >>
776 // We don't want to allow blocks here if we don't allow structs. See
777 // the reasoning for `opt_ambiguous_expr!` above.
778 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
779 ({
780 e = ExprRange {
781 from: Some(Box::new(e.into())),
782 limits: limits,
783 to: hi.map(|e| Box::new(e.into())),
784 }.into();
785 })
786 )) >>
787 (e)
788 ));
789
790 /// ```ignore
791 /// <and> || <and> ...
792 /// ```
793 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
794
795 /// ```ignore
796 /// <compare> && <compare> ...
797 /// ```
798 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
799
800 /// ```ignore
801 /// <bitor> == <bitor> ...
802 /// <bitor> != <bitor> ...
803 /// <bitor> >= <bitor> ...
804 /// <bitor> <= <bitor> ...
805 /// <bitor> > <bitor> ...
806 /// <bitor> < <bitor> ...
807 /// ```
808 ///
809 /// NOTE: This operator appears to be parsed as left-associative, but errors
810 /// if it is used in a non-associative manner.
811 binop!(compare_expr, bitor_expr, alt!(
812 syn!(EqEq) => { BinOp::Eq }
813 |
814 syn!(Ne) => { BinOp::Ne }
815 |
816 // must be above Lt
817 syn!(Le) => { BinOp::Le }
818 |
819 // must be above Gt
820 syn!(Ge) => { BinOp::Ge }
821 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400822 do_parse!(
823 // Make sure that we don't eat the < part of a <- operator
824 not!(syn!(LArrow)) >>
825 t: syn!(Lt) >>
826 (BinOp::Lt(t))
827 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400828 |
829 syn!(Gt) => { BinOp::Gt }
830 ));
831
832 /// ```ignore
833 /// <bitxor> | <bitxor> ...
834 /// ```
835 binop!(bitor_expr, bitxor_expr, do_parse!(
836 not!(syn!(OrOr)) >>
837 not!(syn!(OrEq)) >>
838 t: syn!(Or) >>
839 (BinOp::BitOr(t))
840 ));
841
842 /// ```ignore
843 /// <bitand> ^ <bitand> ...
844 /// ```
845 binop!(bitxor_expr, bitand_expr, do_parse!(
846 // NOTE: Make sure we aren't looking at ^=.
847 not!(syn!(CaretEq)) >>
848 t: syn!(Caret) >>
849 (BinOp::BitXor(t))
850 ));
851
852 /// ```ignore
853 /// <shift> & <shift> ...
854 /// ```
855 binop!(bitand_expr, shift_expr, do_parse!(
856 // NOTE: Make sure we aren't looking at && or &=.
857 not!(syn!(AndAnd)) >>
858 not!(syn!(AndEq)) >>
859 t: syn!(And) >>
860 (BinOp::BitAnd(t))
861 ));
862
863 /// ```ignore
864 /// <arith> << <arith> ...
865 /// <arith> >> <arith> ...
866 /// ```
867 binop!(shift_expr, arith_expr, alt!(
868 syn!(Shl) => { BinOp::Shl }
869 |
870 syn!(Shr) => { BinOp::Shr }
871 ));
872
873 /// ```ignore
874 /// <term> + <term> ...
875 /// <term> - <term> ...
876 /// ```
877 binop!(arith_expr, term_expr, alt!(
878 syn!(Add) => { BinOp::Add }
879 |
880 syn!(Sub) => { BinOp::Sub }
881 ));
882
883 /// ```ignore
884 /// <cast> * <cast> ...
885 /// <cast> / <cast> ...
886 /// <cast> % <cast> ...
887 /// ```
888 binop!(term_expr, cast_expr, alt!(
889 syn!(Star) => { BinOp::Mul }
890 |
891 syn!(Div) => { BinOp::Div }
892 |
893 syn!(Rem) => { BinOp::Rem }
894 ));
895
896 /// ```ignore
897 /// <unary> as <ty>
898 /// <unary> : <ty>
899 /// ```
900 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
901 mut e: call!(unary_expr, allow_struct, allow_block) >>
902 many0!(alt!(
903 do_parse!(
904 as_: syn!(As) >>
905 // We can't accept `A + B` in cast expressions, as it's
906 // ambiguous with the + expression.
907 ty: call!(Ty::without_plus) >>
908 ({
909 e = ExprCast {
910 expr: Box::new(e.into()),
911 as_token: as_,
912 ty: Box::new(ty),
913 }.into();
914 })
915 )
916 |
917 do_parse!(
918 colon: syn!(Colon) >>
919 // We can't accept `A + B` in cast expressions, as it's
920 // ambiguous with the + expression.
921 ty: call!(Ty::without_plus) >>
922 ({
923 e = ExprType {
924 expr: Box::new(e.into()),
925 colon_token: colon,
926 ty: Box::new(ty),
927 }.into();
928 })
929 )
930 )) >>
931 (e)
932 ));
933
934 /// ```
935 /// <UnOp> <trailer>
936 /// & <trailer>
937 /// &mut <trailer>
938 /// box <trailer>
939 /// ```
940 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
941 do_parse!(
942 op: syn!(UnOp) >>
943 expr: call!(unary_expr, allow_struct, true) >>
944 (ExprUnary {
945 op: op,
946 expr: Box::new(expr.into()),
947 }.into())
948 )
949 |
950 do_parse!(
951 and: syn!(And) >>
952 mutability: syn!(Mutability) >>
953 expr: call!(unary_expr, allow_struct, true) >>
954 (ExprAddrOf {
955 and_token: and,
956 mutbl: mutability,
957 expr: Box::new(expr.into()),
958 }.into())
959 )
960 |
961 do_parse!(
962 box_: syn!(Box_) >>
963 expr: call!(unary_expr, allow_struct, true) >>
964 (ExprBox {
965 box_token: box_,
966 expr: Box::new(expr.into()),
967 }.into())
968 )
969 |
970 call!(trailer_expr, allow_struct, allow_block)
971 ));
972
973 /// ```ignore
974 /// <atom> (..<args>) ...
975 /// <atom> . <ident> (..<args>) ...
976 /// <atom> . <ident> ...
977 /// <atom> . <lit> ...
978 /// <atom> [ <expr> ] ...
979 /// <atom> ? ...
980 /// ```
981 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
982 mut e: call!(atom_expr, allow_struct, allow_block) >>
983 many0!(alt!(
984 tap!(args: and_call => {
985 let (args, paren) = args;
986 e = ExprCall {
987 func: Box::new(e.into()),
988 args: args,
989 paren_token: paren,
990 }.into();
991 })
992 |
993 tap!(more: and_method_call => {
994 let mut call = more;
995 call.expr = Box::new(e.into());
996 e = call.into();
997 })
998 |
999 tap!(field: and_field => {
1000 let (field, token) = field;
1001 e = ExprField {
1002 expr: Box::new(e.into()),
1003 field: field,
1004 dot_token: token,
1005 }.into();
1006 })
1007 |
1008 tap!(field: and_tup_field => {
1009 let (field, token) = field;
1010 e = ExprTupField {
1011 expr: Box::new(e.into()),
1012 field: field,
1013 dot_token: token,
1014 }.into();
1015 })
1016 |
1017 tap!(i: and_index => {
1018 let (i, token) = i;
1019 e = ExprIndex {
1020 expr: Box::new(e.into()),
1021 bracket_token: token,
1022 index: Box::new(i),
1023 }.into();
1024 })
1025 |
1026 tap!(question: syn!(Question) => {
1027 e = ExprTry {
1028 expr: Box::new(e.into()),
1029 question_token: question,
1030 }.into();
1031 })
1032 )) >>
1033 (e)
1034 ));
1035
1036 /// Parse all atomic expressions which don't have to worry about precidence
1037 /// interactions, as they are fully contained.
1038 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1039 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1040 |
1041 // must be before expr_path
1042 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1043 |
1044 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1045 |
1046 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1047 |
1048 call!(expr_break, allow_struct) // must be before expr_path
1049 |
1050 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1051 |
1052 call!(expr_ret, allow_struct) // must be before expr_path
1053 |
1054 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1055 syn!(ExprInPlace) => { ExprKind::InPlace }
1056 |
1057 syn!(ExprArray) => { ExprKind::Array }
1058 |
1059 syn!(ExprTup) => { ExprKind::Tup }
1060 |
1061 syn!(ExprIf) => { ExprKind::If }
1062 |
1063 syn!(ExprIfLet) => { ExprKind::IfLet }
1064 |
1065 syn!(ExprWhile) => { ExprKind::While }
1066 |
1067 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1068 |
1069 syn!(ExprForLoop) => { ExprKind::ForLoop }
1070 |
1071 syn!(ExprLoop) => { ExprKind::Loop }
1072 |
1073 syn!(ExprMatch) => { ExprKind::Match }
1074 |
1075 syn!(ExprCatch) => { ExprKind::Catch }
1076 |
1077 call!(expr_closure, allow_struct)
1078 |
1079 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1080 |
1081 // NOTE: This is the prefix-form of range
1082 call!(expr_range, allow_struct)
1083 |
1084 syn!(ExprPath) => { ExprKind::Path }
1085 |
1086 syn!(ExprRepeat) => { ExprKind::Repeat }
1087 ));
1088
Alex Crichton954046c2017-05-30 21:49:42 -07001089 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001090 named!(parse -> Self, do_parse!(
1091 e: parens!(syn!(Expr)) >>
1092 (ExprParen {
1093 expr: Box::new(e.0),
1094 paren_token: e.1,
1095 }.into())
1096 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001097 }
David Tolnay89e05672016-10-02 14:39:42 -07001098
Alex Crichton954046c2017-05-30 21:49:42 -07001099 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001100 named!(parse -> Self, do_parse!(
1101 in_: syn!(In) >>
1102 place: expr_no_struct >>
1103 value: braces!(call!(Block::parse_within)) >>
1104 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001105 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001106 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001107 value: Box::new(Expr {
1108 node: ExprBlock {
1109 unsafety: Unsafety::Normal,
1110 block: Block {
1111 stmts: value.0,
1112 brace_token: value.1,
1113 },
1114 }.into(),
1115 attrs: Vec::new(),
1116 }),
1117 })
1118 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001119 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001120
Alex Crichton954046c2017-05-30 21:49:42 -07001121 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001122 named!(parse -> Self, do_parse!(
1123 elems: brackets!(call!(Delimited::parse_terminated)) >>
1124 (ExprArray {
1125 exprs: elems.0,
1126 bracket_token: elems.1,
1127 })
1128 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001129 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001130
Alex Crichton954046c2017-05-30 21:49:42 -07001131 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1132 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001133
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001134 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001135 dot: syn!(Dot) >>
1136 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001137 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001138 colon2: syn!(Colon2) >>
1139 lt: syn!(Lt) >>
1140 tys: call!(Delimited::parse_terminated) >>
1141 gt: syn!(Gt) >>
1142 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001143 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001144 args: parens!(call!(Delimited::parse_terminated)) >>
1145 ({
1146 let (colon2, lt, tys, gt) = match typarams {
1147 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1148 None => (None, None, None, None),
1149 };
1150 ExprMethodCall {
1151 // this expr will get overwritten after being returned
1152 expr: Box::new(ExprKind::Lit(Lit {
1153 span: Span::default(),
1154 value: LitKind::Bool(false),
1155 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001156
Alex Crichton954046c2017-05-30 21:49:42 -07001157 method: method,
1158 args: args.0,
1159 paren_token: args.1,
1160 dot_token: dot,
1161 lt_token: lt,
1162 gt_token: gt,
1163 colon2_token: colon2,
1164 typarams: tys.unwrap_or_default(),
1165 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001166 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001167 ));
1168
Alex Crichton954046c2017-05-30 21:49:42 -07001169 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001170 named!(parse -> Self, do_parse!(
1171 elems: parens!(call!(Delimited::parse_terminated)) >>
1172 (ExprTup {
1173 args: elems.0,
1174 paren_token: elems.1,
1175 lone_comma: None, // TODO: parse this
1176 })
1177 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001178 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001179
Alex Crichton954046c2017-05-30 21:49:42 -07001180 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001181 named!(parse -> Self, do_parse!(
1182 if_: syn!(If) >>
1183 let_: syn!(Let) >>
1184 pat: syn!(Pat) >>
1185 eq: syn!(Eq) >>
1186 cond: expr_no_struct >>
1187 then_block: braces!(call!(Block::parse_within)) >>
1188 else_block: option!(else_block) >>
1189 (ExprIfLet {
1190 pat: Box::new(pat),
1191 let_token: let_,
1192 eq_token: eq,
1193 expr: Box::new(cond),
1194 if_true: Block {
1195 stmts: then_block.0,
1196 brace_token: then_block.1,
1197 },
1198 if_token: if_,
1199 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1200 if_false: else_block.map(|p| Box::new(p.1.into())),
1201 })
1202 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001203 }
1204
Alex Crichton954046c2017-05-30 21:49:42 -07001205 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001206 named!(parse -> Self, do_parse!(
1207 if_: syn!(If) >>
1208 cond: expr_no_struct >>
1209 then_block: braces!(call!(Block::parse_within)) >>
1210 else_block: option!(else_block) >>
1211 (ExprIf {
1212 cond: Box::new(cond),
1213 if_true: Block {
1214 stmts: then_block.0,
1215 brace_token: then_block.1,
1216 },
1217 if_token: if_,
1218 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1219 if_false: else_block.map(|p| Box::new(p.1.into())),
1220 })
1221 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001222 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001223
Alex Crichton954046c2017-05-30 21:49:42 -07001224 named!(else_block -> (Else, ExprKind), do_parse!(
1225 else_: syn!(Else) >>
1226 expr: alt!(
1227 syn!(ExprIf) => { ExprKind::If }
1228 |
1229 syn!(ExprIfLet) => { ExprKind::IfLet }
1230 |
1231 do_parse!(
1232 else_block: braces!(call!(Block::parse_within)) >>
1233 (ExprKind::Block(ExprBlock {
1234 unsafety: Unsafety::Normal,
1235 block: Block {
1236 stmts: else_block.0,
1237 brace_token: else_block.1,
1238 },
1239 }))
David Tolnay939766a2016-09-23 23:48:12 -07001240 )
Alex Crichton954046c2017-05-30 21:49:42 -07001241 ) >>
1242 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001243 ));
1244
David Tolnaybb6feae2016-10-02 21:25:20 -07001245
Alex Crichton954046c2017-05-30 21:49:42 -07001246 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001247 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001248 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001249 for_: syn!(For) >>
1250 pat: syn!(Pat) >>
1251 in_: syn!(In) >>
1252 expr: expr_no_struct >>
1253 loop_block: syn!(Block) >>
1254 (ExprForLoop {
1255 for_token: for_,
1256 in_token: in_,
1257 pat: Box::new(pat),
1258 expr: Box::new(expr),
1259 body: loop_block,
1260 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1261 label: lbl.map(|p| p.0),
1262 })
1263 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001264 }
Gregory Katze5f35682016-09-27 14:20:55 -04001265
Alex Crichton954046c2017-05-30 21:49:42 -07001266 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001267 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001268 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001269 loop_: syn!(Loop) >>
1270 loop_block: syn!(Block) >>
1271 (ExprLoop {
1272 loop_token: loop_,
1273 body: loop_block,
1274 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1275 label: lbl.map(|p| p.0),
1276 })
1277 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001278 }
1279
1280 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001281 named!(parse -> Self, do_parse!(
1282 match_: syn!(Match) >>
1283 obj: expr_no_struct >>
1284 res: braces!(do_parse!(
1285 mut arms: many0!(do_parse!(
1286 arm: syn!(Arm) >>
1287 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1288 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1289 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001290 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001291 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001292 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001293 arms.extend(last_arm);
1294 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001295 })
Michael Layzell92639a52017-06-01 00:07:44 -04001296 )) >>
1297 ({
1298 let (mut arms, brace) = res;
1299 ExprMatch {
1300 expr: Box::new(obj),
1301 match_token: match_,
1302 brace_token: brace,
1303 arms: {
1304 for arm in &mut arms {
1305 if arm_requires_comma(arm) {
1306 arm.comma = Some(tokens::Comma::default());
1307 }
1308 }
1309 arms
1310 },
1311 }
1312 })
1313 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001314 }
David Tolnay1978c672016-10-27 22:05:52 -07001315
Alex Crichton954046c2017-05-30 21:49:42 -07001316 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001317 named!(parse -> Self, do_parse!(
1318 do_: syn!(Do) >>
1319 catch_: syn!(Catch) >>
1320 catch_block: syn!(Block) >>
1321 (ExprCatch {
1322 block: catch_block,
1323 do_token: do_,
1324 catch_token: catch_,
1325 }.into())
1326 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001327 }
Arnavion02ef13f2017-04-25 00:54:31 -07001328
David Tolnay1978c672016-10-27 22:05:52 -07001329 fn arm_requires_comma(arm: &Arm) -> bool {
Alex Crichton62a0a592017-05-22 13:58:53 -07001330 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
David Tolnay1978c672016-10-27 22:05:52 -07001331 false
1332 } else {
1333 true
1334 }
1335 }
1336
Alex Crichton954046c2017-05-30 21:49:42 -07001337 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001338 named!(parse -> Self, do_parse!(
1339 attrs: many0!(call!(Attribute::parse_outer)) >>
1340 pats: call!(Delimited::parse_separated_nonempty) >>
1341 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1342 rocket: syn!(Rocket) >>
1343 body: alt!(
1344 map!(syn!(Block), |blk| {
1345 ExprKind::Block(ExprBlock {
1346 unsafety: Unsafety::Normal,
1347 block: blk,
1348 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001349 })
Michael Layzell92639a52017-06-01 00:07:44 -04001350 |
1351 syn!(Expr)
1352 ) >>
1353 (Arm {
1354 rocket_token: rocket,
1355 if_token: guard.as_ref().map(|p| If((p.0).0)),
1356 attrs: attrs,
1357 pats: pats,
1358 guard: guard.map(|p| Box::new(p.1)),
1359 body: Box::new(body),
1360 comma: None,
1361 })
1362 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001363 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001364
Michael Layzellb78f3b52017-06-04 19:03:03 -04001365 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001366 capture: syn!(CaptureBy) >>
1367 or1: syn!(Or) >>
1368 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1369 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001370 ret_and_body: alt!(
1371 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001372 arrow: syn!(RArrow) >>
1373 ty: syn!(Ty) >>
1374 body: syn!(Block) >>
1375 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001376 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001377 unsafety: Unsafety::Normal,
1378 block: body,
1379 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001380 )
1381 |
David Tolnay58af3552016-12-22 16:58:07 -05001382 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001383 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001384 (ExprClosure {
1385 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001386 or1_token: or1,
1387 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001388 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001389 inputs: inputs,
1390 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001391 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001392 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001393 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001394 generics: Generics::default(),
1395 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001396 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001397 body: Box::new(ret_and_body.1),
1398 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001399 ));
1400
Alex Crichton954046c2017-05-30 21:49:42 -07001401 named!(fn_arg -> FnArg, do_parse!(
1402 pat: syn!(Pat) >>
1403 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1404 ({
1405 let (colon, ty) = ty.unwrap_or_else(|| {
1406 (Colon::default(), TyInfer {
1407 underscore_token: Underscore::default(),
1408 }.into())
1409 });
1410 ArgCaptured {
1411 pat: pat,
1412 colon_token: colon,
1413 ty: ty,
1414 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001415 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001416 ));
1417
Alex Crichton954046c2017-05-30 21:49:42 -07001418 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001419 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001420 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001421 while_: syn!(While) >>
1422 cond: expr_no_struct >>
1423 while_block: syn!(Block) >>
1424 (ExprWhile {
1425 while_token: while_,
1426 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1427 cond: Box::new(cond),
1428 body: while_block,
1429 label: lbl.map(|p| p.0),
1430 })
1431 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001432 }
1433
1434 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001435 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001436 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001437 while_: syn!(While) >>
1438 let_: syn!(Let) >>
1439 pat: syn!(Pat) >>
1440 eq: syn!(Eq) >>
1441 value: expr_no_struct >>
1442 while_block: syn!(Block) >>
1443 (ExprWhileLet {
1444 eq_token: eq,
1445 let_token: let_,
1446 while_token: while_,
1447 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1448 pat: Box::new(pat),
1449 expr: Box::new(value),
1450 body: while_block,
1451 label: lbl.map(|p| p.0),
1452 })
1453 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001454 }
1455
1456 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001457 named!(parse -> Self, do_parse!(
1458 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001459 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001460 (ExprContinue {
1461 continue_token: cont,
1462 label: lbl,
1463 })
1464 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001465 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001466
Michael Layzellb78f3b52017-06-04 19:03:03 -04001467 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001468 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001469 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001470 // We can't allow blocks after a `break` expression when we wouldn't
1471 // allow structs, as this expression is ambiguous.
1472 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001473 (ExprBreak {
1474 label: lbl,
1475 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001476 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001477 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001478 ));
1479
Michael Layzellb78f3b52017-06-04 19:03:03 -04001480 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001481 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001482 // NOTE: return is greedy and eats blocks after it even when in a
1483 // position where structs are not allowed, such as in if statement
1484 // conditions. For example:
1485 //
1486 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001487 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001488 (ExprRet {
1489 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001490 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001491 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001492 ));
1493
Alex Crichton954046c2017-05-30 21:49:42 -07001494 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001495 named!(parse -> Self, do_parse!(
1496 path: syn!(Path) >>
1497 data: braces!(do_parse!(
1498 fields: call!(Delimited::parse_terminated) >>
1499 base: option!(
1500 cond!(fields.is_empty() || fields.trailing_delim(),
1501 do_parse!(
1502 dots: syn!(Dot2) >>
1503 base: syn!(Expr) >>
1504 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001505 )
Michael Layzell92639a52017-06-01 00:07:44 -04001506 )
1507 ) >>
1508 (fields, base)
1509 )) >>
1510 ({
1511 let ((fields, base), brace) = data;
1512 let (dots, rest) = match base.and_then(|b| b) {
1513 Some((dots, base)) => (Some(dots), Some(base)),
1514 None => (None, None),
1515 };
1516 ExprStruct {
1517 brace_token: brace,
1518 path: path,
1519 fields: fields,
1520 dot2_token: dots,
1521 rest: rest.map(Box::new),
1522 }
1523 })
1524 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001525 }
1526
1527 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001528 named!(parse -> Self, alt!(
1529 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001530 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001531 colon: syn!(Colon) >>
1532 value: syn!(Expr) >>
1533 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001534 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001535 expr: value,
1536 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001537 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001538 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001539 })
Michael Layzell92639a52017-06-01 00:07:44 -04001540 )
1541 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001542 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001543 ident: name.clone(),
1544 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1545 is_shorthand: true,
1546 attrs: Vec::new(),
1547 colon_token: None,
1548 })
1549 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001550 }
David Tolnay055a7042016-10-02 19:23:54 -07001551
Alex Crichton954046c2017-05-30 21:49:42 -07001552 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001553 named!(parse -> Self, do_parse!(
1554 data: brackets!(do_parse!(
1555 value: syn!(Expr) >>
1556 semi: syn!(Semi) >>
1557 times: syn!(Expr) >>
1558 (value, semi, times)
1559 )) >>
1560 (ExprRepeat {
1561 expr: Box::new((data.0).0),
1562 amt: Box::new((data.0).2),
1563 bracket_token: data.1,
1564 semi_token: (data.0).1,
1565 })
1566 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001567 }
David Tolnay055a7042016-10-02 19:23:54 -07001568
Alex Crichton954046c2017-05-30 21:49:42 -07001569 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001570 named!(parse -> Self, do_parse!(
1571 rules: syn!(Unsafety) >>
1572 b: syn!(Block) >>
1573 (ExprBlock {
1574 unsafety: rules,
1575 block: b,
1576 })
1577 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001578 }
David Tolnay89e05672016-10-02 14:39:42 -07001579
Michael Layzellb78f3b52017-06-04 19:03:03 -04001580 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001581 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001582 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001583 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001584 ));
1585
Alex Crichton954046c2017-05-30 21:49:42 -07001586 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001587 named!(parse -> Self, alt!(
1588 // Must come before Dot2
1589 syn!(Dot3) => { RangeLimits::Closed }
1590 |
1591 syn!(Dot2) => { RangeLimits::HalfOpen }
1592 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001593 }
David Tolnay438c9052016-10-07 23:24:48 -07001594
Alex Crichton954046c2017-05-30 21:49:42 -07001595 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001596 named!(parse -> Self, do_parse!(
1597 pair: qpath >>
1598 (ExprPath {
1599 qself: pair.0,
1600 path: pair.1,
1601 })
1602 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001603 }
David Tolnay42602292016-10-01 22:25:45 -07001604
Alex Crichton954046c2017-05-30 21:49:42 -07001605 named!(and_field -> (Ident, Dot),
1606 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001607
Alex Crichton954046c2017-05-30 21:49:42 -07001608 named!(and_tup_field -> (Lit, Dot),
1609 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001610
Alex Crichton954046c2017-05-30 21:49:42 -07001611 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001612
Alex Crichton954046c2017-05-30 21:49:42 -07001613 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001614 named!(parse -> Self, do_parse!(
1615 stmts: braces!(call!(Block::parse_within)) >>
1616 (Block {
1617 stmts: stmts.0,
1618 brace_token: stmts.1,
1619 })
1620 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001621 }
David Tolnay939766a2016-09-23 23:48:12 -07001622
Alex Crichton954046c2017-05-30 21:49:42 -07001623 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001624 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1625 many0!(syn!(Semi)) >>
1626 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1627 last: option!(syn!(Expr)) >>
1628 (match last {
1629 None => standalone,
1630 Some(last) => {
1631 standalone.push(Stmt::Expr(Box::new(last)));
1632 standalone
1633 }
1634 })
1635 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001636 }
1637
1638 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001639 named!(parse -> Self, alt!(
1640 stmt_mac
1641 |
1642 stmt_local
1643 |
1644 stmt_item
1645 |
1646 stmt_expr
1647 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001648 }
David Tolnay939766a2016-09-23 23:48:12 -07001649
David Tolnay13b3d352016-10-03 00:31:15 -07001650 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001651 attrs: many0!(call!(Attribute::parse_outer)) >>
1652 what: syn!(Path) >>
1653 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001654 // Only parse braces here; paren and bracket will get parsed as
1655 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001656 data: braces!(syn!(TokenStream)) >>
1657 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001658 (Stmt::Mac(Box::new((
1659 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001660 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001661 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001662 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001663 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001664 span: ((data.1).0).0,
1665 kind: TokenKind::Sequence(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001666 })],
1667 },
Alex Crichton954046c2017-05-30 21:49:42 -07001668 match semi {
1669 Some(semi) => MacStmtStyle::Semicolon(semi),
1670 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001671 },
David Tolnayeea28d62016-10-25 20:44:08 -07001672 attrs,
1673 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001674 ));
1675
David Tolnay191e0582016-10-02 18:31:09 -07001676 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001677 attrs: many0!(call!(Attribute::parse_outer)) >>
1678 let_: syn!(Let) >>
1679 pat: syn!(Pat) >>
1680 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1681 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1682 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001683 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001684 let_token: let_,
1685 semi_token: semi,
1686 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1687 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001688 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001689 ty: ty.map(|p| Box::new(p.1)),
1690 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001691 attrs: attrs,
1692 })))
1693 ));
1694
Alex Crichton954046c2017-05-30 21:49:42 -07001695 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001696
David Tolnaycfe55022016-10-02 22:02:27 -07001697 fn requires_semi(e: &Expr) -> bool {
David Tolnay7184b132016-10-30 10:06:37 -07001698 match e.node {
Alex Crichton62a0a592017-05-22 13:58:53 -07001699 ExprKind::If(_) |
1700 ExprKind::IfLet(_) |
1701 ExprKind::While(_) |
1702 ExprKind::WhileLet(_) |
1703 ExprKind::ForLoop(_) |
1704 ExprKind::Loop(_) |
1705 ExprKind::Match(_) |
1706 ExprKind::Block(_) => false,
David Tolnaycfe55022016-10-02 22:02:27 -07001707
1708 _ => true,
1709 }
1710 }
1711
1712 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001713 attrs: many0!(call!(Attribute::parse_outer)) >>
1714 mut e: syn!(Expr) >>
1715 semi: option!(syn!(Semi)) >>
David Tolnay7184b132016-10-30 10:06:37 -07001716 ({
1717 e.attrs = attrs;
Alex Crichton954046c2017-05-30 21:49:42 -07001718 if let Some(s) = semi {
1719 Stmt::Semi(Box::new(e), s)
David Tolnay092dcb02016-10-30 10:14:14 -07001720 } else if requires_semi(&e) {
Michael Layzell92639a52017-06-01 00:07:44 -04001721 return parse_error();
David Tolnay7184b132016-10-30 10:06:37 -07001722 } else {
1723 Stmt::Expr(Box::new(e))
1724 }
David Tolnaycfe55022016-10-02 22:02:27 -07001725 })
David Tolnay939766a2016-09-23 23:48:12 -07001726 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001727
Alex Crichton954046c2017-05-30 21:49:42 -07001728 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001729 named!(parse -> Self, alt!(
1730 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1731 |
1732 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1733 |
1734 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1735 |
1736 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1737 |
1738 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1739 |
1740 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1741 |
1742 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1743 |
1744 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1745 |
1746 syn!(PatPath) => { Pat::Path }
1747 |
1748 syn!(PatTuple) => { Pat::Tuple }
1749 |
1750 syn!(PatRef) => { Pat::Ref }
1751 |
1752 syn!(PatSlice) => { Pat::Slice }
1753 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001754 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001755
Alex Crichton954046c2017-05-30 21:49:42 -07001756 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001757 named!(parse -> Self, map!(
1758 syn!(Underscore),
1759 |u| PatWild { underscore_token: u }
1760 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001761 }
David Tolnay84aa0752016-10-02 23:01:13 -07001762
Alex Crichton954046c2017-05-30 21:49:42 -07001763 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001764 named!(parse -> Self, do_parse!(
1765 boxed: syn!(Box_) >>
1766 pat: syn!(Pat) >>
1767 (PatBox {
1768 pat: Box::new(pat),
1769 box_token: boxed,
1770 })
1771 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001772 }
1773
1774 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001775 named!(parse -> Self, do_parse!(
1776 mode: option!(syn!(Ref)) >>
1777 mutability: syn!(Mutability) >>
1778 name: alt!(
1779 syn!(Ident)
1780 |
1781 syn!(Self_) => { Into::into }
1782 ) >>
1783 not!(syn!(Lt)) >>
1784 not!(syn!(Colon2)) >>
1785 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1786 (PatIdent {
1787 mode: match mode {
1788 Some(mode) => BindingMode::ByRef(mode, mutability),
1789 None => BindingMode::ByValue(mutability),
1790 },
1791 ident: name,
1792 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1793 subpat: subpat.map(|p| Box::new(p.1)),
1794 })
1795 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001796 }
1797
1798 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001799 named!(parse -> Self, do_parse!(
1800 path: syn!(Path) >>
1801 tuple: syn!(PatTuple) >>
1802 (PatTupleStruct {
1803 path: path,
1804 pat: tuple,
1805 })
1806 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001807 }
1808
1809 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001810 named!(parse -> Self, do_parse!(
1811 path: syn!(Path) >>
1812 data: braces!(do_parse!(
1813 fields: call!(Delimited::parse_terminated) >>
1814 base: option!(
1815 cond!(fields.is_empty() || fields.trailing_delim(),
1816 syn!(Dot2))
1817 ) >>
1818 (fields, base)
1819 )) >>
1820 (PatStruct {
1821 path: path,
1822 fields: (data.0).0,
1823 brace_token: data.1,
1824 dot2_token: (data.0).1.and_then(|m| m),
1825 })
1826 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001827 }
1828
1829 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04001830 named!(parse -> Self, alt!(
1831 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001832 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001833 colon: syn!(Colon) >>
1834 pat: syn!(Pat) >>
1835 (FieldPat {
1836 ident: ident,
1837 pat: Box::new(pat),
1838 is_shorthand: false,
1839 attrs: Vec::new(),
1840 colon_token: Some(colon),
1841 })
1842 )
1843 |
1844 do_parse!(
1845 boxed: option!(syn!(Box_)) >>
1846 mode: option!(syn!(Ref)) >>
1847 mutability: syn!(Mutability) >>
1848 ident: syn!(Ident) >>
1849 ({
1850 let mut pat: Pat = PatIdent {
1851 mode: if let Some(mode) = mode {
1852 BindingMode::ByRef(mode, mutability)
1853 } else {
1854 BindingMode::ByValue(mutability)
1855 },
1856 ident: ident.clone(),
1857 subpat: None,
1858 at_token: None,
1859 }.into();
1860 if let Some(boxed) = boxed {
1861 pat = PatBox {
1862 pat: Box::new(pat),
1863 box_token: boxed,
1864 }.into();
1865 }
1866 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07001867 ident: ident,
1868 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04001869 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07001870 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001871 colon_token: None,
1872 }
1873 })
1874 )
1875 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001876 }
1877
David Tolnay570695e2017-06-03 16:15:13 -07001878 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07001879 syn!(Ident)
1880 |
1881 do_parse!(
1882 lit: syn!(Lit) >>
1883 ({
David Tolnay570695e2017-06-03 16:15:13 -07001884 let s = lit.to_string();
1885 if s.parse::<usize>().is_ok() {
Alex Crichton954046c2017-05-30 21:49:42 -07001886 Ident::new(s.into(), lit.span)
1887 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04001888 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07001889 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07001890 })
1891 )
1892 ));
1893
Alex Crichton954046c2017-05-30 21:49:42 -07001894 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001895 named!(parse -> Self, map!(
1896 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07001897 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04001898 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001899 }
David Tolnay9636c052016-10-02 17:11:17 -07001900
Alex Crichton954046c2017-05-30 21:49:42 -07001901 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001902 named!(parse -> Self, do_parse!(
1903 data: parens!(do_parse!(
1904 elems: call!(Delimited::parse_terminated) >>
1905 dotdot: map!(cond!(
1906 elems.is_empty() || elems.trailing_delim(),
1907 option!(do_parse!(
1908 dots: syn!(Dot2) >>
1909 trailing: option!(syn!(Comma)) >>
1910 (dots, trailing)
1911 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07001912 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001913 rest: cond!(match dotdot {
1914 Some((_, Some(_))) => true,
1915 _ => false,
1916 },
1917 call!(Delimited::parse_terminated)) >>
1918 (elems, dotdot, rest)
1919 )) >>
1920 ({
1921 let ((mut elems, dotdot, rest), parens) = data;
1922 let (dotdot, trailing) = match dotdot {
1923 Some((a, b)) => (Some(a), Some(b)),
1924 None => (None, None),
1925 };
1926 PatTuple {
1927 paren_token: parens,
1928 dots_pos: dotdot.as_ref().map(|_| elems.len()),
1929 dot2_token: dotdot,
1930 comma_token: trailing.and_then(|b| b),
1931 pats: {
1932 if let Some(rest) = rest {
1933 for elem in rest {
1934 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07001935 }
Michael Layzell92639a52017-06-01 00:07:44 -04001936 }
1937 elems
1938 },
1939 }
1940 })
1941 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001942 }
David Tolnayfbb73232016-10-03 01:00:06 -07001943
Alex Crichton954046c2017-05-30 21:49:42 -07001944 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04001945 named!(parse -> Self, do_parse!(
1946 and: syn!(And) >>
1947 mutability: syn!(Mutability) >>
1948 pat: syn!(Pat) >>
1949 (PatRef {
1950 pat: Box::new(pat),
1951 mutbl: mutability,
1952 and_token: and,
1953 })
1954 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001955 }
David Tolnayffdb97f2016-10-03 01:28:33 -07001956
Alex Crichton954046c2017-05-30 21:49:42 -07001957 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04001958 named!(parse -> Self, do_parse!(
1959 lit: pat_lit_expr >>
1960 (if let ExprKind::Path(_) = lit.node {
1961 return parse_error(); // these need to be parsed by pat_path
1962 } else {
1963 PatLit {
1964 expr: Box::new(lit),
1965 }
1966 })
1967 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001968 }
David Tolnaye1310902016-10-29 23:40:00 -07001969
Alex Crichton954046c2017-05-30 21:49:42 -07001970 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04001971 named!(parse -> Self, do_parse!(
1972 lo: pat_lit_expr >>
1973 limits: syn!(RangeLimits) >>
1974 hi: pat_lit_expr >>
1975 (PatRange {
1976 lo: Box::new(lo),
1977 hi: Box::new(hi),
1978 limits: limits,
1979 })
1980 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001981 }
David Tolnaye1310902016-10-29 23:40:00 -07001982
David Tolnay2cfddc62016-10-30 01:03:27 -07001983 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001984 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07001985 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07001986 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07001987 |
Alex Crichton954046c2017-05-30 21:49:42 -07001988 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07001989 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001990 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07001991 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001992 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07001993 expr: Box::new(v.into())
1994 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001995 } else {
David Tolnay7184b132016-10-30 10:06:37 -07001996 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07001997 })
1998 ));
David Tolnay8b308c22016-10-03 01:24:10 -07001999
Alex Crichton954046c2017-05-30 21:49:42 -07002000 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002001 named!(parse -> Self, map!(
2002 brackets!(do_parse!(
2003 before: call!(Delimited::parse_terminated) >>
2004 middle: option!(do_parse!(
2005 dots: syn!(Dot2) >>
2006 trailing: option!(syn!(Comma)) >>
2007 (dots, trailing)
2008 )) >>
2009 after: cond!(
2010 match middle {
2011 Some((_, ref trailing)) => trailing.is_some(),
2012 _ => false,
2013 },
2014 call!(Delimited::parse_terminated)
2015 ) >>
2016 (before, middle, after)
2017 )),
2018 |((before, middle, after), brackets)| {
2019 let mut before: Delimited<Pat, tokens::Comma> = before;
2020 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2021 let middle: Option<(Dot2, Option<Comma>)> = middle;
2022 PatSlice {
2023 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2024 comma_token: middle.as_ref().and_then(|m| {
2025 m.1.as_ref().map(|m| Comma(m.0))
2026 }),
2027 bracket_token: brackets,
2028 middle: middle.and_then(|_| {
2029 if !before.is_empty() && !before.trailing_delim() {
2030 Some(Box::new(before.pop().unwrap().into_item()))
2031 } else {
2032 None
2033 }
2034 }),
2035 front: before,
2036 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002037 }
Alex Crichton954046c2017-05-30 21:49:42 -07002038 }
Michael Layzell92639a52017-06-01 00:07:44 -04002039 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002040 }
David Tolnay435a9a82016-10-29 13:47:20 -07002041
Alex Crichton954046c2017-05-30 21:49:42 -07002042 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002043 named!(parse -> Self, alt!(
2044 syn!(Move) => { CaptureBy::Value }
2045 |
2046 epsilon!() => { |_| CaptureBy::Ref }
2047 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002048 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002049}
2050
David Tolnayf4bbbd92016-09-23 14:41:55 -07002051#[cfg(feature = "printing")]
2052mod printing {
2053 use super::*;
David Tolnay13b3d352016-10-03 00:31:15 -07002054 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002055 use quote::{Tokens, ToTokens};
2056
2057 impl ToTokens for Expr {
2058 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002059 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002060 self.node.to_tokens(tokens)
2061 }
2062 }
2063
2064 impl ToTokens for ExprBox {
2065 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002066 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002067 self.expr.to_tokens(tokens);
2068 }
2069 }
2070
2071 impl ToTokens for ExprInPlace {
2072 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002073 match self.kind {
2074 InPlaceKind::Arrow(ref arrow) => {
2075 self.place.to_tokens(tokens);
2076 arrow.to_tokens(tokens);
2077 self.value.to_tokens(tokens);
2078 }
2079 InPlaceKind::In(ref _in) => {
2080 _in.to_tokens(tokens);
2081 self.place.to_tokens(tokens);
2082 self.value.to_tokens(tokens);
2083 }
2084 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002085 }
2086 }
2087
2088 impl ToTokens for ExprArray {
2089 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002090 self.bracket_token.surround(tokens, |tokens| {
2091 self.exprs.to_tokens(tokens);
2092 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002093 }
2094 }
2095
2096 impl ToTokens for ExprCall {
2097 fn to_tokens(&self, tokens: &mut Tokens) {
2098 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002099 self.paren_token.surround(tokens, |tokens| {
2100 self.args.to_tokens(tokens);
2101 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002102 }
2103 }
2104
2105 impl ToTokens for ExprMethodCall {
2106 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002107 self.expr.to_tokens(tokens);
2108 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002109 self.method.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002110 self.colon2_token.to_tokens(tokens);
2111 self.lt_token.to_tokens(tokens);
2112 self.typarams.to_tokens(tokens);
2113 self.gt_token.to_tokens(tokens);
2114 self.paren_token.surround(tokens, |tokens| {
2115 self.args.to_tokens(tokens);
2116 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002117 }
2118 }
2119
2120 impl ToTokens for ExprTup {
2121 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002122 self.paren_token.surround(tokens, |tokens| {
2123 self.args.to_tokens(tokens);
2124 self.lone_comma.to_tokens(tokens);
2125 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002126 }
2127 }
2128
2129 impl ToTokens for ExprBinary {
2130 fn to_tokens(&self, tokens: &mut Tokens) {
2131 self.left.to_tokens(tokens);
2132 self.op.to_tokens(tokens);
2133 self.right.to_tokens(tokens);
2134 }
2135 }
2136
2137 impl ToTokens for ExprUnary {
2138 fn to_tokens(&self, tokens: &mut Tokens) {
2139 self.op.to_tokens(tokens);
2140 self.expr.to_tokens(tokens);
2141 }
2142 }
2143
2144 impl ToTokens for ExprCast {
2145 fn to_tokens(&self, tokens: &mut Tokens) {
2146 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002147 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002148 self.ty.to_tokens(tokens);
2149 }
2150 }
2151
2152 impl ToTokens for ExprType {
2153 fn to_tokens(&self, tokens: &mut Tokens) {
2154 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002155 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002156 self.ty.to_tokens(tokens);
2157 }
2158 }
2159
2160 impl ToTokens for ExprIf {
2161 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002162 self.if_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002163 self.cond.to_tokens(tokens);
2164 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002165 self.else_token.to_tokens(tokens);
2166 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002167 }
2168 }
2169
2170 impl ToTokens for ExprIfLet {
2171 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002172 self.if_token.to_tokens(tokens);
2173 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002174 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002175 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002176 self.expr.to_tokens(tokens);
2177 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002178 self.else_token.to_tokens(tokens);
2179 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002180 }
2181 }
2182
2183 impl ToTokens for ExprWhile {
2184 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002185 self.label.to_tokens(tokens);
2186 self.colon_token.to_tokens(tokens);
2187 self.while_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002188 self.cond.to_tokens(tokens);
2189 self.body.to_tokens(tokens);
2190 }
2191 }
2192
2193 impl ToTokens for ExprWhileLet {
2194 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002195 self.label.to_tokens(tokens);
2196 self.colon_token.to_tokens(tokens);
2197 self.while_token.to_tokens(tokens);
2198 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002199 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002200 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002201 self.expr.to_tokens(tokens);
2202 self.body.to_tokens(tokens);
2203 }
2204 }
2205
2206 impl ToTokens for ExprForLoop {
2207 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002208 self.label.to_tokens(tokens);
2209 self.colon_token.to_tokens(tokens);
2210 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002211 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002212 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002213 self.expr.to_tokens(tokens);
2214 self.body.to_tokens(tokens);
2215 }
2216 }
2217
2218 impl ToTokens for ExprLoop {
2219 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002220 self.label.to_tokens(tokens);
2221 self.colon_token.to_tokens(tokens);
2222 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002223 self.body.to_tokens(tokens);
2224 }
2225 }
2226
2227 impl ToTokens for ExprMatch {
2228 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002229 self.match_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002230 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002231 self.brace_token.surround(tokens, |tokens| {
2232 tokens.append_all(&self.arms);
2233 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002234 }
2235 }
2236
2237 impl ToTokens for ExprCatch {
2238 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002239 self.do_token.to_tokens(tokens);
2240 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002241 self.block.to_tokens(tokens);
2242 }
2243 }
2244
2245 impl ToTokens for ExprClosure {
2246 fn to_tokens(&self, tokens: &mut Tokens) {
2247 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002248 self.or1_token.to_tokens(tokens);
2249 for item in self.decl.inputs.iter() {
2250 match **item.item() {
2251 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002252 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002253 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002254 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002255 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002256 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002257 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002258 self.or2_token.to_tokens(tokens);
2259 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002260 self.body.to_tokens(tokens);
2261 }
2262 }
2263
2264 impl ToTokens for ExprBlock {
2265 fn to_tokens(&self, tokens: &mut Tokens) {
2266 self.unsafety.to_tokens(tokens);
2267 self.block.to_tokens(tokens);
2268 }
2269 }
2270
2271 impl ToTokens for ExprAssign {
2272 fn to_tokens(&self, tokens: &mut Tokens) {
2273 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002274 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002275 self.right.to_tokens(tokens);
2276 }
2277 }
2278
2279 impl ToTokens for ExprAssignOp {
2280 fn to_tokens(&self, tokens: &mut Tokens) {
2281 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002282 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002283 self.right.to_tokens(tokens);
2284 }
2285 }
2286
2287 impl ToTokens for ExprField {
2288 fn to_tokens(&self, tokens: &mut Tokens) {
2289 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002290 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002291 self.field.to_tokens(tokens);
2292 }
2293 }
2294
2295 impl ToTokens for ExprTupField {
2296 fn to_tokens(&self, tokens: &mut Tokens) {
2297 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002298 self.dot_token.to_tokens(tokens);
2299 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002300 }
2301 }
2302
2303 impl ToTokens for ExprIndex {
2304 fn to_tokens(&self, tokens: &mut Tokens) {
2305 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002306 self.bracket_token.surround(tokens, |tokens| {
2307 self.index.to_tokens(tokens);
2308 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002309 }
2310 }
2311
2312 impl ToTokens for ExprRange {
2313 fn to_tokens(&self, tokens: &mut Tokens) {
2314 self.from.to_tokens(tokens);
2315 self.limits.to_tokens(tokens);
2316 self.to.to_tokens(tokens);
2317 }
2318 }
2319
2320 impl ToTokens for ExprPath {
2321 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002322 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002323 }
2324 }
2325
2326 impl ToTokens for ExprAddrOf {
2327 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002328 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002329 self.mutbl.to_tokens(tokens);
2330 self.expr.to_tokens(tokens);
2331 }
2332 }
2333
2334 impl ToTokens for ExprBreak {
2335 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002336 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002337 self.label.to_tokens(tokens);
2338 self.expr.to_tokens(tokens);
2339 }
2340 }
2341
2342 impl ToTokens for ExprContinue {
2343 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002344 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002345 self.label.to_tokens(tokens);
2346 }
2347 }
2348
2349 impl ToTokens for ExprRet {
2350 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002351 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002352 self.expr.to_tokens(tokens);
2353 }
2354 }
2355
2356 impl ToTokens for ExprStruct {
2357 fn to_tokens(&self, tokens: &mut Tokens) {
2358 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002359 self.brace_token.surround(tokens, |tokens| {
2360 self.fields.to_tokens(tokens);
2361 self.dot2_token.to_tokens(tokens);
2362 self.rest.to_tokens(tokens);
2363 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002364 }
2365 }
2366
2367 impl ToTokens for ExprRepeat {
2368 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002369 self.bracket_token.surround(tokens, |tokens| {
2370 self.expr.to_tokens(tokens);
2371 self.semi_token.to_tokens(tokens);
2372 self.amt.to_tokens(tokens);
2373 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002374 }
2375 }
2376
2377 impl ToTokens for ExprParen {
2378 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002379 self.paren_token.surround(tokens, |tokens| {
2380 self.expr.to_tokens(tokens);
2381 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002382 }
2383 }
2384
2385 impl ToTokens for ExprTry {
2386 fn to_tokens(&self, tokens: &mut Tokens) {
2387 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002388 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002389 }
2390 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002391
David Tolnay055a7042016-10-02 19:23:54 -07002392 impl ToTokens for FieldValue {
2393 fn to_tokens(&self, tokens: &mut Tokens) {
2394 self.ident.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002395 if !self.is_shorthand {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002396 self.colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002397 self.expr.to_tokens(tokens);
2398 }
David Tolnay055a7042016-10-02 19:23:54 -07002399 }
2400 }
2401
David Tolnayb4ad3b52016-10-01 21:58:13 -07002402 impl ToTokens for Arm {
2403 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002404 tokens.append_all(&self.attrs);
2405 self.pats.to_tokens(tokens);
2406 self.if_token.to_tokens(tokens);
2407 self.guard.to_tokens(tokens);
2408 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002409 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002410 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002411 }
2412 }
2413
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002414 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002415 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002416 self.underscore_token.to_tokens(tokens);
2417 }
2418 }
2419
2420 impl ToTokens for PatIdent {
2421 fn to_tokens(&self, tokens: &mut Tokens) {
2422 self.mode.to_tokens(tokens);
2423 self.ident.to_tokens(tokens);
2424 self.at_token.to_tokens(tokens);
2425 self.subpat.to_tokens(tokens);
2426 }
2427 }
2428
2429 impl ToTokens for PatStruct {
2430 fn to_tokens(&self, tokens: &mut Tokens) {
2431 self.path.to_tokens(tokens);
2432 self.brace_token.surround(tokens, |tokens| {
2433 self.fields.to_tokens(tokens);
2434 self.dot2_token.to_tokens(tokens);
2435 });
2436 }
2437 }
2438
2439 impl ToTokens for PatTupleStruct {
2440 fn to_tokens(&self, tokens: &mut Tokens) {
2441 self.path.to_tokens(tokens);
2442 self.pat.to_tokens(tokens);
2443 }
2444 }
2445
2446 impl ToTokens for PatPath {
2447 fn to_tokens(&self, tokens: &mut Tokens) {
2448 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2449 }
2450 }
2451
2452 impl ToTokens for PatTuple {
2453 fn to_tokens(&self, tokens: &mut Tokens) {
2454 self.paren_token.surround(tokens, |tokens| {
2455 for (i, token) in self.pats.iter().enumerate() {
2456 if Some(i) == self.dots_pos {
2457 self.dot2_token.to_tokens(tokens);
2458 self.comma_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002459 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002460 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002461 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002462
2463 if Some(self.pats.len()) == self.dots_pos {
2464 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002465 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002466 });
2467 }
2468 }
2469
2470 impl ToTokens for PatBox {
2471 fn to_tokens(&self, tokens: &mut Tokens) {
2472 self.box_token.to_tokens(tokens);
2473 self.pat.to_tokens(tokens);
2474 }
2475 }
2476
2477 impl ToTokens for PatRef {
2478 fn to_tokens(&self, tokens: &mut Tokens) {
2479 self.and_token.to_tokens(tokens);
2480 self.mutbl.to_tokens(tokens);
2481 self.pat.to_tokens(tokens);
2482 }
2483 }
2484
2485 impl ToTokens for PatLit {
2486 fn to_tokens(&self, tokens: &mut Tokens) {
2487 self.expr.to_tokens(tokens);
2488 }
2489 }
2490
2491 impl ToTokens for PatRange {
2492 fn to_tokens(&self, tokens: &mut Tokens) {
2493 self.lo.to_tokens(tokens);
2494 self.limits.to_tokens(tokens);
2495 self.hi.to_tokens(tokens);
2496 }
2497 }
2498
2499 impl ToTokens for PatSlice {
2500 fn to_tokens(&self, tokens: &mut Tokens) {
2501 self.bracket_token.surround(tokens, |tokens| {
2502 self.front.to_tokens(tokens);
2503 self.middle.to_tokens(tokens);
2504 self.dot2_token.to_tokens(tokens);
2505 self.comma_token.to_tokens(tokens);
2506 self.back.to_tokens(tokens);
2507 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002508 }
2509 }
2510
Arnavion1992e2f2017-04-25 01:47:46 -07002511 impl ToTokens for RangeLimits {
2512 fn to_tokens(&self, tokens: &mut Tokens) {
2513 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002514 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2515 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002516 }
2517 }
2518 }
2519
David Tolnay8d9e81a2016-10-03 22:36:32 -07002520 impl ToTokens for FieldPat {
2521 fn to_tokens(&self, tokens: &mut Tokens) {
2522 if !self.is_shorthand {
2523 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002524 self.colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002525 }
2526 self.pat.to_tokens(tokens);
2527 }
2528 }
2529
David Tolnayb4ad3b52016-10-01 21:58:13 -07002530 impl ToTokens for BindingMode {
2531 fn to_tokens(&self, tokens: &mut Tokens) {
2532 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002533 BindingMode::ByRef(ref t, ref m) => {
2534 t.to_tokens(tokens);
2535 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002536 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002537 BindingMode::ByValue(ref m) => {
2538 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002539 }
2540 }
2541 }
2542 }
David Tolnay42602292016-10-01 22:25:45 -07002543
David Tolnay89e05672016-10-02 14:39:42 -07002544 impl ToTokens for CaptureBy {
2545 fn to_tokens(&self, tokens: &mut Tokens) {
2546 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002547 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002548 CaptureBy::Ref => {
2549 // nothing
2550 }
David Tolnay89e05672016-10-02 14:39:42 -07002551 }
2552 }
2553 }
2554
David Tolnay42602292016-10-01 22:25:45 -07002555 impl ToTokens for Block {
2556 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002557 self.brace_token.surround(tokens, |tokens| {
2558 tokens.append_all(&self.stmts);
2559 });
David Tolnay42602292016-10-01 22:25:45 -07002560 }
2561 }
2562
David Tolnay42602292016-10-01 22:25:45 -07002563 impl ToTokens for Stmt {
2564 fn to_tokens(&self, tokens: &mut Tokens) {
2565 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002566 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002567 Stmt::Item(ref item) => item.to_tokens(tokens),
2568 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002569 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002570 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002571 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002572 }
David Tolnay13b3d352016-10-03 00:31:15 -07002573 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002574 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002575 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002576 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002577 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002578 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002579 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2580 // no semicolon
2581 }
David Tolnay13b3d352016-10-03 00:31:15 -07002582 }
2583 }
David Tolnay42602292016-10-01 22:25:45 -07002584 }
2585 }
2586 }
David Tolnay191e0582016-10-02 18:31:09 -07002587
2588 impl ToTokens for Local {
2589 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002590 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002591 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002592 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002593 self.colon_token.to_tokens(tokens);
2594 self.ty.to_tokens(tokens);
2595 self.eq_token.to_tokens(tokens);
2596 self.init.to_tokens(tokens);
2597 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002598 }
2599 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002600}