blob: 79a4b563bef981c81a6e1ec1fb68e7af92dc1888 [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
Michael Layzell93c36282017-06-04 20:43:14 -0400325 /// No-op: used solely so we can pretty-print faithfully
326 ///
327 /// A `group` represents a `None`-delimited span in the input
328 /// `TokenStream` which affects the precidence of the resulting
329 /// expression. They are used for macro hygiene.
330 pub Group(ExprGroup {
331 pub expr: Box<Expr>,
332 pub group_token: tokens::Group,
333 }),
334
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 /// `expr?`
336 pub Try(ExprTry {
337 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700338 pub question_token: tokens::Question,
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700340
Alex Crichton62a0a592017-05-22 13:58:53 -0700341 /// A catch expression.
342 ///
343 /// E.g. `do catch { block }`
344 pub Catch(ExprCatch {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700345 pub do_token: tokens::Do,
346 pub catch_token: tokens::Catch,
Alex Crichton62a0a592017-05-22 13:58:53 -0700347 pub block: Block,
348 }),
349 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700350}
351
Alex Crichton62a0a592017-05-22 13:58:53 -0700352ast_struct! {
353 /// A field-value pair in a struct literal.
354 pub struct FieldValue {
355 /// Name of the field.
356 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500357
Alex Crichton62a0a592017-05-22 13:58:53 -0700358 /// Value of the field.
359 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500360
Alex Crichton62a0a592017-05-22 13:58:53 -0700361 /// Whether this is a shorthand field, e.g. `Struct { x }`
362 /// instead of `Struct { x: x }`.
363 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500364
Alex Crichton62a0a592017-05-22 13:58:53 -0700365 /// Attributes tagged on the field.
366 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700367
368 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700369 }
David Tolnay055a7042016-10-02 19:23:54 -0700370}
371
Alex Crichton62a0a592017-05-22 13:58:53 -0700372ast_struct! {
373 /// A Block (`{ .. }`).
374 ///
375 /// E.g. `{ .. }` as in `fn foo() { .. }`
376 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700377 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700378 /// Statements in a block
379 pub stmts: Vec<Stmt>,
380 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700381}
382
Alex Crichton62a0a592017-05-22 13:58:53 -0700383ast_enum! {
384 /// A statement, usually ending in a semicolon.
385 pub enum Stmt {
386 /// A local (let) binding.
387 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700388
Alex Crichton62a0a592017-05-22 13:58:53 -0700389 /// An item definition.
390 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391
Alex Crichton62a0a592017-05-22 13:58:53 -0700392 /// Expr without trailing semicolon.
393 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700394
Alex Crichton62a0a592017-05-22 13:58:53 -0700395 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700396 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700397
Alex Crichton62a0a592017-05-22 13:58:53 -0700398 /// Macro invocation.
399 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
400 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700401}
402
Alex Crichton62a0a592017-05-22 13:58:53 -0700403ast_enum! {
404 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700405 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700406 pub enum MacStmtStyle {
407 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
408 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700409 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// The macro statement had braces; e.g. foo! { ... }
412 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// The macro statement had parentheses or brackets and no semicolon; e.g.
415 /// `foo!(...)`. All of these will end up being converted into macro
416 /// expressions.
417 NoBraces,
418 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700419}
420
Alex Crichton62a0a592017-05-22 13:58:53 -0700421ast_struct! {
422 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
423 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700424 pub let_token: tokens::Let,
425 pub colon_token: Option<tokens::Colon>,
426 pub eq_token: Option<tokens::Eq>,
427 pub semi_token: tokens::Semi,
428
Alex Crichton62a0a592017-05-22 13:58:53 -0700429 pub pat: Box<Pat>,
430 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500431
Alex Crichton62a0a592017-05-22 13:58:53 -0700432 /// Initializer expression to set the value, if any
433 pub init: Option<Box<Expr>>,
434 pub attrs: Vec<Attribute>,
435 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700436}
437
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700438ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700439 // Clippy false positive
440 // https://github.com/Manishearth/rust-clippy/issues/1241
441 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
442 pub enum Pat {
443 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700444 pub Wild(PatWild {
445 pub underscore_token: tokens::Underscore,
446 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700447
Alex Crichton62a0a592017-05-22 13:58:53 -0700448 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
449 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
450 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
451 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700452 pub Ident(PatIdent {
453 pub mode: BindingMode,
454 pub ident: Ident,
455 pub subpat: Option<Box<Pat>>,
456 pub at_token: Option<tokens::At>,
457 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700458
Alex Crichton62a0a592017-05-22 13:58:53 -0700459 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
460 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700461 pub Struct(PatStruct {
462 pub path: Path,
463 pub fields: Delimited<FieldPat, tokens::Comma>,
464 pub brace_token: tokens::Brace,
465 pub dot2_token: Option<tokens::Dot2>,
466 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700467
Alex Crichton62a0a592017-05-22 13:58:53 -0700468 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
469 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
470 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700471 pub TupleStruct(PatTupleStruct {
472 pub path: Path,
473 pub pat: PatTuple,
474 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700475
Alex Crichton62a0a592017-05-22 13:58:53 -0700476 /// A possibly qualified path pattern.
477 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
478 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
479 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480 pub Path(PatPath {
481 pub qself: Option<QSelf>,
482 pub path: Path,
483 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700484
Alex Crichton62a0a592017-05-22 13:58:53 -0700485 /// A tuple pattern `(a, b)`.
486 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
487 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700488 pub Tuple(PatTuple {
489 pub pats: Delimited<Pat, tokens::Comma>,
490 pub dots_pos: Option<usize>,
491 pub paren_token: tokens::Paren,
492 pub dot2_token: Option<tokens::Dot2>,
493 pub comma_token: Option<tokens::Comma>,
494 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700495 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700496 pub Box(PatBox {
497 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700498 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700499 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700500 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700501 pub Ref(PatRef {
502 pub pat: Box<Pat>,
503 pub mutbl: Mutability,
504 pub and_token: tokens::And,
505 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700506 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700507 pub Lit(PatLit {
508 pub expr: Box<Expr>,
509 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700510 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700511 pub Range(PatRange {
512 pub lo: Box<Expr>,
513 pub hi: Box<Expr>,
514 pub limits: RangeLimits,
515 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700516 /// `[a, b, ..i, y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700517 pub Slice(PatSlice {
518 pub front: Delimited<Pat, tokens::Comma>,
519 pub middle: Option<Box<Pat>>,
520 pub back: Delimited<Pat, tokens::Comma>,
521 pub dot2_token: Option<tokens::Dot2>,
522 pub comma_token: Option<tokens::Comma>,
523 pub bracket_token: tokens::Bracket,
524 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700525 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700526 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700527 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700528}
529
Alex Crichton62a0a592017-05-22 13:58:53 -0700530ast_struct! {
531 /// An arm of a 'match'.
532 ///
533 /// E.g. `0...10 => { println!("match!") }` as in
534 ///
535 /// ```rust,ignore
536 /// match n {
537 /// 0...10 => { println!("match!") },
538 /// // ..
539 /// }
540 /// ```
541 pub struct Arm {
542 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700543 pub pats: Delimited<Pat, tokens::Or>,
544 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700545 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700546 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700547 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700548 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700549 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700550}
551
Alex Crichton62a0a592017-05-22 13:58:53 -0700552ast_enum! {
553 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700554 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700555 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700557 Ref,
558 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700559}
560
Alex Crichton62a0a592017-05-22 13:58:53 -0700561ast_enum! {
562 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700563 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 pub enum RangeLimits {
565 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700566 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700567 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700568 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700569 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700570}
571
Alex Crichton62a0a592017-05-22 13:58:53 -0700572ast_struct! {
573 /// A single field in a struct pattern
574 ///
575 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
576 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
577 /// except `is_shorthand` is true
578 pub struct FieldPat {
579 /// The identifier for the field
580 pub ident: Ident,
581 /// The pattern the field is destructured to
582 pub pat: Box<Pat>,
583 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700584 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700585 pub attrs: Vec<Attribute>,
586 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587}
588
Alex Crichton62a0a592017-05-22 13:58:53 -0700589ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700590 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700591 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700592 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700593 ByValue(Mutability),
594 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700595}
596
Michael Layzell6a5a1642017-06-04 19:35:15 -0400597ast_enum! {
598 #[cfg_attr(feature = "clone-impls", derive(Copy))]
599 pub enum InPlaceKind {
600 Arrow(tokens::LArrow),
601 In(tokens::In),
602 }
603}
604
David Tolnayb9c8e322016-09-23 20:48:37 -0700605#[cfg(feature = "parsing")]
606pub mod parsing {
607 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700608 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700609
Michael Layzell92639a52017-06-01 00:07:44 -0400610 use proc_macro2::{TokenStream, TokenKind, Delimiter};
611 use synom::{PResult, Cursor, Synom, parse_error};
Alex Crichton954046c2017-05-30 21:49:42 -0700612 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700613
Michael Layzellb78f3b52017-06-04 19:03:03 -0400614 /// When we're parsing expressions which occur before blocks, like in
615 /// an if statement's condition, we cannot parse a struct literal.
616 ///
617 /// Struct literals are ambiguous in certain positions
618 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700619 macro_rules! ambiguous_expr {
620 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700621 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700622 };
623 }
624
Michael Layzellb78f3b52017-06-04 19:03:03 -0400625 /// When we are parsing an optional suffix expression, we cannot allow
626 /// blocks if structs are not allowed.
627 ///
628 /// Example:
629 /// ```ignore
630 /// if break { } { }
631 /// // is ambiguous between:
632 /// if (break { }) { }
633 /// // - or -
634 /// if (break) { } { }
635 /// ```
636 macro_rules! opt_ambiguous_expr {
637 ($i:expr, $allow_struct:ident) => {
638 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
639 };
640 }
641
Alex Crichton954046c2017-05-30 21:49:42 -0700642 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400643 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700644
645 fn description() -> Option<&'static str> {
646 Some("expression")
647 }
648 }
649
David Tolnayaf2557e2016-10-24 11:52:21 -0700650
651 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
652
Michael Layzellb78f3b52017-06-04 19:03:03 -0400653 /// Parse an arbitrary expression.
654 pub fn ambiguous_expr(i: Cursor,
655 allow_struct: bool,
656 allow_block: bool)
657 -> PResult<Expr> {
658 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700659 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400660 call!(assign_expr, allow_struct, allow_block),
661 ExprKind::into
662 )
663 }
664
665 /// Parse a left-associative binary operator.
666 macro_rules! binop {
667 (
668 $name: ident,
669 $next: ident,
670 $submac: ident!( $($args:tt)* )
671 ) => {
672 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
673 mut e: call!($next, allow_struct, allow_block) >>
674 many0!(do_parse!(
675 op: $submac!($($args)*) >>
676 rhs: call!($next, allow_struct, true) >>
677 ({
678 e = ExprBinary {
679 left: Box::new(e.into()),
680 op: op,
681 right: Box::new(rhs.into()),
682 }.into();
683 })
684 )) >>
685 (e)
686 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700687 }
David Tolnay54e854d2016-10-24 12:03:30 -0700688 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700689
Michael Layzellb78f3b52017-06-04 19:03:03 -0400690 /// ```ignore
691 /// <placement> = <placement> ..
692 /// <placement> += <placement> ..
693 /// <placement> -= <placement> ..
694 /// <placement> *= <placement> ..
695 /// <placement> /= <placement> ..
696 /// <placement> %= <placement> ..
697 /// <placement> ^= <placement> ..
698 /// <placement> &= <placement> ..
699 /// <placement> |= <placement> ..
700 /// <placement> <<= <placement> ..
701 /// <placement> >>= <placement> ..
702 /// ```
703 ///
704 /// NOTE: This operator is right-associative.
705 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
706 mut e: call!(placement_expr, allow_struct, allow_block) >>
707 alt!(
708 do_parse!(
709 eq: syn!(Eq) >>
710 // Recurse into self to parse right-associative operator.
711 rhs: call!(assign_expr, allow_struct, true) >>
712 ({
713 e = ExprAssign {
714 left: Box::new(e.into()),
715 eq_token: eq,
716 right: Box::new(rhs.into()),
717 }.into();
718 })
719 )
720 |
721 do_parse!(
722 op: call!(BinOp::parse_assign_op) >>
723 // Recurse into self to parse right-associative operator.
724 rhs: call!(assign_expr, allow_struct, true) >>
725 ({
726 e = ExprAssignOp {
727 left: Box::new(e.into()),
728 op: op,
729 right: Box::new(rhs.into()),
730 }.into();
731 })
732 )
733 |
734 epsilon!()
735 ) >>
736 (e)
737 ));
738
739 /// ```ignore
740 /// <range> <- <range> ..
741 /// ```
742 ///
743 /// NOTE: The `in place { expr }` version of this syntax is parsed in
744 /// `atom_expr`, not here.
745 ///
746 /// NOTE: This operator is right-associative.
747 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
748 mut e: call!(range_expr, allow_struct, allow_block) >>
749 alt!(
750 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400751 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400752 // Recurse into self to parse right-associative operator.
753 rhs: call!(placement_expr, allow_struct, true) >>
754 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400755 e = ExprInPlace {
756 // op: BinOp::Place(larrow),
757 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400758 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400759 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400760 }.into();
761 })
762 )
763 |
764 epsilon!()
765 ) >>
766 (e)
767 ));
768
769 /// ```ignore
770 /// <or> ... <or> ..
771 /// <or> .. <or> ..
772 /// <or> ..
773 /// ```
774 ///
775 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
776 /// rules are for parsing these expressions are, but this is not correct.
777 /// For example, `a .. b .. c` is not a legal expression. It should not
778 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
779 ///
780 /// NOTE: The form of ranges which don't include a preceding expression are
781 /// parsed by `atom_expr`, rather than by this function.
782 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
783 mut e: call!(or_expr, allow_struct, allow_block) >>
784 many0!(do_parse!(
785 limits: syn!(RangeLimits) >>
786 // We don't want to allow blocks here if we don't allow structs. See
787 // the reasoning for `opt_ambiguous_expr!` above.
788 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
789 ({
790 e = ExprRange {
791 from: Some(Box::new(e.into())),
792 limits: limits,
793 to: hi.map(|e| Box::new(e.into())),
794 }.into();
795 })
796 )) >>
797 (e)
798 ));
799
800 /// ```ignore
801 /// <and> || <and> ...
802 /// ```
803 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
804
805 /// ```ignore
806 /// <compare> && <compare> ...
807 /// ```
808 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
809
810 /// ```ignore
811 /// <bitor> == <bitor> ...
812 /// <bitor> != <bitor> ...
813 /// <bitor> >= <bitor> ...
814 /// <bitor> <= <bitor> ...
815 /// <bitor> > <bitor> ...
816 /// <bitor> < <bitor> ...
817 /// ```
818 ///
819 /// NOTE: This operator appears to be parsed as left-associative, but errors
820 /// if it is used in a non-associative manner.
821 binop!(compare_expr, bitor_expr, alt!(
822 syn!(EqEq) => { BinOp::Eq }
823 |
824 syn!(Ne) => { BinOp::Ne }
825 |
826 // must be above Lt
827 syn!(Le) => { BinOp::Le }
828 |
829 // must be above Gt
830 syn!(Ge) => { BinOp::Ge }
831 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400832 do_parse!(
833 // Make sure that we don't eat the < part of a <- operator
834 not!(syn!(LArrow)) >>
835 t: syn!(Lt) >>
836 (BinOp::Lt(t))
837 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400838 |
839 syn!(Gt) => { BinOp::Gt }
840 ));
841
842 /// ```ignore
843 /// <bitxor> | <bitxor> ...
844 /// ```
845 binop!(bitor_expr, bitxor_expr, do_parse!(
846 not!(syn!(OrOr)) >>
847 not!(syn!(OrEq)) >>
848 t: syn!(Or) >>
849 (BinOp::BitOr(t))
850 ));
851
852 /// ```ignore
853 /// <bitand> ^ <bitand> ...
854 /// ```
855 binop!(bitxor_expr, bitand_expr, do_parse!(
856 // NOTE: Make sure we aren't looking at ^=.
857 not!(syn!(CaretEq)) >>
858 t: syn!(Caret) >>
859 (BinOp::BitXor(t))
860 ));
861
862 /// ```ignore
863 /// <shift> & <shift> ...
864 /// ```
865 binop!(bitand_expr, shift_expr, do_parse!(
866 // NOTE: Make sure we aren't looking at && or &=.
867 not!(syn!(AndAnd)) >>
868 not!(syn!(AndEq)) >>
869 t: syn!(And) >>
870 (BinOp::BitAnd(t))
871 ));
872
873 /// ```ignore
874 /// <arith> << <arith> ...
875 /// <arith> >> <arith> ...
876 /// ```
877 binop!(shift_expr, arith_expr, alt!(
878 syn!(Shl) => { BinOp::Shl }
879 |
880 syn!(Shr) => { BinOp::Shr }
881 ));
882
883 /// ```ignore
884 /// <term> + <term> ...
885 /// <term> - <term> ...
886 /// ```
887 binop!(arith_expr, term_expr, alt!(
888 syn!(Add) => { BinOp::Add }
889 |
890 syn!(Sub) => { BinOp::Sub }
891 ));
892
893 /// ```ignore
894 /// <cast> * <cast> ...
895 /// <cast> / <cast> ...
896 /// <cast> % <cast> ...
897 /// ```
898 binop!(term_expr, cast_expr, alt!(
899 syn!(Star) => { BinOp::Mul }
900 |
901 syn!(Div) => { BinOp::Div }
902 |
903 syn!(Rem) => { BinOp::Rem }
904 ));
905
906 /// ```ignore
907 /// <unary> as <ty>
908 /// <unary> : <ty>
909 /// ```
910 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
911 mut e: call!(unary_expr, allow_struct, allow_block) >>
912 many0!(alt!(
913 do_parse!(
914 as_: syn!(As) >>
915 // We can't accept `A + B` in cast expressions, as it's
916 // ambiguous with the + expression.
917 ty: call!(Ty::without_plus) >>
918 ({
919 e = ExprCast {
920 expr: Box::new(e.into()),
921 as_token: as_,
922 ty: Box::new(ty),
923 }.into();
924 })
925 )
926 |
927 do_parse!(
928 colon: syn!(Colon) >>
929 // We can't accept `A + B` in cast expressions, as it's
930 // ambiguous with the + expression.
931 ty: call!(Ty::without_plus) >>
932 ({
933 e = ExprType {
934 expr: Box::new(e.into()),
935 colon_token: colon,
936 ty: Box::new(ty),
937 }.into();
938 })
939 )
940 )) >>
941 (e)
942 ));
943
944 /// ```
945 /// <UnOp> <trailer>
946 /// & <trailer>
947 /// &mut <trailer>
948 /// box <trailer>
949 /// ```
950 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
951 do_parse!(
952 op: syn!(UnOp) >>
953 expr: call!(unary_expr, allow_struct, true) >>
954 (ExprUnary {
955 op: op,
956 expr: Box::new(expr.into()),
957 }.into())
958 )
959 |
960 do_parse!(
961 and: syn!(And) >>
962 mutability: syn!(Mutability) >>
963 expr: call!(unary_expr, allow_struct, true) >>
964 (ExprAddrOf {
965 and_token: and,
966 mutbl: mutability,
967 expr: Box::new(expr.into()),
968 }.into())
969 )
970 |
971 do_parse!(
972 box_: syn!(Box_) >>
973 expr: call!(unary_expr, allow_struct, true) >>
974 (ExprBox {
975 box_token: box_,
976 expr: Box::new(expr.into()),
977 }.into())
978 )
979 |
980 call!(trailer_expr, allow_struct, allow_block)
981 ));
982
983 /// ```ignore
984 /// <atom> (..<args>) ...
985 /// <atom> . <ident> (..<args>) ...
986 /// <atom> . <ident> ...
987 /// <atom> . <lit> ...
988 /// <atom> [ <expr> ] ...
989 /// <atom> ? ...
990 /// ```
991 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
992 mut e: call!(atom_expr, allow_struct, allow_block) >>
993 many0!(alt!(
994 tap!(args: and_call => {
995 let (args, paren) = args;
996 e = ExprCall {
997 func: Box::new(e.into()),
998 args: args,
999 paren_token: paren,
1000 }.into();
1001 })
1002 |
1003 tap!(more: and_method_call => {
1004 let mut call = more;
1005 call.expr = Box::new(e.into());
1006 e = call.into();
1007 })
1008 |
1009 tap!(field: and_field => {
1010 let (field, token) = field;
1011 e = ExprField {
1012 expr: Box::new(e.into()),
1013 field: field,
1014 dot_token: token,
1015 }.into();
1016 })
1017 |
1018 tap!(field: and_tup_field => {
1019 let (field, token) = field;
1020 e = ExprTupField {
1021 expr: Box::new(e.into()),
1022 field: field,
1023 dot_token: token,
1024 }.into();
1025 })
1026 |
1027 tap!(i: and_index => {
1028 let (i, token) = i;
1029 e = ExprIndex {
1030 expr: Box::new(e.into()),
1031 bracket_token: token,
1032 index: Box::new(i),
1033 }.into();
1034 })
1035 |
1036 tap!(question: syn!(Question) => {
1037 e = ExprTry {
1038 expr: Box::new(e.into()),
1039 question_token: question,
1040 }.into();
1041 })
1042 )) >>
1043 (e)
1044 ));
1045
1046 /// Parse all atomic expressions which don't have to worry about precidence
1047 /// interactions, as they are fully contained.
1048 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001049 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1050 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001051 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1052 |
1053 // must be before expr_path
1054 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1055 |
1056 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1057 |
1058 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1059 |
1060 call!(expr_break, allow_struct) // must be before expr_path
1061 |
1062 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1063 |
1064 call!(expr_ret, allow_struct) // must be before expr_path
1065 |
1066 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1067 syn!(ExprInPlace) => { ExprKind::InPlace }
1068 |
1069 syn!(ExprArray) => { ExprKind::Array }
1070 |
1071 syn!(ExprTup) => { ExprKind::Tup }
1072 |
1073 syn!(ExprIf) => { ExprKind::If }
1074 |
1075 syn!(ExprIfLet) => { ExprKind::IfLet }
1076 |
1077 syn!(ExprWhile) => { ExprKind::While }
1078 |
1079 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1080 |
1081 syn!(ExprForLoop) => { ExprKind::ForLoop }
1082 |
1083 syn!(ExprLoop) => { ExprKind::Loop }
1084 |
1085 syn!(ExprMatch) => { ExprKind::Match }
1086 |
1087 syn!(ExprCatch) => { ExprKind::Catch }
1088 |
1089 call!(expr_closure, allow_struct)
1090 |
1091 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1092 |
1093 // NOTE: This is the prefix-form of range
1094 call!(expr_range, allow_struct)
1095 |
1096 syn!(ExprPath) => { ExprKind::Path }
1097 |
1098 syn!(ExprRepeat) => { ExprKind::Repeat }
1099 ));
1100
Michael Layzell35418782017-06-07 09:20:25 -04001101 named!(expr_nosemi -> Expr, map!(alt!(
1102 syn!(ExprIf) => { ExprKind::If }
1103 |
1104 syn!(ExprIfLet) => { ExprKind::IfLet }
1105 |
1106 syn!(ExprWhile) => { ExprKind::While }
1107 |
1108 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1109 |
1110 syn!(ExprForLoop) => { ExprKind::ForLoop }
1111 |
1112 syn!(ExprLoop) => { ExprKind::Loop }
1113 |
1114 syn!(ExprMatch) => { ExprKind::Match }
1115 |
1116 syn!(ExprCatch) => { ExprKind::Catch }
1117 |
1118 syn!(ExprBlock) => { ExprKind::Block }
1119 ), Expr::from));
1120
Michael Layzell93c36282017-06-04 20:43:14 -04001121 impl Synom for ExprGroup {
1122 named!(parse -> Self, do_parse!(
1123 e: grouped!(syn!(Expr)) >>
1124 (ExprGroup {
1125 expr: Box::new(e.0),
1126 group_token: e.1,
1127 }.into())
1128 ));
1129 }
1130
Alex Crichton954046c2017-05-30 21:49:42 -07001131 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001132 named!(parse -> Self, do_parse!(
1133 e: parens!(syn!(Expr)) >>
1134 (ExprParen {
1135 expr: Box::new(e.0),
1136 paren_token: e.1,
1137 }.into())
1138 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001139 }
David Tolnay89e05672016-10-02 14:39:42 -07001140
Alex Crichton954046c2017-05-30 21:49:42 -07001141 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001142 named!(parse -> Self, do_parse!(
1143 in_: syn!(In) >>
1144 place: expr_no_struct >>
1145 value: braces!(call!(Block::parse_within)) >>
1146 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001147 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001148 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001149 value: Box::new(Expr {
1150 node: ExprBlock {
1151 unsafety: Unsafety::Normal,
1152 block: Block {
1153 stmts: value.0,
1154 brace_token: value.1,
1155 },
1156 }.into(),
1157 attrs: Vec::new(),
1158 }),
1159 })
1160 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001161 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001162
Alex Crichton954046c2017-05-30 21:49:42 -07001163 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001164 named!(parse -> Self, do_parse!(
1165 elems: brackets!(call!(Delimited::parse_terminated)) >>
1166 (ExprArray {
1167 exprs: elems.0,
1168 bracket_token: elems.1,
1169 })
1170 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001171 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001172
Alex Crichton954046c2017-05-30 21:49:42 -07001173 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1174 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001175
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001176 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001177 dot: syn!(Dot) >>
1178 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001179 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001180 colon2: syn!(Colon2) >>
1181 lt: syn!(Lt) >>
1182 tys: call!(Delimited::parse_terminated) >>
1183 gt: syn!(Gt) >>
1184 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001185 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001186 args: parens!(call!(Delimited::parse_terminated)) >>
1187 ({
1188 let (colon2, lt, tys, gt) = match typarams {
1189 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1190 None => (None, None, None, None),
1191 };
1192 ExprMethodCall {
1193 // this expr will get overwritten after being returned
1194 expr: Box::new(ExprKind::Lit(Lit {
1195 span: Span::default(),
1196 value: LitKind::Bool(false),
1197 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001198
Alex Crichton954046c2017-05-30 21:49:42 -07001199 method: method,
1200 args: args.0,
1201 paren_token: args.1,
1202 dot_token: dot,
1203 lt_token: lt,
1204 gt_token: gt,
1205 colon2_token: colon2,
1206 typarams: tys.unwrap_or_default(),
1207 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001208 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001209 ));
1210
Alex Crichton954046c2017-05-30 21:49:42 -07001211 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001212 named!(parse -> Self, do_parse!(
1213 elems: parens!(call!(Delimited::parse_terminated)) >>
1214 (ExprTup {
1215 args: elems.0,
1216 paren_token: elems.1,
1217 lone_comma: None, // TODO: parse this
1218 })
1219 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001220 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001221
Alex Crichton954046c2017-05-30 21:49:42 -07001222 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001223 named!(parse -> Self, do_parse!(
1224 if_: syn!(If) >>
1225 let_: syn!(Let) >>
1226 pat: syn!(Pat) >>
1227 eq: syn!(Eq) >>
1228 cond: expr_no_struct >>
1229 then_block: braces!(call!(Block::parse_within)) >>
1230 else_block: option!(else_block) >>
1231 (ExprIfLet {
1232 pat: Box::new(pat),
1233 let_token: let_,
1234 eq_token: eq,
1235 expr: Box::new(cond),
1236 if_true: Block {
1237 stmts: then_block.0,
1238 brace_token: then_block.1,
1239 },
1240 if_token: if_,
1241 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1242 if_false: else_block.map(|p| Box::new(p.1.into())),
1243 })
1244 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001245 }
1246
Alex Crichton954046c2017-05-30 21:49:42 -07001247 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001248 named!(parse -> Self, do_parse!(
1249 if_: syn!(If) >>
1250 cond: expr_no_struct >>
1251 then_block: braces!(call!(Block::parse_within)) >>
1252 else_block: option!(else_block) >>
1253 (ExprIf {
1254 cond: Box::new(cond),
1255 if_true: Block {
1256 stmts: then_block.0,
1257 brace_token: then_block.1,
1258 },
1259 if_token: if_,
1260 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1261 if_false: else_block.map(|p| Box::new(p.1.into())),
1262 })
1263 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001264 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001265
Alex Crichton954046c2017-05-30 21:49:42 -07001266 named!(else_block -> (Else, ExprKind), do_parse!(
1267 else_: syn!(Else) >>
1268 expr: alt!(
1269 syn!(ExprIf) => { ExprKind::If }
1270 |
1271 syn!(ExprIfLet) => { ExprKind::IfLet }
1272 |
1273 do_parse!(
1274 else_block: braces!(call!(Block::parse_within)) >>
1275 (ExprKind::Block(ExprBlock {
1276 unsafety: Unsafety::Normal,
1277 block: Block {
1278 stmts: else_block.0,
1279 brace_token: else_block.1,
1280 },
1281 }))
David Tolnay939766a2016-09-23 23:48:12 -07001282 )
Alex Crichton954046c2017-05-30 21:49:42 -07001283 ) >>
1284 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001285 ));
1286
David Tolnaybb6feae2016-10-02 21:25:20 -07001287
Alex Crichton954046c2017-05-30 21:49:42 -07001288 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001289 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001290 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001291 for_: syn!(For) >>
1292 pat: syn!(Pat) >>
1293 in_: syn!(In) >>
1294 expr: expr_no_struct >>
1295 loop_block: syn!(Block) >>
1296 (ExprForLoop {
1297 for_token: for_,
1298 in_token: in_,
1299 pat: Box::new(pat),
1300 expr: Box::new(expr),
1301 body: loop_block,
1302 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1303 label: lbl.map(|p| p.0),
1304 })
1305 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001306 }
Gregory Katze5f35682016-09-27 14:20:55 -04001307
Alex Crichton954046c2017-05-30 21:49:42 -07001308 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001309 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001310 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001311 loop_: syn!(Loop) >>
1312 loop_block: syn!(Block) >>
1313 (ExprLoop {
1314 loop_token: loop_,
1315 body: loop_block,
1316 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1317 label: lbl.map(|p| p.0),
1318 })
1319 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001320 }
1321
1322 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001323 named!(parse -> Self, do_parse!(
1324 match_: syn!(Match) >>
1325 obj: expr_no_struct >>
1326 res: braces!(do_parse!(
1327 mut arms: many0!(do_parse!(
1328 arm: syn!(Arm) >>
1329 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1330 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1331 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001332 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001333 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001334 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001335 arms.extend(last_arm);
1336 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001337 })
Michael Layzell92639a52017-06-01 00:07:44 -04001338 )) >>
1339 ({
1340 let (mut arms, brace) = res;
1341 ExprMatch {
1342 expr: Box::new(obj),
1343 match_token: match_,
1344 brace_token: brace,
1345 arms: {
1346 for arm in &mut arms {
1347 if arm_requires_comma(arm) {
1348 arm.comma = Some(tokens::Comma::default());
1349 }
1350 }
1351 arms
1352 },
1353 }
1354 })
1355 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001356 }
David Tolnay1978c672016-10-27 22:05:52 -07001357
Alex Crichton954046c2017-05-30 21:49:42 -07001358 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001359 named!(parse -> Self, do_parse!(
1360 do_: syn!(Do) >>
1361 catch_: syn!(Catch) >>
1362 catch_block: syn!(Block) >>
1363 (ExprCatch {
1364 block: catch_block,
1365 do_token: do_,
1366 catch_token: catch_,
1367 }.into())
1368 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001369 }
Arnavion02ef13f2017-04-25 00:54:31 -07001370
David Tolnay1978c672016-10-27 22:05:52 -07001371 fn arm_requires_comma(arm: &Arm) -> bool {
Alex Crichton62a0a592017-05-22 13:58:53 -07001372 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
David Tolnay1978c672016-10-27 22:05:52 -07001373 false
1374 } else {
1375 true
1376 }
1377 }
1378
Alex Crichton954046c2017-05-30 21:49:42 -07001379 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001380 named!(parse -> Self, do_parse!(
1381 attrs: many0!(call!(Attribute::parse_outer)) >>
1382 pats: call!(Delimited::parse_separated_nonempty) >>
1383 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1384 rocket: syn!(Rocket) >>
1385 body: alt!(
1386 map!(syn!(Block), |blk| {
1387 ExprKind::Block(ExprBlock {
1388 unsafety: Unsafety::Normal,
1389 block: blk,
1390 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001391 })
Michael Layzell92639a52017-06-01 00:07:44 -04001392 |
1393 syn!(Expr)
1394 ) >>
1395 (Arm {
1396 rocket_token: rocket,
1397 if_token: guard.as_ref().map(|p| If((p.0).0)),
1398 attrs: attrs,
1399 pats: pats,
1400 guard: guard.map(|p| Box::new(p.1)),
1401 body: Box::new(body),
1402 comma: None,
1403 })
1404 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001405 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001406
Michael Layzellb78f3b52017-06-04 19:03:03 -04001407 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001408 capture: syn!(CaptureBy) >>
1409 or1: syn!(Or) >>
1410 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1411 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001412 ret_and_body: alt!(
1413 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001414 arrow: syn!(RArrow) >>
1415 ty: syn!(Ty) >>
1416 body: syn!(Block) >>
1417 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001418 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001419 unsafety: Unsafety::Normal,
1420 block: body,
1421 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001422 )
1423 |
David Tolnay58af3552016-12-22 16:58:07 -05001424 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001425 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001426 (ExprClosure {
1427 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001428 or1_token: or1,
1429 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001430 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001431 inputs: inputs,
1432 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001433 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001434 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001435 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001436 generics: Generics::default(),
1437 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001438 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001439 body: Box::new(ret_and_body.1),
1440 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001441 ));
1442
Alex Crichton954046c2017-05-30 21:49:42 -07001443 named!(fn_arg -> FnArg, do_parse!(
1444 pat: syn!(Pat) >>
1445 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1446 ({
1447 let (colon, ty) = ty.unwrap_or_else(|| {
1448 (Colon::default(), TyInfer {
1449 underscore_token: Underscore::default(),
1450 }.into())
1451 });
1452 ArgCaptured {
1453 pat: pat,
1454 colon_token: colon,
1455 ty: ty,
1456 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001457 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001458 ));
1459
Alex Crichton954046c2017-05-30 21:49:42 -07001460 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001461 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001462 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001463 while_: syn!(While) >>
1464 cond: expr_no_struct >>
1465 while_block: syn!(Block) >>
1466 (ExprWhile {
1467 while_token: while_,
1468 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1469 cond: Box::new(cond),
1470 body: while_block,
1471 label: lbl.map(|p| p.0),
1472 })
1473 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001474 }
1475
1476 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001477 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001478 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001479 while_: syn!(While) >>
1480 let_: syn!(Let) >>
1481 pat: syn!(Pat) >>
1482 eq: syn!(Eq) >>
1483 value: expr_no_struct >>
1484 while_block: syn!(Block) >>
1485 (ExprWhileLet {
1486 eq_token: eq,
1487 let_token: let_,
1488 while_token: while_,
1489 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1490 pat: Box::new(pat),
1491 expr: Box::new(value),
1492 body: while_block,
1493 label: lbl.map(|p| p.0),
1494 })
1495 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001496 }
1497
1498 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001499 named!(parse -> Self, do_parse!(
1500 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001501 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001502 (ExprContinue {
1503 continue_token: cont,
1504 label: lbl,
1505 })
1506 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001507 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001508
Michael Layzellb78f3b52017-06-04 19:03:03 -04001509 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001510 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001511 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001512 // We can't allow blocks after a `break` expression when we wouldn't
1513 // allow structs, as this expression is ambiguous.
1514 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001515 (ExprBreak {
1516 label: lbl,
1517 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001518 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001519 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001520 ));
1521
Michael Layzellb78f3b52017-06-04 19:03:03 -04001522 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001523 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001524 // NOTE: return is greedy and eats blocks after it even when in a
1525 // position where structs are not allowed, such as in if statement
1526 // conditions. For example:
1527 //
1528 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001529 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001530 (ExprRet {
1531 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001532 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001533 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001534 ));
1535
Alex Crichton954046c2017-05-30 21:49:42 -07001536 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001537 named!(parse -> Self, do_parse!(
1538 path: syn!(Path) >>
1539 data: braces!(do_parse!(
1540 fields: call!(Delimited::parse_terminated) >>
1541 base: option!(
1542 cond!(fields.is_empty() || fields.trailing_delim(),
1543 do_parse!(
1544 dots: syn!(Dot2) >>
1545 base: syn!(Expr) >>
1546 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001547 )
Michael Layzell92639a52017-06-01 00:07:44 -04001548 )
1549 ) >>
1550 (fields, base)
1551 )) >>
1552 ({
1553 let ((fields, base), brace) = data;
1554 let (dots, rest) = match base.and_then(|b| b) {
1555 Some((dots, base)) => (Some(dots), Some(base)),
1556 None => (None, None),
1557 };
1558 ExprStruct {
1559 brace_token: brace,
1560 path: path,
1561 fields: fields,
1562 dot2_token: dots,
1563 rest: rest.map(Box::new),
1564 }
1565 })
1566 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001567 }
1568
1569 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001570 named!(parse -> Self, alt!(
1571 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001572 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001573 colon: syn!(Colon) >>
1574 value: syn!(Expr) >>
1575 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001576 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001577 expr: value,
1578 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001579 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001580 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001581 })
Michael Layzell92639a52017-06-01 00:07:44 -04001582 )
1583 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001584 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001585 ident: name.clone(),
1586 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1587 is_shorthand: true,
1588 attrs: Vec::new(),
1589 colon_token: None,
1590 })
1591 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001592 }
David Tolnay055a7042016-10-02 19:23:54 -07001593
Alex Crichton954046c2017-05-30 21:49:42 -07001594 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001595 named!(parse -> Self, do_parse!(
1596 data: brackets!(do_parse!(
1597 value: syn!(Expr) >>
1598 semi: syn!(Semi) >>
1599 times: syn!(Expr) >>
1600 (value, semi, times)
1601 )) >>
1602 (ExprRepeat {
1603 expr: Box::new((data.0).0),
1604 amt: Box::new((data.0).2),
1605 bracket_token: data.1,
1606 semi_token: (data.0).1,
1607 })
1608 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001609 }
David Tolnay055a7042016-10-02 19:23:54 -07001610
Alex Crichton954046c2017-05-30 21:49:42 -07001611 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001612 named!(parse -> Self, do_parse!(
1613 rules: syn!(Unsafety) >>
1614 b: syn!(Block) >>
1615 (ExprBlock {
1616 unsafety: rules,
1617 block: b,
1618 })
1619 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001620 }
David Tolnay89e05672016-10-02 14:39:42 -07001621
Michael Layzellb78f3b52017-06-04 19:03:03 -04001622 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001623 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001624 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001625 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001626 ));
1627
Alex Crichton954046c2017-05-30 21:49:42 -07001628 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001629 named!(parse -> Self, alt!(
1630 // Must come before Dot2
1631 syn!(Dot3) => { RangeLimits::Closed }
1632 |
1633 syn!(Dot2) => { RangeLimits::HalfOpen }
1634 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001635 }
David Tolnay438c9052016-10-07 23:24:48 -07001636
Alex Crichton954046c2017-05-30 21:49:42 -07001637 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001638 named!(parse -> Self, do_parse!(
1639 pair: qpath >>
1640 (ExprPath {
1641 qself: pair.0,
1642 path: pair.1,
1643 })
1644 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001645 }
David Tolnay42602292016-10-01 22:25:45 -07001646
Alex Crichton954046c2017-05-30 21:49:42 -07001647 named!(and_field -> (Ident, Dot),
1648 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001649
Alex Crichton954046c2017-05-30 21:49:42 -07001650 named!(and_tup_field -> (Lit, Dot),
1651 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001652
Alex Crichton954046c2017-05-30 21:49:42 -07001653 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001654
Alex Crichton954046c2017-05-30 21:49:42 -07001655 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001656 named!(parse -> Self, do_parse!(
1657 stmts: braces!(call!(Block::parse_within)) >>
1658 (Block {
1659 stmts: stmts.0,
1660 brace_token: stmts.1,
1661 })
1662 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001663 }
David Tolnay939766a2016-09-23 23:48:12 -07001664
Alex Crichton954046c2017-05-30 21:49:42 -07001665 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001666 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1667 many0!(syn!(Semi)) >>
1668 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1669 last: option!(syn!(Expr)) >>
1670 (match last {
1671 None => standalone,
1672 Some(last) => {
1673 standalone.push(Stmt::Expr(Box::new(last)));
1674 standalone
1675 }
1676 })
1677 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001678 }
1679
1680 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001681 named!(parse -> Self, alt!(
1682 stmt_mac
1683 |
1684 stmt_local
1685 |
1686 stmt_item
1687 |
Michael Layzell35418782017-06-07 09:20:25 -04001688 stmt_blockexpr
1689 |
Michael Layzell92639a52017-06-01 00:07:44 -04001690 stmt_expr
1691 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001692 }
David Tolnay939766a2016-09-23 23:48:12 -07001693
David Tolnay13b3d352016-10-03 00:31:15 -07001694 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001695 attrs: many0!(call!(Attribute::parse_outer)) >>
1696 what: syn!(Path) >>
1697 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001698 // Only parse braces here; paren and bracket will get parsed as
1699 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001700 data: braces!(syn!(TokenStream)) >>
1701 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001702 (Stmt::Mac(Box::new((
1703 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001704 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001705 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001706 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001707 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001708 span: ((data.1).0).0,
1709 kind: TokenKind::Sequence(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001710 })],
1711 },
Alex Crichton954046c2017-05-30 21:49:42 -07001712 match semi {
1713 Some(semi) => MacStmtStyle::Semicolon(semi),
1714 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001715 },
David Tolnayeea28d62016-10-25 20:44:08 -07001716 attrs,
1717 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001718 ));
1719
David Tolnay191e0582016-10-02 18:31:09 -07001720 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001721 attrs: many0!(call!(Attribute::parse_outer)) >>
1722 let_: syn!(Let) >>
1723 pat: syn!(Pat) >>
1724 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1725 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1726 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001727 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001728 let_token: let_,
1729 semi_token: semi,
1730 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1731 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001732 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001733 ty: ty.map(|p| Box::new(p.1)),
1734 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001735 attrs: attrs,
1736 })))
1737 ));
1738
Alex Crichton954046c2017-05-30 21:49:42 -07001739 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001740
Michael Layzell35418782017-06-07 09:20:25 -04001741 named!(stmt_blockexpr -> Stmt, do_parse!(
1742 attrs: many0!(call!(Attribute::parse_outer)) >>
1743 mut e: expr_nosemi >>
1744 // If the next token is a `.` or a `?` it is special-cased to parse as
1745 // an expression instead of a blockexpression.
1746 not!(syn!(Dot)) >>
1747 not!(syn!(Question)) >>
1748 semi: option!(syn!(Semi)) >>
1749 ({
1750 e.attrs = attrs;
1751 if let Some(semi) = semi {
1752 Stmt::Semi(Box::new(e), semi)
1753 } else {
1754 Stmt::Expr(Box::new(e))
1755 }
1756 })
1757 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001758
1759 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001760 attrs: many0!(call!(Attribute::parse_outer)) >>
1761 mut e: syn!(Expr) >>
Michael Layzell35418782017-06-07 09:20:25 -04001762 semi: syn!(Semi) >>
David Tolnay7184b132016-10-30 10:06:37 -07001763 ({
1764 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001765 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001766 })
David Tolnay939766a2016-09-23 23:48:12 -07001767 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001768
Alex Crichton954046c2017-05-30 21:49:42 -07001769 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001770 named!(parse -> Self, alt!(
1771 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1772 |
1773 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1774 |
1775 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1776 |
1777 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1778 |
1779 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1780 |
1781 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1782 |
1783 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1784 |
1785 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1786 |
1787 syn!(PatPath) => { Pat::Path }
1788 |
1789 syn!(PatTuple) => { Pat::Tuple }
1790 |
1791 syn!(PatRef) => { Pat::Ref }
1792 |
1793 syn!(PatSlice) => { Pat::Slice }
1794 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001795 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001796
Alex Crichton954046c2017-05-30 21:49:42 -07001797 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001798 named!(parse -> Self, map!(
1799 syn!(Underscore),
1800 |u| PatWild { underscore_token: u }
1801 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001802 }
David Tolnay84aa0752016-10-02 23:01:13 -07001803
Alex Crichton954046c2017-05-30 21:49:42 -07001804 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001805 named!(parse -> Self, do_parse!(
1806 boxed: syn!(Box_) >>
1807 pat: syn!(Pat) >>
1808 (PatBox {
1809 pat: Box::new(pat),
1810 box_token: boxed,
1811 })
1812 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001813 }
1814
1815 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001816 named!(parse -> Self, do_parse!(
1817 mode: option!(syn!(Ref)) >>
1818 mutability: syn!(Mutability) >>
1819 name: alt!(
1820 syn!(Ident)
1821 |
1822 syn!(Self_) => { Into::into }
1823 ) >>
1824 not!(syn!(Lt)) >>
1825 not!(syn!(Colon2)) >>
1826 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1827 (PatIdent {
1828 mode: match mode {
1829 Some(mode) => BindingMode::ByRef(mode, mutability),
1830 None => BindingMode::ByValue(mutability),
1831 },
1832 ident: name,
1833 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1834 subpat: subpat.map(|p| Box::new(p.1)),
1835 })
1836 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001837 }
1838
1839 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001840 named!(parse -> Self, do_parse!(
1841 path: syn!(Path) >>
1842 tuple: syn!(PatTuple) >>
1843 (PatTupleStruct {
1844 path: path,
1845 pat: tuple,
1846 })
1847 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001848 }
1849
1850 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001851 named!(parse -> Self, do_parse!(
1852 path: syn!(Path) >>
1853 data: braces!(do_parse!(
1854 fields: call!(Delimited::parse_terminated) >>
1855 base: option!(
1856 cond!(fields.is_empty() || fields.trailing_delim(),
1857 syn!(Dot2))
1858 ) >>
1859 (fields, base)
1860 )) >>
1861 (PatStruct {
1862 path: path,
1863 fields: (data.0).0,
1864 brace_token: data.1,
1865 dot2_token: (data.0).1.and_then(|m| m),
1866 })
1867 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001868 }
1869
1870 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04001871 named!(parse -> Self, alt!(
1872 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001873 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001874 colon: syn!(Colon) >>
1875 pat: syn!(Pat) >>
1876 (FieldPat {
1877 ident: ident,
1878 pat: Box::new(pat),
1879 is_shorthand: false,
1880 attrs: Vec::new(),
1881 colon_token: Some(colon),
1882 })
1883 )
1884 |
1885 do_parse!(
1886 boxed: option!(syn!(Box_)) >>
1887 mode: option!(syn!(Ref)) >>
1888 mutability: syn!(Mutability) >>
1889 ident: syn!(Ident) >>
1890 ({
1891 let mut pat: Pat = PatIdent {
1892 mode: if let Some(mode) = mode {
1893 BindingMode::ByRef(mode, mutability)
1894 } else {
1895 BindingMode::ByValue(mutability)
1896 },
1897 ident: ident.clone(),
1898 subpat: None,
1899 at_token: None,
1900 }.into();
1901 if let Some(boxed) = boxed {
1902 pat = PatBox {
1903 pat: Box::new(pat),
1904 box_token: boxed,
1905 }.into();
1906 }
1907 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07001908 ident: ident,
1909 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04001910 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07001911 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001912 colon_token: None,
1913 }
1914 })
1915 )
1916 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001917 }
1918
David Tolnay570695e2017-06-03 16:15:13 -07001919 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07001920 syn!(Ident)
1921 |
1922 do_parse!(
1923 lit: syn!(Lit) >>
1924 ({
David Tolnay570695e2017-06-03 16:15:13 -07001925 let s = lit.to_string();
1926 if s.parse::<usize>().is_ok() {
Alex Crichton954046c2017-05-30 21:49:42 -07001927 Ident::new(s.into(), lit.span)
1928 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04001929 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07001930 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07001931 })
1932 )
1933 ));
1934
Alex Crichton954046c2017-05-30 21:49:42 -07001935 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001936 named!(parse -> Self, map!(
1937 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07001938 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04001939 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001940 }
David Tolnay9636c052016-10-02 17:11:17 -07001941
Alex Crichton954046c2017-05-30 21:49:42 -07001942 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001943 named!(parse -> Self, do_parse!(
1944 data: parens!(do_parse!(
1945 elems: call!(Delimited::parse_terminated) >>
1946 dotdot: map!(cond!(
1947 elems.is_empty() || elems.trailing_delim(),
1948 option!(do_parse!(
1949 dots: syn!(Dot2) >>
1950 trailing: option!(syn!(Comma)) >>
1951 (dots, trailing)
1952 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07001953 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001954 rest: cond!(match dotdot {
1955 Some((_, Some(_))) => true,
1956 _ => false,
1957 },
1958 call!(Delimited::parse_terminated)) >>
1959 (elems, dotdot, rest)
1960 )) >>
1961 ({
1962 let ((mut elems, dotdot, rest), parens) = data;
1963 let (dotdot, trailing) = match dotdot {
1964 Some((a, b)) => (Some(a), Some(b)),
1965 None => (None, None),
1966 };
1967 PatTuple {
1968 paren_token: parens,
1969 dots_pos: dotdot.as_ref().map(|_| elems.len()),
1970 dot2_token: dotdot,
1971 comma_token: trailing.and_then(|b| b),
1972 pats: {
1973 if let Some(rest) = rest {
1974 for elem in rest {
1975 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07001976 }
Michael Layzell92639a52017-06-01 00:07:44 -04001977 }
1978 elems
1979 },
1980 }
1981 })
1982 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001983 }
David Tolnayfbb73232016-10-03 01:00:06 -07001984
Alex Crichton954046c2017-05-30 21:49:42 -07001985 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04001986 named!(parse -> Self, do_parse!(
1987 and: syn!(And) >>
1988 mutability: syn!(Mutability) >>
1989 pat: syn!(Pat) >>
1990 (PatRef {
1991 pat: Box::new(pat),
1992 mutbl: mutability,
1993 and_token: and,
1994 })
1995 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001996 }
David Tolnayffdb97f2016-10-03 01:28:33 -07001997
Alex Crichton954046c2017-05-30 21:49:42 -07001998 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04001999 named!(parse -> Self, do_parse!(
2000 lit: pat_lit_expr >>
2001 (if let ExprKind::Path(_) = lit.node {
2002 return parse_error(); // these need to be parsed by pat_path
2003 } else {
2004 PatLit {
2005 expr: Box::new(lit),
2006 }
2007 })
2008 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002009 }
David Tolnaye1310902016-10-29 23:40:00 -07002010
Alex Crichton954046c2017-05-30 21:49:42 -07002011 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002012 named!(parse -> Self, do_parse!(
2013 lo: pat_lit_expr >>
2014 limits: syn!(RangeLimits) >>
2015 hi: pat_lit_expr >>
2016 (PatRange {
2017 lo: Box::new(lo),
2018 hi: Box::new(hi),
2019 limits: limits,
2020 })
2021 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002022 }
David Tolnaye1310902016-10-29 23:40:00 -07002023
David Tolnay2cfddc62016-10-30 01:03:27 -07002024 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002025 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002026 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002027 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002028 |
Alex Crichton954046c2017-05-30 21:49:42 -07002029 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002030 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002031 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002032 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002033 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002034 expr: Box::new(v.into())
2035 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002036 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002037 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002038 })
2039 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002040
Alex Crichton954046c2017-05-30 21:49:42 -07002041 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002042 named!(parse -> Self, map!(
2043 brackets!(do_parse!(
2044 before: call!(Delimited::parse_terminated) >>
2045 middle: option!(do_parse!(
2046 dots: syn!(Dot2) >>
2047 trailing: option!(syn!(Comma)) >>
2048 (dots, trailing)
2049 )) >>
2050 after: cond!(
2051 match middle {
2052 Some((_, ref trailing)) => trailing.is_some(),
2053 _ => false,
2054 },
2055 call!(Delimited::parse_terminated)
2056 ) >>
2057 (before, middle, after)
2058 )),
2059 |((before, middle, after), brackets)| {
2060 let mut before: Delimited<Pat, tokens::Comma> = before;
2061 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2062 let middle: Option<(Dot2, Option<Comma>)> = middle;
2063 PatSlice {
2064 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2065 comma_token: middle.as_ref().and_then(|m| {
2066 m.1.as_ref().map(|m| Comma(m.0))
2067 }),
2068 bracket_token: brackets,
2069 middle: middle.and_then(|_| {
2070 if !before.is_empty() && !before.trailing_delim() {
2071 Some(Box::new(before.pop().unwrap().into_item()))
2072 } else {
2073 None
2074 }
2075 }),
2076 front: before,
2077 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002078 }
Alex Crichton954046c2017-05-30 21:49:42 -07002079 }
Michael Layzell92639a52017-06-01 00:07:44 -04002080 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002081 }
David Tolnay435a9a82016-10-29 13:47:20 -07002082
Alex Crichton954046c2017-05-30 21:49:42 -07002083 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002084 named!(parse -> Self, alt!(
2085 syn!(Move) => { CaptureBy::Value }
2086 |
2087 epsilon!() => { |_| CaptureBy::Ref }
2088 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002089 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002090}
2091
David Tolnayf4bbbd92016-09-23 14:41:55 -07002092#[cfg(feature = "printing")]
2093mod printing {
2094 use super::*;
David Tolnay13b3d352016-10-03 00:31:15 -07002095 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002096 use quote::{Tokens, ToTokens};
2097
2098 impl ToTokens for Expr {
2099 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002100 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002101 self.node.to_tokens(tokens)
2102 }
2103 }
2104
2105 impl ToTokens for ExprBox {
2106 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002107 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002108 self.expr.to_tokens(tokens);
2109 }
2110 }
2111
2112 impl ToTokens for ExprInPlace {
2113 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002114 match self.kind {
2115 InPlaceKind::Arrow(ref arrow) => {
2116 self.place.to_tokens(tokens);
2117 arrow.to_tokens(tokens);
2118 self.value.to_tokens(tokens);
2119 }
2120 InPlaceKind::In(ref _in) => {
2121 _in.to_tokens(tokens);
2122 self.place.to_tokens(tokens);
2123 self.value.to_tokens(tokens);
2124 }
2125 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002126 }
2127 }
2128
2129 impl ToTokens for ExprArray {
2130 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002131 self.bracket_token.surround(tokens, |tokens| {
2132 self.exprs.to_tokens(tokens);
2133 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002134 }
2135 }
2136
2137 impl ToTokens for ExprCall {
2138 fn to_tokens(&self, tokens: &mut Tokens) {
2139 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002140 self.paren_token.surround(tokens, |tokens| {
2141 self.args.to_tokens(tokens);
2142 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002143 }
2144 }
2145
2146 impl ToTokens for ExprMethodCall {
2147 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002148 self.expr.to_tokens(tokens);
2149 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002150 self.method.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002151 self.colon2_token.to_tokens(tokens);
2152 self.lt_token.to_tokens(tokens);
2153 self.typarams.to_tokens(tokens);
2154 self.gt_token.to_tokens(tokens);
2155 self.paren_token.surround(tokens, |tokens| {
2156 self.args.to_tokens(tokens);
2157 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002158 }
2159 }
2160
2161 impl ToTokens for ExprTup {
2162 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002163 self.paren_token.surround(tokens, |tokens| {
2164 self.args.to_tokens(tokens);
2165 self.lone_comma.to_tokens(tokens);
2166 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002167 }
2168 }
2169
2170 impl ToTokens for ExprBinary {
2171 fn to_tokens(&self, tokens: &mut Tokens) {
2172 self.left.to_tokens(tokens);
2173 self.op.to_tokens(tokens);
2174 self.right.to_tokens(tokens);
2175 }
2176 }
2177
2178 impl ToTokens for ExprUnary {
2179 fn to_tokens(&self, tokens: &mut Tokens) {
2180 self.op.to_tokens(tokens);
2181 self.expr.to_tokens(tokens);
2182 }
2183 }
2184
2185 impl ToTokens for ExprCast {
2186 fn to_tokens(&self, tokens: &mut Tokens) {
2187 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002188 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002189 self.ty.to_tokens(tokens);
2190 }
2191 }
2192
2193 impl ToTokens for ExprType {
2194 fn to_tokens(&self, tokens: &mut Tokens) {
2195 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002196 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002197 self.ty.to_tokens(tokens);
2198 }
2199 }
2200
2201 impl ToTokens for ExprIf {
2202 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002203 self.if_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002204 self.cond.to_tokens(tokens);
2205 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002206 self.else_token.to_tokens(tokens);
2207 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002208 }
2209 }
2210
2211 impl ToTokens for ExprIfLet {
2212 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002213 self.if_token.to_tokens(tokens);
2214 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002215 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002216 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002217 self.expr.to_tokens(tokens);
2218 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002219 self.else_token.to_tokens(tokens);
2220 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002221 }
2222 }
2223
2224 impl ToTokens for ExprWhile {
2225 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002226 self.label.to_tokens(tokens);
2227 self.colon_token.to_tokens(tokens);
2228 self.while_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002229 self.cond.to_tokens(tokens);
2230 self.body.to_tokens(tokens);
2231 }
2232 }
2233
2234 impl ToTokens for ExprWhileLet {
2235 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002236 self.label.to_tokens(tokens);
2237 self.colon_token.to_tokens(tokens);
2238 self.while_token.to_tokens(tokens);
2239 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002240 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002241 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002242 self.expr.to_tokens(tokens);
2243 self.body.to_tokens(tokens);
2244 }
2245 }
2246
2247 impl ToTokens for ExprForLoop {
2248 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002249 self.label.to_tokens(tokens);
2250 self.colon_token.to_tokens(tokens);
2251 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002252 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002253 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002254 self.expr.to_tokens(tokens);
2255 self.body.to_tokens(tokens);
2256 }
2257 }
2258
2259 impl ToTokens for ExprLoop {
2260 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002261 self.label.to_tokens(tokens);
2262 self.colon_token.to_tokens(tokens);
2263 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002264 self.body.to_tokens(tokens);
2265 }
2266 }
2267
2268 impl ToTokens for ExprMatch {
2269 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002270 self.match_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002271 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002272 self.brace_token.surround(tokens, |tokens| {
2273 tokens.append_all(&self.arms);
2274 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002275 }
2276 }
2277
2278 impl ToTokens for ExprCatch {
2279 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002280 self.do_token.to_tokens(tokens);
2281 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002282 self.block.to_tokens(tokens);
2283 }
2284 }
2285
2286 impl ToTokens for ExprClosure {
2287 fn to_tokens(&self, tokens: &mut Tokens) {
2288 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002289 self.or1_token.to_tokens(tokens);
2290 for item in self.decl.inputs.iter() {
2291 match **item.item() {
2292 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002293 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002294 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002295 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002296 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002297 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002298 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002299 self.or2_token.to_tokens(tokens);
2300 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002301 self.body.to_tokens(tokens);
2302 }
2303 }
2304
2305 impl ToTokens for ExprBlock {
2306 fn to_tokens(&self, tokens: &mut Tokens) {
2307 self.unsafety.to_tokens(tokens);
2308 self.block.to_tokens(tokens);
2309 }
2310 }
2311
2312 impl ToTokens for ExprAssign {
2313 fn to_tokens(&self, tokens: &mut Tokens) {
2314 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002315 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002316 self.right.to_tokens(tokens);
2317 }
2318 }
2319
2320 impl ToTokens for ExprAssignOp {
2321 fn to_tokens(&self, tokens: &mut Tokens) {
2322 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002323 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002324 self.right.to_tokens(tokens);
2325 }
2326 }
2327
2328 impl ToTokens for ExprField {
2329 fn to_tokens(&self, tokens: &mut Tokens) {
2330 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002331 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002332 self.field.to_tokens(tokens);
2333 }
2334 }
2335
2336 impl ToTokens for ExprTupField {
2337 fn to_tokens(&self, tokens: &mut Tokens) {
2338 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002339 self.dot_token.to_tokens(tokens);
2340 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002341 }
2342 }
2343
2344 impl ToTokens for ExprIndex {
2345 fn to_tokens(&self, tokens: &mut Tokens) {
2346 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002347 self.bracket_token.surround(tokens, |tokens| {
2348 self.index.to_tokens(tokens);
2349 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002350 }
2351 }
2352
2353 impl ToTokens for ExprRange {
2354 fn to_tokens(&self, tokens: &mut Tokens) {
2355 self.from.to_tokens(tokens);
2356 self.limits.to_tokens(tokens);
2357 self.to.to_tokens(tokens);
2358 }
2359 }
2360
2361 impl ToTokens for ExprPath {
2362 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002363 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002364 }
2365 }
2366
2367 impl ToTokens for ExprAddrOf {
2368 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002369 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002370 self.mutbl.to_tokens(tokens);
2371 self.expr.to_tokens(tokens);
2372 }
2373 }
2374
2375 impl ToTokens for ExprBreak {
2376 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002377 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002378 self.label.to_tokens(tokens);
2379 self.expr.to_tokens(tokens);
2380 }
2381 }
2382
2383 impl ToTokens for ExprContinue {
2384 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002385 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002386 self.label.to_tokens(tokens);
2387 }
2388 }
2389
2390 impl ToTokens for ExprRet {
2391 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002392 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002393 self.expr.to_tokens(tokens);
2394 }
2395 }
2396
2397 impl ToTokens for ExprStruct {
2398 fn to_tokens(&self, tokens: &mut Tokens) {
2399 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002400 self.brace_token.surround(tokens, |tokens| {
2401 self.fields.to_tokens(tokens);
2402 self.dot2_token.to_tokens(tokens);
2403 self.rest.to_tokens(tokens);
2404 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002405 }
2406 }
2407
2408 impl ToTokens for ExprRepeat {
2409 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002410 self.bracket_token.surround(tokens, |tokens| {
2411 self.expr.to_tokens(tokens);
2412 self.semi_token.to_tokens(tokens);
2413 self.amt.to_tokens(tokens);
2414 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002415 }
2416 }
2417
Michael Layzell93c36282017-06-04 20:43:14 -04002418 impl ToTokens for ExprGroup {
2419 fn to_tokens(&self, tokens: &mut Tokens) {
2420 self.group_token.surround(tokens, |tokens| {
2421 self.expr.to_tokens(tokens);
2422 });
2423 }
2424 }
2425
Alex Crichton62a0a592017-05-22 13:58:53 -07002426 impl ToTokens for ExprParen {
2427 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002428 self.paren_token.surround(tokens, |tokens| {
2429 self.expr.to_tokens(tokens);
2430 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002431 }
2432 }
2433
2434 impl ToTokens for ExprTry {
2435 fn to_tokens(&self, tokens: &mut Tokens) {
2436 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002437 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002438 }
2439 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002440
David Tolnay055a7042016-10-02 19:23:54 -07002441 impl ToTokens for FieldValue {
2442 fn to_tokens(&self, tokens: &mut Tokens) {
2443 self.ident.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002444 if !self.is_shorthand {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002445 self.colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002446 self.expr.to_tokens(tokens);
2447 }
David Tolnay055a7042016-10-02 19:23:54 -07002448 }
2449 }
2450
David Tolnayb4ad3b52016-10-01 21:58:13 -07002451 impl ToTokens for Arm {
2452 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002453 tokens.append_all(&self.attrs);
2454 self.pats.to_tokens(tokens);
2455 self.if_token.to_tokens(tokens);
2456 self.guard.to_tokens(tokens);
2457 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002458 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002459 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002460 }
2461 }
2462
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002463 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002464 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002465 self.underscore_token.to_tokens(tokens);
2466 }
2467 }
2468
2469 impl ToTokens for PatIdent {
2470 fn to_tokens(&self, tokens: &mut Tokens) {
2471 self.mode.to_tokens(tokens);
2472 self.ident.to_tokens(tokens);
2473 self.at_token.to_tokens(tokens);
2474 self.subpat.to_tokens(tokens);
2475 }
2476 }
2477
2478 impl ToTokens for PatStruct {
2479 fn to_tokens(&self, tokens: &mut Tokens) {
2480 self.path.to_tokens(tokens);
2481 self.brace_token.surround(tokens, |tokens| {
2482 self.fields.to_tokens(tokens);
2483 self.dot2_token.to_tokens(tokens);
2484 });
2485 }
2486 }
2487
2488 impl ToTokens for PatTupleStruct {
2489 fn to_tokens(&self, tokens: &mut Tokens) {
2490 self.path.to_tokens(tokens);
2491 self.pat.to_tokens(tokens);
2492 }
2493 }
2494
2495 impl ToTokens for PatPath {
2496 fn to_tokens(&self, tokens: &mut Tokens) {
2497 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2498 }
2499 }
2500
2501 impl ToTokens for PatTuple {
2502 fn to_tokens(&self, tokens: &mut Tokens) {
2503 self.paren_token.surround(tokens, |tokens| {
2504 for (i, token) in self.pats.iter().enumerate() {
2505 if Some(i) == self.dots_pos {
2506 self.dot2_token.to_tokens(tokens);
2507 self.comma_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002508 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002509 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002510 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002511
2512 if Some(self.pats.len()) == self.dots_pos {
2513 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002514 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002515 });
2516 }
2517 }
2518
2519 impl ToTokens for PatBox {
2520 fn to_tokens(&self, tokens: &mut Tokens) {
2521 self.box_token.to_tokens(tokens);
2522 self.pat.to_tokens(tokens);
2523 }
2524 }
2525
2526 impl ToTokens for PatRef {
2527 fn to_tokens(&self, tokens: &mut Tokens) {
2528 self.and_token.to_tokens(tokens);
2529 self.mutbl.to_tokens(tokens);
2530 self.pat.to_tokens(tokens);
2531 }
2532 }
2533
2534 impl ToTokens for PatLit {
2535 fn to_tokens(&self, tokens: &mut Tokens) {
2536 self.expr.to_tokens(tokens);
2537 }
2538 }
2539
2540 impl ToTokens for PatRange {
2541 fn to_tokens(&self, tokens: &mut Tokens) {
2542 self.lo.to_tokens(tokens);
2543 self.limits.to_tokens(tokens);
2544 self.hi.to_tokens(tokens);
2545 }
2546 }
2547
2548 impl ToTokens for PatSlice {
2549 fn to_tokens(&self, tokens: &mut Tokens) {
2550 self.bracket_token.surround(tokens, |tokens| {
2551 self.front.to_tokens(tokens);
2552 self.middle.to_tokens(tokens);
2553 self.dot2_token.to_tokens(tokens);
2554 self.comma_token.to_tokens(tokens);
2555 self.back.to_tokens(tokens);
2556 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002557 }
2558 }
2559
Arnavion1992e2f2017-04-25 01:47:46 -07002560 impl ToTokens for RangeLimits {
2561 fn to_tokens(&self, tokens: &mut Tokens) {
2562 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002563 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2564 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002565 }
2566 }
2567 }
2568
David Tolnay8d9e81a2016-10-03 22:36:32 -07002569 impl ToTokens for FieldPat {
2570 fn to_tokens(&self, tokens: &mut Tokens) {
2571 if !self.is_shorthand {
2572 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002573 self.colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002574 }
2575 self.pat.to_tokens(tokens);
2576 }
2577 }
2578
David Tolnayb4ad3b52016-10-01 21:58:13 -07002579 impl ToTokens for BindingMode {
2580 fn to_tokens(&self, tokens: &mut Tokens) {
2581 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002582 BindingMode::ByRef(ref t, ref m) => {
2583 t.to_tokens(tokens);
2584 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002585 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002586 BindingMode::ByValue(ref m) => {
2587 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002588 }
2589 }
2590 }
2591 }
David Tolnay42602292016-10-01 22:25:45 -07002592
David Tolnay89e05672016-10-02 14:39:42 -07002593 impl ToTokens for CaptureBy {
2594 fn to_tokens(&self, tokens: &mut Tokens) {
2595 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002596 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002597 CaptureBy::Ref => {
2598 // nothing
2599 }
David Tolnay89e05672016-10-02 14:39:42 -07002600 }
2601 }
2602 }
2603
David Tolnay42602292016-10-01 22:25:45 -07002604 impl ToTokens for Block {
2605 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002606 self.brace_token.surround(tokens, |tokens| {
2607 tokens.append_all(&self.stmts);
2608 });
David Tolnay42602292016-10-01 22:25:45 -07002609 }
2610 }
2611
David Tolnay42602292016-10-01 22:25:45 -07002612 impl ToTokens for Stmt {
2613 fn to_tokens(&self, tokens: &mut Tokens) {
2614 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002615 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002616 Stmt::Item(ref item) => item.to_tokens(tokens),
2617 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002618 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002619 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002620 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002621 }
David Tolnay13b3d352016-10-03 00:31:15 -07002622 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002623 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002624 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002625 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002626 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002627 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002628 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2629 // no semicolon
2630 }
David Tolnay13b3d352016-10-03 00:31:15 -07002631 }
2632 }
David Tolnay42602292016-10-01 22:25:45 -07002633 }
2634 }
2635 }
David Tolnay191e0582016-10-02 18:31:09 -07002636
2637 impl ToTokens for Local {
2638 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002639 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002640 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002641 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002642 self.colon_token.to_tokens(tokens);
2643 self.ty.to_tokens(tokens);
2644 self.eq_token.to_tokens(tokens);
2645 self.init.to_tokens(tokens);
2646 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002647 }
2648 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002649}