blob: 3271431f1bf432714e292fe4440342e923f73553 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080029 pub box_token: Token![box],
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080041 pub exprs: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070042 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080048 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070049 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
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])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -080063 pub typarams: Delimited<Ty, Token![,]>,
64 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080066 pub dot_token: Token![.],
67 pub lt_token: Option<Token![<]>,
68 pub colon2_token: Option<Token![::]>,
69 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
Michael Layzell734adb42017-06-07 16:58:31 -040073 pub Tup(ExprTup #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080074 pub args: Delimited<Expr, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080076 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080098 pub as_token: Token![as],
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>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800105 pub colon_token: Token![:],
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 }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800116 pub if_token: Token![if],
117 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800130 pub if_token: Token![if],
131 pub let_token: Token![let],
132 pub eq_token: Token![=],
133 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800143 pub colon_token: Option<Token![:]>,
144 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800157 pub colon_token: Option<Token![:]>,
158 pub while_token: Token![while],
159 pub let_token: Token![let],
160 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800173 pub for_token: Token![for],
174 pub colon_token: Option<Token![:]>,
175 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800184 pub loop_token: Token![loop],
185 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800190 pub match_token: Token![match],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700191 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800201 pub or1_token: Token![|],
202 pub or2_token: Token![|],
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// A block (`{ ... }` or `unsafe { ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400206 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 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()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800215 pub eq_token: Token![=],
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`.
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 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`)
Michael Layzell734adb42017-06-07 16:58:31 -0400228 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 pub expr: Box<Expr>,
230 pub field: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800231 pub dot_token: Token![.],
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`.
Michael Layzell734adb42017-06-07 16:58:31 -0400237 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700239 pub field: Lit,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800240 pub dot_token: Token![.],
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`)
Michael Layzell734adb42017-06-07 16:58:31 -0400251 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 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`)
Michael Layzell734adb42017-06-07 16:58:31 -0400268 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800269 pub and_token: Token![&],
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
Michael Layzell734adb42017-06-07 16:58:31 -0400275 pub Break(ExprBreak #full {
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>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800278 pub break_token: Token![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
Michael Layzell734adb42017-06-07 16:58:31 -0400282 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700283 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800284 pub continue_token: Token![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
Michael Layzell734adb42017-06-07 16:58:31 -0400288 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800290 pub return_token: Token![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
David Tolnaydecf28d2017-11-11 11:56:45 -0800294 pub Macro(Macro),
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>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400300 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800302 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800304 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700305 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.
Michael Layzell734adb42017-06-07 16:58:31 -0400312 pub Repeat(ExprRepeat #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 pub bracket_token: tokens::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800314 pub semi_token: Token![;],
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?`
Michael Layzell734adb42017-06-07 16:58:31 -0400336 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800338 pub question_token: Token![?],
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 }`
Michael Layzell734adb42017-06-07 16:58:31 -0400344 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800345 pub do_token: Token![do],
346 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700347 pub block: Block,
348 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700349
350 /// A yield expression.
351 ///
352 /// E.g. `yield expr`
353 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800354 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700355 pub expr: Option<Box<Expr>>,
356 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700358}
359
Michael Layzell734adb42017-06-07 16:58:31 -0400360#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700361ast_struct! {
362 /// A field-value pair in a struct literal.
363 pub struct FieldValue {
364 /// Name of the field.
365 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500366
Alex Crichton62a0a592017-05-22 13:58:53 -0700367 /// Value of the field.
368 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500369
Alex Crichton62a0a592017-05-22 13:58:53 -0700370 /// Whether this is a shorthand field, e.g. `Struct { x }`
371 /// instead of `Struct { x: x }`.
372 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500373
Alex Crichton62a0a592017-05-22 13:58:53 -0700374 /// Attributes tagged on the field.
375 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700376
David Tolnayf8db7ba2017-11-11 22:52:16 -0800377 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700378 }
David Tolnay055a7042016-10-02 19:23:54 -0700379}
380
Michael Layzell734adb42017-06-07 16:58:31 -0400381#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700382ast_struct! {
383 /// A Block (`{ .. }`).
384 ///
385 /// E.g. `{ .. }` as in `fn foo() { .. }`
386 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700387 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700388 /// Statements in a block
389 pub stmts: Vec<Stmt>,
390 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391}
392
Michael Layzell734adb42017-06-07 16:58:31 -0400393#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700394ast_enum! {
395 /// A statement, usually ending in a semicolon.
396 pub enum Stmt {
397 /// A local (let) binding.
398 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700399
Alex Crichton62a0a592017-05-22 13:58:53 -0700400 /// An item definition.
401 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700402
Alex Crichton62a0a592017-05-22 13:58:53 -0700403 /// Expr without trailing semicolon.
404 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700405
Alex Crichton62a0a592017-05-22 13:58:53 -0700406 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800407 Semi(Box<Expr>, Token![;]),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700408
Alex Crichton62a0a592017-05-22 13:58:53 -0700409 /// Macro invocation.
David Tolnaydecf28d2017-11-11 11:56:45 -0800410 Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700412}
413
Michael Layzell734adb42017-06-07 16:58:31 -0400414#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700415ast_enum! {
416 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700417 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 pub enum MacStmtStyle {
419 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
420 /// `foo!(...);`, `foo![...];`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800421 Semicolon(Token![;]),
Clar Charrd22b5702017-03-10 15:24:56 -0500422
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 /// The macro statement had braces; e.g. foo! { ... }
424 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500425
Alex Crichton62a0a592017-05-22 13:58:53 -0700426 /// The macro statement had parentheses or brackets and no semicolon; e.g.
427 /// `foo!(...)`. All of these will end up being converted into macro
428 /// expressions.
429 NoBraces,
430 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700431}
432
Michael Layzell734adb42017-06-07 16:58:31 -0400433#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700434ast_struct! {
435 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
436 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800437 pub let_token: Token![let],
438 pub colon_token: Option<Token![:]>,
439 pub eq_token: Option<Token![=]>,
440 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 pub pat: Box<Pat>,
443 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Initializer expression to set the value, if any
446 pub init: Option<Box<Expr>>,
447 pub attrs: Vec<Attribute>,
448 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700449}
450
Michael Layzell734adb42017-06-07 16:58:31 -0400451#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700452ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700453 // Clippy false positive
454 // https://github.com/Manishearth/rust-clippy/issues/1241
455 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
456 pub enum Pat {
457 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800459 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700460 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
463 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
464 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
465 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700466 pub Ident(PatIdent {
467 pub mode: BindingMode,
468 pub ident: Ident,
469 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800470 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700471 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700472
Alex Crichton62a0a592017-05-22 13:58:53 -0700473 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
474 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 pub Struct(PatStruct {
476 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800477 pub fields: Delimited<FieldPat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700478 pub brace_token: tokens::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800479 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700480 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
483 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
484 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 pub TupleStruct(PatTupleStruct {
486 pub path: Path,
487 pub pat: PatTuple,
488 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A possibly qualified path pattern.
491 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
492 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
493 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 pub Path(PatPath {
495 pub qself: Option<QSelf>,
496 pub path: Path,
497 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700498
Alex Crichton62a0a592017-05-22 13:58:53 -0700499 /// A tuple pattern `(a, b)`.
500 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
501 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800503 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700504 pub dots_pos: Option<usize>,
505 pub paren_token: tokens::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800506 pub dot2_token: Option<Token![..]>,
507 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700508 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700509 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700510 pub Box(PatBox {
511 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800512 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Ref(PatRef {
516 pub pat: Box<Pat>,
517 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800518 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700519 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700520 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 pub Lit(PatLit {
522 pub expr: Box<Expr>,
523 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700524 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub Range(PatRange {
526 pub lo: Box<Expr>,
527 pub hi: Box<Expr>,
528 pub limits: RangeLimits,
529 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400530 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800532 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700533 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800534 pub back: Delimited<Pat, Token![,]>,
535 pub dot2_token: Option<Token![..]>,
536 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700537 pub bracket_token: tokens::Bracket,
538 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800540 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700541 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700542}
543
Michael Layzell734adb42017-06-07 16:58:31 -0400544#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700545ast_struct! {
546 /// An arm of a 'match'.
547 ///
548 /// E.g. `0...10 => { println!("match!") }` as in
549 ///
550 /// ```rust,ignore
551 /// match n {
552 /// 0...10 => { println!("match!") },
553 /// // ..
554 /// }
555 /// ```
556 pub struct Arm {
557 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800558 pub pats: Delimited<Pat, Token![|]>,
559 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800561 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800563 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700565}
566
Michael Layzell734adb42017-06-07 16:58:31 -0400567#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700568ast_enum! {
569 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700570 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800572 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 Ref,
574 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700575}
576
Michael Layzell734adb42017-06-07 16:58:31 -0400577#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700578ast_enum! {
579 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700580 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub enum RangeLimits {
582 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800583 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 /// Inclusive at the beginning and end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800585 Closed(Token![...]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587}
588
Michael Layzell734adb42017-06-07 16:58:31 -0400589#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700590ast_struct! {
591 /// A single field in a struct pattern
592 ///
593 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
594 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
595 /// except `is_shorthand` is true
596 pub struct FieldPat {
597 /// The identifier for the field
598 pub ident: Ident,
599 /// The pattern the field is destructured to
600 pub pat: Box<Pat>,
601 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800602 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 pub attrs: Vec<Attribute>,
604 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700605}
606
Michael Layzell734adb42017-06-07 16:58:31 -0400607#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700608ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700609 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800611 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700612 ByValue(Mutability),
613 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700614}
615
Michael Layzell734adb42017-06-07 16:58:31 -0400616#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400617ast_enum! {
618 #[cfg_attr(feature = "clone-impls", derive(Copy))]
619 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800620 Arrow(Token![<-]),
621 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400622 }
623}
624
Michael Layzell3936ceb2017-07-08 00:28:36 -0400625#[cfg(any(feature = "parsing", feature = "printing"))]
626#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700627fn arm_expr_requires_comma(expr: &Expr) -> bool {
628 // see https://github.com/rust-lang/rust/blob/eb8f2586e
629 // /src/libsyntax/parse/classify.rs#L17-L37
630 match expr.node {
631 ExprKind::Block(..) |
632 ExprKind::If(..) |
633 ExprKind::IfLet(..) |
634 ExprKind::Match(..) |
635 ExprKind::While(..) |
636 ExprKind::WhileLet(..) |
637 ExprKind::Loop(..) |
638 ExprKind::ForLoop(..) |
639 ExprKind::Catch(..) => false,
640 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400641 }
642}
643
David Tolnayb9c8e322016-09-23 20:48:37 -0700644#[cfg(feature = "parsing")]
645pub mod parsing {
646 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700647 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700648
Michael Layzell734adb42017-06-07 16:58:31 -0400649 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700650 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400651 use synom::{PResult, Cursor, Synom};
652 #[cfg(feature = "full")]
653 use synom::parse_error;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700654
Michael Layzellb78f3b52017-06-04 19:03:03 -0400655 /// When we're parsing expressions which occur before blocks, like in
656 /// an if statement's condition, we cannot parse a struct literal.
657 ///
658 /// Struct literals are ambiguous in certain positions
659 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700660 macro_rules! ambiguous_expr {
661 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700662 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700663 };
664 }
665
Michael Layzellb78f3b52017-06-04 19:03:03 -0400666 /// When we are parsing an optional suffix expression, we cannot allow
667 /// blocks if structs are not allowed.
668 ///
669 /// Example:
670 /// ```ignore
671 /// if break { } { }
672 /// // is ambiguous between:
673 /// if (break { }) { }
674 /// // - or -
675 /// if (break) { } { }
676 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400677 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400678 macro_rules! opt_ambiguous_expr {
679 ($i:expr, $allow_struct:ident) => {
680 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
681 };
682 }
683
Alex Crichton954046c2017-05-30 21:49:42 -0700684 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400685 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700686
687 fn description() -> Option<&'static str> {
688 Some("expression")
689 }
690 }
691
Michael Layzell734adb42017-06-07 16:58:31 -0400692 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700693 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
694
Michael Layzellb78f3b52017-06-04 19:03:03 -0400695 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400696 #[cfg(feature = "full")]
697 fn ambiguous_expr(i: Cursor,
698 allow_struct: bool,
699 allow_block: bool)
700 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400701 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700702 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400703 call!(assign_expr, allow_struct, allow_block),
704 ExprKind::into
705 )
706 }
707
Michael Layzell734adb42017-06-07 16:58:31 -0400708 #[cfg(not(feature = "full"))]
709 fn ambiguous_expr(i: Cursor,
710 allow_struct: bool,
711 allow_block: bool)
712 -> PResult<Expr> {
713 map!(
714 i,
715 // NOTE: We intentionally skip assign_expr, placement_expr, and
716 // range_expr, as they are not parsed in non-full mode.
717 call!(or_expr, allow_struct, allow_block),
718 ExprKind::into
719 )
720 }
721
Michael Layzellb78f3b52017-06-04 19:03:03 -0400722 /// Parse a left-associative binary operator.
723 macro_rules! binop {
724 (
725 $name: ident,
726 $next: ident,
727 $submac: ident!( $($args:tt)* )
728 ) => {
729 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
730 mut e: call!($next, allow_struct, allow_block) >>
731 many0!(do_parse!(
732 op: $submac!($($args)*) >>
733 rhs: call!($next, allow_struct, true) >>
734 ({
735 e = ExprBinary {
736 left: Box::new(e.into()),
737 op: op,
738 right: Box::new(rhs.into()),
739 }.into();
740 })
741 )) >>
742 (e)
743 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700744 }
David Tolnay54e854d2016-10-24 12:03:30 -0700745 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700746
Michael Layzellb78f3b52017-06-04 19:03:03 -0400747 /// ```ignore
748 /// <placement> = <placement> ..
749 /// <placement> += <placement> ..
750 /// <placement> -= <placement> ..
751 /// <placement> *= <placement> ..
752 /// <placement> /= <placement> ..
753 /// <placement> %= <placement> ..
754 /// <placement> ^= <placement> ..
755 /// <placement> &= <placement> ..
756 /// <placement> |= <placement> ..
757 /// <placement> <<= <placement> ..
758 /// <placement> >>= <placement> ..
759 /// ```
760 ///
761 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400762 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400763 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
764 mut e: call!(placement_expr, allow_struct, allow_block) >>
765 alt!(
766 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800767 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400768 // Recurse into self to parse right-associative operator.
769 rhs: call!(assign_expr, allow_struct, true) >>
770 ({
771 e = ExprAssign {
772 left: Box::new(e.into()),
773 eq_token: eq,
774 right: Box::new(rhs.into()),
775 }.into();
776 })
777 )
778 |
779 do_parse!(
780 op: call!(BinOp::parse_assign_op) >>
781 // Recurse into self to parse right-associative operator.
782 rhs: call!(assign_expr, allow_struct, true) >>
783 ({
784 e = ExprAssignOp {
785 left: Box::new(e.into()),
786 op: op,
787 right: Box::new(rhs.into()),
788 }.into();
789 })
790 )
791 |
792 epsilon!()
793 ) >>
794 (e)
795 ));
796
797 /// ```ignore
798 /// <range> <- <range> ..
799 /// ```
800 ///
801 /// NOTE: The `in place { expr }` version of this syntax is parsed in
802 /// `atom_expr`, not here.
803 ///
804 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400805 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400806 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
807 mut e: call!(range_expr, allow_struct, allow_block) >>
808 alt!(
809 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800810 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400811 // Recurse into self to parse right-associative operator.
812 rhs: call!(placement_expr, allow_struct, true) >>
813 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400814 e = ExprInPlace {
815 // op: BinOp::Place(larrow),
816 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400817 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400818 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400819 }.into();
820 })
821 )
822 |
823 epsilon!()
824 ) >>
825 (e)
826 ));
827
828 /// ```ignore
829 /// <or> ... <or> ..
830 /// <or> .. <or> ..
831 /// <or> ..
832 /// ```
833 ///
834 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
835 /// rules are for parsing these expressions are, but this is not correct.
836 /// For example, `a .. b .. c` is not a legal expression. It should not
837 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
838 ///
839 /// NOTE: The form of ranges which don't include a preceding expression are
840 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400841 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400842 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
843 mut e: call!(or_expr, allow_struct, allow_block) >>
844 many0!(do_parse!(
845 limits: syn!(RangeLimits) >>
846 // We don't want to allow blocks here if we don't allow structs. See
847 // the reasoning for `opt_ambiguous_expr!` above.
848 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
849 ({
850 e = ExprRange {
851 from: Some(Box::new(e.into())),
852 limits: limits,
853 to: hi.map(|e| Box::new(e.into())),
854 }.into();
855 })
856 )) >>
857 (e)
858 ));
859
860 /// ```ignore
861 /// <and> || <and> ...
862 /// ```
David Tolnayf8db7ba2017-11-11 22:52:16 -0800863 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400864
865 /// ```ignore
866 /// <compare> && <compare> ...
867 /// ```
David Tolnayf8db7ba2017-11-11 22:52:16 -0800868 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400869
870 /// ```ignore
871 /// <bitor> == <bitor> ...
872 /// <bitor> != <bitor> ...
873 /// <bitor> >= <bitor> ...
874 /// <bitor> <= <bitor> ...
875 /// <bitor> > <bitor> ...
876 /// <bitor> < <bitor> ...
877 /// ```
878 ///
879 /// NOTE: This operator appears to be parsed as left-associative, but errors
880 /// if it is used in a non-associative manner.
881 binop!(compare_expr, bitor_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800882 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400883 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800884 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400885 |
886 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800887 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400888 |
889 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800890 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400891 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400892 do_parse!(
893 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800894 not!(punct!(<-)) >>
895 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400896 (BinOp::Lt(t))
897 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400898 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800899 punct!(>) => { BinOp::Gt }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400900 ));
901
902 /// ```ignore
903 /// <bitxor> | <bitxor> ...
904 /// ```
905 binop!(bitor_expr, bitxor_expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800906 not!(punct!(||)) >>
907 not!(punct!(|=)) >>
908 t: punct!(|) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400909 (BinOp::BitOr(t))
910 ));
911
912 /// ```ignore
913 /// <bitand> ^ <bitand> ...
914 /// ```
915 binop!(bitxor_expr, bitand_expr, do_parse!(
916 // NOTE: Make sure we aren't looking at ^=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800917 not!(punct!(^=)) >>
918 t: punct!(^) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400919 (BinOp::BitXor(t))
920 ));
921
922 /// ```ignore
923 /// <shift> & <shift> ...
924 /// ```
925 binop!(bitand_expr, shift_expr, do_parse!(
926 // NOTE: Make sure we aren't looking at && or &=.
David Tolnayf8db7ba2017-11-11 22:52:16 -0800927 not!(punct!(&&)) >>
928 not!(punct!(&=)) >>
929 t: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400930 (BinOp::BitAnd(t))
931 ));
932
933 /// ```ignore
934 /// <arith> << <arith> ...
935 /// <arith> >> <arith> ...
936 /// ```
937 binop!(shift_expr, arith_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800938 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400939 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800940 punct!(>>) => { BinOp::Shr }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400941 ));
942
943 /// ```ignore
944 /// <term> + <term> ...
945 /// <term> - <term> ...
946 /// ```
947 binop!(arith_expr, term_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800948 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400949 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800950 punct!(-) => { BinOp::Sub }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400951 ));
952
953 /// ```ignore
954 /// <cast> * <cast> ...
955 /// <cast> / <cast> ...
956 /// <cast> % <cast> ...
957 /// ```
958 binop!(term_expr, cast_expr, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800959 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400960 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800961 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400962 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800963 punct!(%) => { BinOp::Rem }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400964 ));
965
966 /// ```ignore
967 /// <unary> as <ty>
968 /// <unary> : <ty>
969 /// ```
970 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
971 mut e: call!(unary_expr, allow_struct, allow_block) >>
972 many0!(alt!(
973 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800974 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400975 // We can't accept `A + B` in cast expressions, as it's
976 // ambiguous with the + expression.
977 ty: call!(Ty::without_plus) >>
978 ({
979 e = ExprCast {
980 expr: Box::new(e.into()),
981 as_token: as_,
982 ty: Box::new(ty),
983 }.into();
984 })
985 )
986 |
987 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800988 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400989 // We can't accept `A + B` in cast expressions, as it's
990 // ambiguous with the + expression.
991 ty: call!(Ty::without_plus) >>
992 ({
993 e = ExprType {
994 expr: Box::new(e.into()),
995 colon_token: colon,
996 ty: Box::new(ty),
997 }.into();
998 })
999 )
1000 )) >>
1001 (e)
1002 ));
1003
1004 /// ```
1005 /// <UnOp> <trailer>
1006 /// & <trailer>
1007 /// &mut <trailer>
1008 /// box <trailer>
1009 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001010 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001011 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1012 do_parse!(
1013 op: syn!(UnOp) >>
1014 expr: call!(unary_expr, allow_struct, true) >>
1015 (ExprUnary {
1016 op: op,
1017 expr: Box::new(expr.into()),
1018 }.into())
1019 )
1020 |
1021 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001022 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001023 mutability: syn!(Mutability) >>
1024 expr: call!(unary_expr, allow_struct, true) >>
1025 (ExprAddrOf {
1026 and_token: and,
1027 mutbl: mutability,
1028 expr: Box::new(expr.into()),
1029 }.into())
1030 )
1031 |
1032 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001033 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001034 expr: call!(unary_expr, allow_struct, true) >>
1035 (ExprBox {
1036 box_token: box_,
1037 expr: Box::new(expr.into()),
1038 }.into())
1039 )
1040 |
1041 call!(trailer_expr, allow_struct, allow_block)
1042 ));
1043
Michael Layzell734adb42017-06-07 16:58:31 -04001044 // XXX: This duplication is ugly
1045 #[cfg(not(feature = "full"))]
1046 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1047 do_parse!(
1048 op: syn!(UnOp) >>
1049 expr: call!(unary_expr, allow_struct, true) >>
1050 (ExprUnary {
1051 op: op,
1052 expr: Box::new(expr.into()),
1053 }.into())
1054 )
1055 |
1056 call!(trailer_expr, allow_struct, allow_block)
1057 ));
1058
Michael Layzellb78f3b52017-06-04 19:03:03 -04001059 /// ```ignore
1060 /// <atom> (..<args>) ...
1061 /// <atom> . <ident> (..<args>) ...
1062 /// <atom> . <ident> ...
1063 /// <atom> . <lit> ...
1064 /// <atom> [ <expr> ] ...
1065 /// <atom> ? ...
1066 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001067 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001068 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1069 mut e: call!(atom_expr, allow_struct, allow_block) >>
1070 many0!(alt!(
1071 tap!(args: and_call => {
1072 let (args, paren) = args;
1073 e = ExprCall {
1074 func: Box::new(e.into()),
1075 args: args,
1076 paren_token: paren,
1077 }.into();
1078 })
1079 |
1080 tap!(more: and_method_call => {
1081 let mut call = more;
1082 call.expr = Box::new(e.into());
1083 e = call.into();
1084 })
1085 |
1086 tap!(field: and_field => {
1087 let (field, token) = field;
1088 e = ExprField {
1089 expr: Box::new(e.into()),
1090 field: field,
1091 dot_token: token,
1092 }.into();
1093 })
1094 |
1095 tap!(field: and_tup_field => {
1096 let (field, token) = field;
1097 e = ExprTupField {
1098 expr: Box::new(e.into()),
1099 field: field,
1100 dot_token: token,
1101 }.into();
1102 })
1103 |
1104 tap!(i: and_index => {
1105 let (i, token) = i;
1106 e = ExprIndex {
1107 expr: Box::new(e.into()),
1108 bracket_token: token,
1109 index: Box::new(i),
1110 }.into();
1111 })
1112 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001113 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001114 e = ExprTry {
1115 expr: Box::new(e.into()),
1116 question_token: question,
1117 }.into();
1118 })
1119 )) >>
1120 (e)
1121 ));
1122
Michael Layzell734adb42017-06-07 16:58:31 -04001123 // XXX: Duplication == ugly
1124 #[cfg(not(feature = "full"))]
1125 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1126 mut e: call!(atom_expr, allow_struct, allow_block) >>
1127 many0!(alt!(
1128 tap!(args: and_call => {
1129 let (args, paren) = args;
1130 e = ExprCall {
1131 func: Box::new(e.into()),
1132 args: args,
1133 paren_token: paren,
1134 }.into();
1135 })
1136 |
1137 tap!(i: and_index => {
1138 let (i, token) = i;
1139 e = ExprIndex {
1140 expr: Box::new(e.into()),
1141 bracket_token: token,
1142 index: Box::new(i),
1143 }.into();
1144 })
1145 )) >>
1146 (e)
1147 ));
1148
Michael Layzellb78f3b52017-06-04 19:03:03 -04001149 /// Parse all atomic expressions which don't have to worry about precidence
1150 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001151 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001152 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001153 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1154 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001155 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1156 |
1157 // must be before expr_path
1158 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1159 |
1160 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1161 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001162 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001163 |
1164 call!(expr_break, allow_struct) // must be before expr_path
1165 |
1166 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1167 |
1168 call!(expr_ret, allow_struct) // must be before expr_path
1169 |
1170 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1171 syn!(ExprInPlace) => { ExprKind::InPlace }
1172 |
1173 syn!(ExprArray) => { ExprKind::Array }
1174 |
1175 syn!(ExprTup) => { ExprKind::Tup }
1176 |
1177 syn!(ExprIf) => { ExprKind::If }
1178 |
1179 syn!(ExprIfLet) => { ExprKind::IfLet }
1180 |
1181 syn!(ExprWhile) => { ExprKind::While }
1182 |
1183 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1184 |
1185 syn!(ExprForLoop) => { ExprKind::ForLoop }
1186 |
1187 syn!(ExprLoop) => { ExprKind::Loop }
1188 |
1189 syn!(ExprMatch) => { ExprKind::Match }
1190 |
1191 syn!(ExprCatch) => { ExprKind::Catch }
1192 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001193 syn!(ExprYield) => { ExprKind::Yield }
1194 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001195 call!(expr_closure, allow_struct)
1196 |
1197 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1198 |
1199 // NOTE: This is the prefix-form of range
1200 call!(expr_range, allow_struct)
1201 |
1202 syn!(ExprPath) => { ExprKind::Path }
1203 |
1204 syn!(ExprRepeat) => { ExprKind::Repeat }
1205 ));
1206
Michael Layzell734adb42017-06-07 16:58:31 -04001207 #[cfg(not(feature = "full"))]
1208 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1209 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1210 |
1211 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1212 |
1213 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1214 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001215 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001216 |
1217 syn!(ExprPath) => { ExprKind::Path }
1218 ));
1219
1220
1221 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001222 named!(expr_nosemi -> Expr, map!(alt!(
1223 syn!(ExprIf) => { ExprKind::If }
1224 |
1225 syn!(ExprIfLet) => { ExprKind::IfLet }
1226 |
1227 syn!(ExprWhile) => { ExprKind::While }
1228 |
1229 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1230 |
1231 syn!(ExprForLoop) => { ExprKind::ForLoop }
1232 |
1233 syn!(ExprLoop) => { ExprKind::Loop }
1234 |
1235 syn!(ExprMatch) => { ExprKind::Match }
1236 |
1237 syn!(ExprCatch) => { ExprKind::Catch }
1238 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001239 syn!(ExprYield) => { ExprKind::Yield }
1240 |
Michael Layzell35418782017-06-07 09:20:25 -04001241 syn!(ExprBlock) => { ExprKind::Block }
1242 ), Expr::from));
1243
Michael Layzell93c36282017-06-04 20:43:14 -04001244 impl Synom for ExprGroup {
1245 named!(parse -> Self, do_parse!(
1246 e: grouped!(syn!(Expr)) >>
1247 (ExprGroup {
1248 expr: Box::new(e.0),
1249 group_token: e.1,
1250 }.into())
1251 ));
1252 }
1253
Alex Crichton954046c2017-05-30 21:49:42 -07001254 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001255 named!(parse -> Self, do_parse!(
1256 e: parens!(syn!(Expr)) >>
1257 (ExprParen {
1258 expr: Box::new(e.0),
1259 paren_token: e.1,
1260 }.into())
1261 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001262 }
David Tolnay89e05672016-10-02 14:39:42 -07001263
Michael Layzell734adb42017-06-07 16:58:31 -04001264 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001265 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001266 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001267 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001268 place: expr_no_struct >>
1269 value: braces!(call!(Block::parse_within)) >>
1270 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001271 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001272 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001273 value: Box::new(Expr {
1274 node: ExprBlock {
1275 unsafety: Unsafety::Normal,
1276 block: Block {
1277 stmts: value.0,
1278 brace_token: value.1,
1279 },
1280 }.into(),
1281 attrs: Vec::new(),
1282 }),
1283 })
1284 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001285 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001286
Michael Layzell734adb42017-06-07 16:58:31 -04001287 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001288 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001289 named!(parse -> Self, do_parse!(
1290 elems: brackets!(call!(Delimited::parse_terminated)) >>
1291 (ExprArray {
1292 exprs: elems.0,
1293 bracket_token: elems.1,
1294 })
1295 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001296 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001297
David Tolnayf8db7ba2017-11-11 22:52:16 -08001298 named!(and_call -> (Delimited<Expr, Token![,]>, tokens::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001299 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001300
Michael Layzell734adb42017-06-07 16:58:31 -04001301 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001302 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001303 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001304 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001305 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001306 colon2: punct!(::) >>
1307 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001308 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001309 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001310 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001311 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001312 args: parens!(call!(Delimited::parse_terminated)) >>
1313 ({
1314 let (colon2, lt, tys, gt) = match typarams {
1315 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1316 None => (None, None, None, None),
1317 };
1318 ExprMethodCall {
1319 // this expr will get overwritten after being returned
1320 expr: Box::new(ExprKind::Lit(Lit {
1321 span: Span::default(),
1322 value: LitKind::Bool(false),
1323 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001324
Alex Crichton954046c2017-05-30 21:49:42 -07001325 method: method,
1326 args: args.0,
1327 paren_token: args.1,
1328 dot_token: dot,
1329 lt_token: lt,
1330 gt_token: gt,
1331 colon2_token: colon2,
1332 typarams: tys.unwrap_or_default(),
1333 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001334 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001335 ));
1336
Michael Layzell734adb42017-06-07 16:58:31 -04001337 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001338 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001339 named!(parse -> Self, do_parse!(
1340 elems: parens!(call!(Delimited::parse_terminated)) >>
1341 (ExprTup {
1342 args: elems.0,
1343 paren_token: elems.1,
1344 lone_comma: None, // TODO: parse this
1345 })
1346 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001347 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001348
Michael Layzell734adb42017-06-07 16:58:31 -04001349 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001350 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001351 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001352 if_: keyword!(if) >>
1353 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001354 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001355 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001356 cond: expr_no_struct >>
1357 then_block: braces!(call!(Block::parse_within)) >>
1358 else_block: option!(else_block) >>
1359 (ExprIfLet {
1360 pat: Box::new(pat),
1361 let_token: let_,
1362 eq_token: eq,
1363 expr: Box::new(cond),
1364 if_true: Block {
1365 stmts: then_block.0,
1366 brace_token: then_block.1,
1367 },
1368 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001369 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001370 if_false: else_block.map(|p| Box::new(p.1.into())),
1371 })
1372 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001373 }
1374
Michael Layzell734adb42017-06-07 16:58:31 -04001375 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001376 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001377 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001378 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001379 cond: expr_no_struct >>
1380 then_block: braces!(call!(Block::parse_within)) >>
1381 else_block: option!(else_block) >>
1382 (ExprIf {
1383 cond: Box::new(cond),
1384 if_true: Block {
1385 stmts: then_block.0,
1386 brace_token: then_block.1,
1387 },
1388 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001389 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001390 if_false: else_block.map(|p| Box::new(p.1.into())),
1391 })
1392 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001393 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001394
Michael Layzell734adb42017-06-07 16:58:31 -04001395 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001396 named!(else_block -> (Token![else], ExprKind), do_parse!(
1397 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001398 expr: alt!(
1399 syn!(ExprIf) => { ExprKind::If }
1400 |
1401 syn!(ExprIfLet) => { ExprKind::IfLet }
1402 |
1403 do_parse!(
1404 else_block: braces!(call!(Block::parse_within)) >>
1405 (ExprKind::Block(ExprBlock {
1406 unsafety: Unsafety::Normal,
1407 block: Block {
1408 stmts: else_block.0,
1409 brace_token: else_block.1,
1410 },
1411 }))
David Tolnay939766a2016-09-23 23:48:12 -07001412 )
Alex Crichton954046c2017-05-30 21:49:42 -07001413 ) >>
1414 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001415 ));
1416
David Tolnaybb6feae2016-10-02 21:25:20 -07001417
Michael Layzell734adb42017-06-07 16:58:31 -04001418 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001419 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001420 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001421 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1422 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001423 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001424 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001425 expr: expr_no_struct >>
1426 loop_block: syn!(Block) >>
1427 (ExprForLoop {
1428 for_token: for_,
1429 in_token: in_,
1430 pat: Box::new(pat),
1431 expr: Box::new(expr),
1432 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001433 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001434 label: lbl.map(|p| p.0),
1435 })
1436 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001437 }
Gregory Katze5f35682016-09-27 14:20:55 -04001438
Michael Layzell734adb42017-06-07 16:58:31 -04001439 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001440 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001441 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001442 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1443 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001444 loop_block: syn!(Block) >>
1445 (ExprLoop {
1446 loop_token: loop_,
1447 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001448 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001449 label: lbl.map(|p| p.0),
1450 })
1451 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001452 }
1453
Michael Layzell734adb42017-06-07 16:58:31 -04001454 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001455 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001456 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001457 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001458 obj: expr_no_struct >>
Alex Crichton03b30272017-08-28 09:35:24 -07001459 res: braces!(many0!(syn!(Arm))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001460 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001461 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001462 ExprMatch {
1463 expr: Box::new(obj),
1464 match_token: match_,
1465 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001466 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001467 }
1468 })
1469 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001470 }
David Tolnay1978c672016-10-27 22:05:52 -07001471
Michael Layzell734adb42017-06-07 16:58:31 -04001472 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001473 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001474 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001475 do_: keyword!(do) >>
1476 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001477 catch_block: syn!(Block) >>
1478 (ExprCatch {
1479 block: catch_block,
1480 do_token: do_,
1481 catch_token: catch_,
1482 }.into())
1483 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001484 }
Arnavion02ef13f2017-04-25 00:54:31 -07001485
Michael Layzell734adb42017-06-07 16:58:31 -04001486 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001487 impl Synom for ExprYield {
1488 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001489 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001490 expr: option!(syn!(Expr)) >>
1491 (ExprYield {
1492 yield_token: yield_,
1493 expr: expr.map(Box::new),
1494 })
1495 ));
1496 }
1497
1498 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001499 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001500 named!(parse -> Self, do_parse!(
1501 attrs: many0!(call!(Attribute::parse_outer)) >>
1502 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001503 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1504 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001505 body: do_parse!(
1506 expr: alt!(expr_nosemi | syn!(Expr)) >>
1507 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1508 map!(input_end!(), |_| None)
1509 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001510 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001511 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001512 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001513 (expr, comma1.and_then(|x| x).or(comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001514 ) >>
1515 (Arm {
1516 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001517 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001518 attrs: attrs,
1519 pats: pats,
1520 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001521 body: Box::new(body.0),
1522 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001523 })
1524 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001525 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001526
Michael Layzell734adb42017-06-07 16:58:31 -04001527 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001528 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001529 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001530 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001531 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001532 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001533 ret_and_body: alt!(
1534 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001535 arrow: punct!(->) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001536 ty: syn!(Ty) >>
1537 body: syn!(Block) >>
David Tolnayf93b90d2017-11-11 19:21:26 -08001538 (ReturnType::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001539 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001540 unsafety: Unsafety::Normal,
1541 block: body,
1542 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001543 )
1544 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001545 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001546 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001547 (ExprClosure {
1548 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001549 or1_token: or1,
1550 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001551 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001552 inputs: inputs,
1553 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001554 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001555 dot_tokens: None,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001556 fn_token: <Token![fn]>::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001557 generics: Generics::default(),
1558 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001559 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001560 body: Box::new(ret_and_body.1),
1561 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001562 ));
1563
Michael Layzell734adb42017-06-07 16:58:31 -04001564 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001565 named!(fn_arg -> FnArg, do_parse!(
1566 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001567 ty: option!(tuple!(punct!(:), syn!(Ty))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001568 ({
1569 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001570 (<Token![:]>::default(), TyInfer {
1571 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001572 }.into())
1573 });
1574 ArgCaptured {
1575 pat: pat,
1576 colon_token: colon,
1577 ty: ty,
1578 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001579 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001580 ));
1581
Michael Layzell734adb42017-06-07 16:58:31 -04001582 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001583 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001584 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001585 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1586 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001587 cond: expr_no_struct >>
1588 while_block: syn!(Block) >>
1589 (ExprWhile {
1590 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001591 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001592 cond: Box::new(cond),
1593 body: while_block,
1594 label: lbl.map(|p| p.0),
1595 })
1596 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001597 }
1598
Michael Layzell734adb42017-06-07 16:58:31 -04001599 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001600 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001601 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001602 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1603 while_: keyword!(while) >>
1604 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001605 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001606 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001607 value: expr_no_struct >>
1608 while_block: syn!(Block) >>
1609 (ExprWhileLet {
1610 eq_token: eq,
1611 let_token: let_,
1612 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001613 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001614 pat: Box::new(pat),
1615 expr: Box::new(value),
1616 body: while_block,
1617 label: lbl.map(|p| p.0),
1618 })
1619 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001620 }
1621
Michael Layzell734adb42017-06-07 16:58:31 -04001622 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001623 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001624 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001625 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001626 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001627 (ExprContinue {
1628 continue_token: cont,
1629 label: lbl,
1630 })
1631 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001632 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001633
Michael Layzell734adb42017-06-07 16:58:31 -04001634 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001635 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001636 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001637 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001638 // We can't allow blocks after a `break` expression when we wouldn't
1639 // allow structs, as this expression is ambiguous.
1640 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001641 (ExprBreak {
1642 label: lbl,
1643 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001644 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001645 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001646 ));
1647
Michael Layzell734adb42017-06-07 16:58:31 -04001648 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001649 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001650 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001651 // NOTE: return is greedy and eats blocks after it even when in a
1652 // position where structs are not allowed, such as in if statement
1653 // conditions. For example:
1654 //
1655 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001656 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001657 (ExprRet {
1658 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001659 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001660 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001661 ));
1662
Michael Layzell734adb42017-06-07 16:58:31 -04001663 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001664 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001665 named!(parse -> Self, do_parse!(
1666 path: syn!(Path) >>
1667 data: braces!(do_parse!(
1668 fields: call!(Delimited::parse_terminated) >>
1669 base: option!(
1670 cond!(fields.is_empty() || fields.trailing_delim(),
1671 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001672 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001673 base: syn!(Expr) >>
1674 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001675 )
Michael Layzell92639a52017-06-01 00:07:44 -04001676 )
1677 ) >>
1678 (fields, base)
1679 )) >>
1680 ({
1681 let ((fields, base), brace) = data;
1682 let (dots, rest) = match base.and_then(|b| b) {
1683 Some((dots, base)) => (Some(dots), Some(base)),
1684 None => (None, None),
1685 };
1686 ExprStruct {
1687 brace_token: brace,
1688 path: path,
1689 fields: fields,
1690 dot2_token: dots,
1691 rest: rest.map(Box::new),
1692 }
1693 })
1694 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001695 }
1696
Michael Layzell734adb42017-06-07 16:58:31 -04001697 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001698 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001699 named!(parse -> Self, alt!(
1700 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001701 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001702 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001703 value: syn!(Expr) >>
1704 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001705 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001706 expr: value,
1707 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001708 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001709 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001710 })
Michael Layzell92639a52017-06-01 00:07:44 -04001711 )
1712 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001713 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001714 ident: name.clone(),
1715 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1716 is_shorthand: true,
1717 attrs: Vec::new(),
1718 colon_token: None,
1719 })
1720 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001721 }
David Tolnay055a7042016-10-02 19:23:54 -07001722
Michael Layzell734adb42017-06-07 16:58:31 -04001723 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001724 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001725 named!(parse -> Self, do_parse!(
1726 data: brackets!(do_parse!(
1727 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001728 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001729 times: syn!(Expr) >>
1730 (value, semi, times)
1731 )) >>
1732 (ExprRepeat {
1733 expr: Box::new((data.0).0),
1734 amt: Box::new((data.0).2),
1735 bracket_token: data.1,
1736 semi_token: (data.0).1,
1737 })
1738 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001739 }
David Tolnay055a7042016-10-02 19:23:54 -07001740
Michael Layzell734adb42017-06-07 16:58:31 -04001741 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001742 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001743 named!(parse -> Self, do_parse!(
1744 rules: syn!(Unsafety) >>
1745 b: syn!(Block) >>
1746 (ExprBlock {
1747 unsafety: rules,
1748 block: b,
1749 })
1750 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001751 }
David Tolnay89e05672016-10-02 14:39:42 -07001752
Michael Layzell734adb42017-06-07 16:58:31 -04001753 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001754 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001755 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001756 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001757 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001758 ));
1759
Michael Layzell734adb42017-06-07 16:58:31 -04001760 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001761 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001762 named!(parse -> Self, alt!(
1763 // Must come before Dot2
David Tolnayf8db7ba2017-11-11 22:52:16 -08001764 punct!(...) => { RangeLimits::Closed }
Michael Layzell92639a52017-06-01 00:07:44 -04001765 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001766 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001767 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001768 }
David Tolnay438c9052016-10-07 23:24:48 -07001769
Alex Crichton954046c2017-05-30 21:49:42 -07001770 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001771 named!(parse -> Self, do_parse!(
1772 pair: qpath >>
1773 (ExprPath {
1774 qself: pair.0,
1775 path: pair.1,
1776 })
1777 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001778 }
David Tolnay42602292016-10-01 22:25:45 -07001779
Michael Layzell734adb42017-06-07 16:58:31 -04001780 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001781 named!(and_field -> (Ident, Token![.]),
1782 map!(tuple!(punct!(.), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001783
Michael Layzell734adb42017-06-07 16:58:31 -04001784 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001785 named!(and_tup_field -> (Lit, Token![.]),
1786 map!(tuple!(punct!(.), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001787
Alex Crichton954046c2017-05-30 21:49:42 -07001788 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001789
Michael Layzell734adb42017-06-07 16:58:31 -04001790 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001791 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001792 named!(parse -> Self, do_parse!(
1793 stmts: braces!(call!(Block::parse_within)) >>
1794 (Block {
1795 stmts: stmts.0,
1796 brace_token: stmts.1,
1797 })
1798 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001799 }
David Tolnay939766a2016-09-23 23:48:12 -07001800
Michael Layzell734adb42017-06-07 16:58:31 -04001801 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001802 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001803 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001804 many0!(punct!(;)) >>
1805 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001806 last: option!(do_parse!(
1807 attrs: many0!(call!(Attribute::parse_outer)) >>
1808 mut e: syn!(Expr) >>
1809 ({
1810 e.attrs = attrs;
1811 Stmt::Expr(Box::new(e))
1812 })
1813 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001814 (match last {
1815 None => standalone,
1816 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001817 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001818 standalone
1819 }
1820 })
1821 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001822 }
1823
Michael Layzell734adb42017-06-07 16:58:31 -04001824 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001825 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001826 named!(parse -> Self, alt!(
1827 stmt_mac
1828 |
1829 stmt_local
1830 |
1831 stmt_item
1832 |
Michael Layzell35418782017-06-07 09:20:25 -04001833 stmt_blockexpr
1834 |
Michael Layzell92639a52017-06-01 00:07:44 -04001835 stmt_expr
1836 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001837 }
David Tolnay939766a2016-09-23 23:48:12 -07001838
Michael Layzell734adb42017-06-07 16:58:31 -04001839 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001840 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001841 attrs: many0!(call!(Attribute::parse_outer)) >>
1842 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001843 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001844 // Only parse braces here; paren and bracket will get parsed as
1845 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001846 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001847 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001848 (Stmt::Macro(Box::new((
1849 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001850 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001851 bang_token: bang,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001852 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001853 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001854 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001855 })],
1856 },
Alex Crichton954046c2017-05-30 21:49:42 -07001857 match semi {
1858 Some(semi) => MacStmtStyle::Semicolon(semi),
1859 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001860 },
David Tolnayeea28d62016-10-25 20:44:08 -07001861 attrs,
1862 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001863 ));
1864
Michael Layzell734adb42017-06-07 16:58:31 -04001865 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001866 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001867 attrs: many0!(call!(Attribute::parse_outer)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001868 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001869 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001870 ty: option!(tuple!(punct!(:), syn!(Ty))) >>
1871 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1872 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001873 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001874 let_token: let_,
1875 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001876 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1877 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001878 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001879 ty: ty.map(|p| Box::new(p.1)),
1880 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001881 attrs: attrs,
1882 })))
1883 ));
1884
Michael Layzell734adb42017-06-07 16:58:31 -04001885 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001886 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001887
Michael Layzell734adb42017-06-07 16:58:31 -04001888 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001889 named!(stmt_blockexpr -> Stmt, do_parse!(
1890 attrs: many0!(call!(Attribute::parse_outer)) >>
1891 mut e: expr_nosemi >>
1892 // If the next token is a `.` or a `?` it is special-cased to parse as
1893 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001894 not!(punct!(.)) >>
1895 not!(punct!(?)) >>
1896 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001897 ({
1898 e.attrs = attrs;
1899 if let Some(semi) = semi {
1900 Stmt::Semi(Box::new(e), semi)
1901 } else {
1902 Stmt::Expr(Box::new(e))
1903 }
1904 })
1905 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001906
Michael Layzell734adb42017-06-07 16:58:31 -04001907 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001908 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001909 attrs: many0!(call!(Attribute::parse_outer)) >>
1910 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001911 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001912 ({
1913 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001914 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001915 })
David Tolnay939766a2016-09-23 23:48:12 -07001916 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001917
Michael Layzell734adb42017-06-07 16:58:31 -04001918 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001919 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001920 named!(parse -> Self, alt!(
1921 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1922 |
1923 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1924 |
1925 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1926 |
1927 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1928 |
1929 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1930 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001931 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001932 |
1933 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1934 |
1935 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1936 |
1937 syn!(PatPath) => { Pat::Path }
1938 |
1939 syn!(PatTuple) => { Pat::Tuple }
1940 |
1941 syn!(PatRef) => { Pat::Ref }
1942 |
1943 syn!(PatSlice) => { Pat::Slice }
1944 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001945 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001946
Michael Layzell734adb42017-06-07 16:58:31 -04001947 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001948 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001949 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001950 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001951 |u| PatWild { underscore_token: u }
1952 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001953 }
David Tolnay84aa0752016-10-02 23:01:13 -07001954
Michael Layzell734adb42017-06-07 16:58:31 -04001955 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001956 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001957 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001958 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001959 pat: syn!(Pat) >>
1960 (PatBox {
1961 pat: Box::new(pat),
1962 box_token: boxed,
1963 })
1964 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001965 }
1966
Michael Layzell734adb42017-06-07 16:58:31 -04001967 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001968 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001969 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001970 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001971 mutability: syn!(Mutability) >>
1972 name: alt!(
1973 syn!(Ident)
1974 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001975 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001976 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001977 not!(punct!(<)) >>
1978 not!(punct!(::)) >>
1979 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001980 (PatIdent {
1981 mode: match mode {
1982 Some(mode) => BindingMode::ByRef(mode, mutability),
1983 None => BindingMode::ByValue(mutability),
1984 },
1985 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001986 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001987 subpat: subpat.map(|p| Box::new(p.1)),
1988 })
1989 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001990 }
1991
Michael Layzell734adb42017-06-07 16:58:31 -04001992 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001993 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001994 named!(parse -> Self, do_parse!(
1995 path: syn!(Path) >>
1996 tuple: syn!(PatTuple) >>
1997 (PatTupleStruct {
1998 path: path,
1999 pat: tuple,
2000 })
2001 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002002 }
2003
Michael Layzell734adb42017-06-07 16:58:31 -04002004 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002005 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002006 named!(parse -> Self, do_parse!(
2007 path: syn!(Path) >>
2008 data: braces!(do_parse!(
2009 fields: call!(Delimited::parse_terminated) >>
2010 base: option!(
2011 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002012 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002013 ) >>
2014 (fields, base)
2015 )) >>
2016 (PatStruct {
2017 path: path,
2018 fields: (data.0).0,
2019 brace_token: data.1,
2020 dot2_token: (data.0).1.and_then(|m| m),
2021 })
2022 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002023 }
2024
Michael Layzell734adb42017-06-07 16:58:31 -04002025 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002026 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002027 named!(parse -> Self, alt!(
2028 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002029 ident: field_ident >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002030 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002031 pat: syn!(Pat) >>
2032 (FieldPat {
2033 ident: ident,
2034 pat: Box::new(pat),
2035 is_shorthand: false,
2036 attrs: Vec::new(),
2037 colon_token: Some(colon),
2038 })
2039 )
2040 |
2041 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002042 boxed: option!(keyword!(box)) >>
2043 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002044 mutability: syn!(Mutability) >>
2045 ident: syn!(Ident) >>
2046 ({
2047 let mut pat: Pat = PatIdent {
2048 mode: if let Some(mode) = mode {
2049 BindingMode::ByRef(mode, mutability)
2050 } else {
2051 BindingMode::ByValue(mutability)
2052 },
2053 ident: ident.clone(),
2054 subpat: None,
2055 at_token: None,
2056 }.into();
2057 if let Some(boxed) = boxed {
2058 pat = PatBox {
2059 pat: Box::new(pat),
2060 box_token: boxed,
2061 }.into();
2062 }
2063 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002064 ident: ident,
2065 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002066 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002067 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002068 colon_token: None,
2069 }
2070 })
2071 )
2072 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002073 }
2074
Michael Layzell734adb42017-06-07 16:58:31 -04002075 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002076 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002077 syn!(Ident)
2078 |
2079 do_parse!(
2080 lit: syn!(Lit) >>
2081 ({
David Tolnay570695e2017-06-03 16:15:13 -07002082 let s = lit.to_string();
2083 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002084 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002085 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002086 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002087 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002088 })
2089 )
2090 ));
2091
Michael Layzell734adb42017-06-07 16:58:31 -04002092 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002093 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002094 named!(parse -> Self, map!(
2095 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002096 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002097 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002098 }
David Tolnay9636c052016-10-02 17:11:17 -07002099
Michael Layzell734adb42017-06-07 16:58:31 -04002100 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002101 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002102 named!(parse -> Self, do_parse!(
2103 data: parens!(do_parse!(
2104 elems: call!(Delimited::parse_terminated) >>
2105 dotdot: map!(cond!(
2106 elems.is_empty() || elems.trailing_delim(),
2107 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002108 dots: punct!(..) >>
2109 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002110 (dots, trailing)
2111 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002112 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002113 rest: cond!(match dotdot {
2114 Some((_, Some(_))) => true,
2115 _ => false,
2116 },
2117 call!(Delimited::parse_terminated)) >>
2118 (elems, dotdot, rest)
2119 )) >>
2120 ({
2121 let ((mut elems, dotdot, rest), parens) = data;
2122 let (dotdot, trailing) = match dotdot {
2123 Some((a, b)) => (Some(a), Some(b)),
2124 None => (None, None),
2125 };
2126 PatTuple {
2127 paren_token: parens,
2128 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2129 dot2_token: dotdot,
2130 comma_token: trailing.and_then(|b| b),
2131 pats: {
2132 if let Some(rest) = rest {
2133 for elem in rest {
2134 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002135 }
Michael Layzell92639a52017-06-01 00:07:44 -04002136 }
2137 elems
2138 },
2139 }
2140 })
2141 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002142 }
David Tolnayfbb73232016-10-03 01:00:06 -07002143
Michael Layzell734adb42017-06-07 16:58:31 -04002144 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002145 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002146 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002147 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002148 mutability: syn!(Mutability) >>
2149 pat: syn!(Pat) >>
2150 (PatRef {
2151 pat: Box::new(pat),
2152 mutbl: mutability,
2153 and_token: and,
2154 })
2155 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002156 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002157
Michael Layzell734adb42017-06-07 16:58:31 -04002158 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002159 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002160 named!(parse -> Self, do_parse!(
2161 lit: pat_lit_expr >>
2162 (if let ExprKind::Path(_) = lit.node {
2163 return parse_error(); // these need to be parsed by pat_path
2164 } else {
2165 PatLit {
2166 expr: Box::new(lit),
2167 }
2168 })
2169 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002170 }
David Tolnaye1310902016-10-29 23:40:00 -07002171
Michael Layzell734adb42017-06-07 16:58:31 -04002172 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002173 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002174 named!(parse -> Self, do_parse!(
2175 lo: pat_lit_expr >>
2176 limits: syn!(RangeLimits) >>
2177 hi: pat_lit_expr >>
2178 (PatRange {
2179 lo: Box::new(lo),
2180 hi: Box::new(hi),
2181 limits: limits,
2182 })
2183 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002184 }
David Tolnaye1310902016-10-29 23:40:00 -07002185
Michael Layzell734adb42017-06-07 16:58:31 -04002186 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002187 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002188 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002189 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002190 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002191 |
Alex Crichton954046c2017-05-30 21:49:42 -07002192 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002193 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002194 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002195 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002196 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002197 expr: Box::new(v.into())
2198 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002199 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002200 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002201 })
2202 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002203
Michael Layzell734adb42017-06-07 16:58:31 -04002204 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002205 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002206 named!(parse -> Self, map!(
2207 brackets!(do_parse!(
2208 before: call!(Delimited::parse_terminated) >>
2209 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002210 dots: punct!(..) >>
2211 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002212 (dots, trailing)
2213 )) >>
2214 after: cond!(
2215 match middle {
2216 Some((_, ref trailing)) => trailing.is_some(),
2217 _ => false,
2218 },
2219 call!(Delimited::parse_terminated)
2220 ) >>
2221 (before, middle, after)
2222 )),
2223 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002224 let mut before: Delimited<Pat, Token![,]> = before;
2225 let after: Option<Delimited<Pat, Token![,]>> = after;
2226 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002227 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002228 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002229 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002230 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002231 }),
2232 bracket_token: brackets,
2233 middle: middle.and_then(|_| {
2234 if !before.is_empty() && !before.trailing_delim() {
2235 Some(Box::new(before.pop().unwrap().into_item()))
2236 } else {
2237 None
2238 }
2239 }),
2240 front: before,
2241 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002242 }
Alex Crichton954046c2017-05-30 21:49:42 -07002243 }
Michael Layzell92639a52017-06-01 00:07:44 -04002244 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002245 }
David Tolnay435a9a82016-10-29 13:47:20 -07002246
Michael Layzell734adb42017-06-07 16:58:31 -04002247 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002248 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002249 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002250 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002251 |
2252 epsilon!() => { |_| CaptureBy::Ref }
2253 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002254 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002255}
2256
David Tolnayf4bbbd92016-09-23 14:41:55 -07002257#[cfg(feature = "printing")]
2258mod printing {
2259 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002260 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002261 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002262 use quote::{Tokens, ToTokens};
2263
Michael Layzell3936ceb2017-07-08 00:28:36 -04002264 /// If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2265 /// before appending it to `Tokens`.
2266 #[cfg(feature = "full")]
2267 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2268 if let ExprKind::Struct(_) = e.node {
2269 tokens::Paren::default().surround(tokens, |tokens| {
2270 e.to_tokens(tokens);
2271 });
2272 } else {
2273 e.to_tokens(tokens);
2274 }
2275 }
2276
David Tolnayf4bbbd92016-09-23 14:41:55 -07002277 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002278 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002279 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002280 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002281 self.node.to_tokens(tokens)
2282 }
Michael Layzell734adb42017-06-07 16:58:31 -04002283
2284 #[cfg(not(feature = "full"))]
2285 fn to_tokens(&self, tokens: &mut Tokens) {
2286 self.node.to_tokens(tokens)
2287 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002288 }
2289
Michael Layzell734adb42017-06-07 16:58:31 -04002290 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002291 impl ToTokens for ExprBox {
2292 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002293 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002294 self.expr.to_tokens(tokens);
2295 }
2296 }
2297
Michael Layzell734adb42017-06-07 16:58:31 -04002298 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002299 impl ToTokens for ExprInPlace {
2300 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002301 match self.kind {
2302 InPlaceKind::Arrow(ref arrow) => {
2303 self.place.to_tokens(tokens);
2304 arrow.to_tokens(tokens);
2305 self.value.to_tokens(tokens);
2306 }
2307 InPlaceKind::In(ref _in) => {
2308 _in.to_tokens(tokens);
2309 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002310 // NOTE: The second operand must be in a block, add one if
2311 // it is not present.
2312 if let ExprKind::Block(_) = self.value.node {
2313 self.value.to_tokens(tokens);
2314 } else {
2315 tokens::Brace::default().surround(tokens, |tokens| {
2316 self.value.to_tokens(tokens);
2317 })
2318 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002319 }
2320 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002321 }
2322 }
2323
Michael Layzell734adb42017-06-07 16:58:31 -04002324 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002325 impl ToTokens for ExprArray {
2326 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002327 self.bracket_token.surround(tokens, |tokens| {
2328 self.exprs.to_tokens(tokens);
2329 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002330 }
2331 }
2332
2333 impl ToTokens for ExprCall {
2334 fn to_tokens(&self, tokens: &mut Tokens) {
2335 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002336 self.paren_token.surround(tokens, |tokens| {
2337 self.args.to_tokens(tokens);
2338 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002339 }
2340 }
2341
Michael Layzell734adb42017-06-07 16:58:31 -04002342 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002343 impl ToTokens for ExprMethodCall {
2344 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002345 self.expr.to_tokens(tokens);
2346 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002347 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002348 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002349 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2350 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002351 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002352 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002353 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002354 self.paren_token.surround(tokens, |tokens| {
2355 self.args.to_tokens(tokens);
2356 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002357 }
2358 }
2359
Michael Layzell734adb42017-06-07 16:58:31 -04002360 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002361 impl ToTokens for ExprTup {
2362 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002363 self.paren_token.surround(tokens, |tokens| {
2364 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002365 // If we only have one argument, we need a trailing comma to
2366 // distinguish ExprTup from ExprParen.
2367 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002368 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002369 }
2370 // XXX: Not sure how to handle this, but we never parse it yet.
2371 // Is this for an expression like (0,)? Can't we use the
2372 // trailing delimiter on Delimited for that? (,) isn't a valid
2373 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002374 self.lone_comma.to_tokens(tokens);
2375 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002376 }
2377 }
2378
2379 impl ToTokens for ExprBinary {
2380 fn to_tokens(&self, tokens: &mut Tokens) {
2381 self.left.to_tokens(tokens);
2382 self.op.to_tokens(tokens);
2383 self.right.to_tokens(tokens);
2384 }
2385 }
2386
2387 impl ToTokens for ExprUnary {
2388 fn to_tokens(&self, tokens: &mut Tokens) {
2389 self.op.to_tokens(tokens);
2390 self.expr.to_tokens(tokens);
2391 }
2392 }
2393
2394 impl ToTokens for ExprCast {
2395 fn to_tokens(&self, tokens: &mut Tokens) {
2396 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002397 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002398 self.ty.to_tokens(tokens);
2399 }
2400 }
2401
2402 impl ToTokens for ExprType {
2403 fn to_tokens(&self, tokens: &mut Tokens) {
2404 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002405 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002406 self.ty.to_tokens(tokens);
2407 }
2408 }
2409
Michael Layzell734adb42017-06-07 16:58:31 -04002410 #[cfg(feature = "full")]
Michael Layzell3936ceb2017-07-08 00:28:36 -04002411 fn maybe_wrap_else(tokens: &mut Tokens,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002412 else_token: &Option<Token![else]>,
Michael Layzell3936ceb2017-07-08 00:28:36 -04002413 if_false: &Option<Box<Expr>>)
2414 {
2415 if let Some(ref if_false) = *if_false {
Alex Crichton259ee532017-07-14 06:51:02 -07002416 TokensOrDefault(&else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002417
2418 // If we are not one of the valid expressions to exist in an else
2419 // clause, wrap ourselves in a block.
2420 match if_false.node {
2421 ExprKind::If(_) |
2422 ExprKind::IfLet(_) |
2423 ExprKind::Block(_) => {
2424 if_false.to_tokens(tokens);
2425 }
2426 _ => {
2427 tokens::Brace::default().surround(tokens, |tokens| {
2428 if_false.to_tokens(tokens);
2429 });
2430 }
2431 }
2432 }
2433 }
2434
2435 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002436 impl ToTokens for ExprIf {
2437 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002438 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002439 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002440 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002441 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002442 }
2443 }
2444
Michael Layzell734adb42017-06-07 16:58:31 -04002445 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002446 impl ToTokens for ExprIfLet {
2447 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002448 self.if_token.to_tokens(tokens);
2449 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002450 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002451 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002452 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002453 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002454 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002455 }
2456 }
2457
Michael Layzell734adb42017-06-07 16:58:31 -04002458 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002459 impl ToTokens for ExprWhile {
2460 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002461 if self.label.is_some() {
2462 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002463 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002464 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002465 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002466 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 self.body.to_tokens(tokens);
2468 }
2469 }
2470
Michael Layzell734adb42017-06-07 16:58:31 -04002471 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002472 impl ToTokens for ExprWhileLet {
2473 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002474 if self.label.is_some() {
2475 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002476 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002477 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002478 self.while_token.to_tokens(tokens);
2479 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002480 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002481 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002482 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002483 self.body.to_tokens(tokens);
2484 }
2485 }
2486
Michael Layzell734adb42017-06-07 16:58:31 -04002487 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002488 impl ToTokens for ExprForLoop {
2489 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002490 if self.label.is_some() {
2491 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002492 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002493 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002494 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002495 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002496 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002497 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002498 self.body.to_tokens(tokens);
2499 }
2500 }
2501
Michael Layzell734adb42017-06-07 16:58:31 -04002502 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002503 impl ToTokens for ExprLoop {
2504 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002505 if self.label.is_some() {
2506 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002507 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002508 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002509 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002510 self.body.to_tokens(tokens);
2511 }
2512 }
2513
Michael Layzell734adb42017-06-07 16:58:31 -04002514 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002515 impl ToTokens for ExprMatch {
2516 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002517 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002518 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002519 self.brace_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002520 for (i, arm) in self.arms.iter().enumerate() {
2521 arm.to_tokens(tokens);
2522 // Ensure that we have a comma after a non-block arm, except
2523 // for the last one.
2524 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002525 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002526 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002527 }
2528 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002529 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002530 }
2531 }
2532
Michael Layzell734adb42017-06-07 16:58:31 -04002533 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002534 impl ToTokens for ExprCatch {
2535 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002536 self.do_token.to_tokens(tokens);
2537 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002538 self.block.to_tokens(tokens);
2539 }
2540 }
2541
Michael Layzell734adb42017-06-07 16:58:31 -04002542 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002543 impl ToTokens for ExprYield {
2544 fn to_tokens(&self, tokens: &mut Tokens) {
2545 self.yield_token.to_tokens(tokens);
2546 self.expr.to_tokens(tokens);
2547 }
2548 }
2549
2550 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002551 impl ToTokens for ExprClosure {
2552 fn to_tokens(&self, tokens: &mut Tokens) {
2553 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002554 self.or1_token.to_tokens(tokens);
2555 for item in self.decl.inputs.iter() {
2556 match **item.item() {
2557 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002559 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002560 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002561 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002562 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002563 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002564 self.or2_token.to_tokens(tokens);
2565 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002566 self.body.to_tokens(tokens);
2567 }
2568 }
2569
Michael Layzell734adb42017-06-07 16:58:31 -04002570 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002571 impl ToTokens for ExprBlock {
2572 fn to_tokens(&self, tokens: &mut Tokens) {
2573 self.unsafety.to_tokens(tokens);
2574 self.block.to_tokens(tokens);
2575 }
2576 }
2577
Michael Layzell734adb42017-06-07 16:58:31 -04002578 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002579 impl ToTokens for ExprAssign {
2580 fn to_tokens(&self, tokens: &mut Tokens) {
2581 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002582 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002583 self.right.to_tokens(tokens);
2584 }
2585 }
2586
Michael Layzell734adb42017-06-07 16:58:31 -04002587 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002588 impl ToTokens for ExprAssignOp {
2589 fn to_tokens(&self, tokens: &mut Tokens) {
2590 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002591 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002592 self.right.to_tokens(tokens);
2593 }
2594 }
2595
Michael Layzell734adb42017-06-07 16:58:31 -04002596 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002597 impl ToTokens for ExprField {
2598 fn to_tokens(&self, tokens: &mut Tokens) {
2599 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002600 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002601 // XXX: I don't think we can do anything if someone shoves a
2602 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002603 self.field.to_tokens(tokens);
2604 }
2605 }
2606
Michael Layzell734adb42017-06-07 16:58:31 -04002607 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002608 impl ToTokens for ExprTupField {
2609 fn to_tokens(&self, tokens: &mut Tokens) {
2610 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002611 self.dot_token.to_tokens(tokens);
2612 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 }
2614 }
2615
2616 impl ToTokens for ExprIndex {
2617 fn to_tokens(&self, tokens: &mut Tokens) {
2618 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002619 self.bracket_token.surround(tokens, |tokens| {
2620 self.index.to_tokens(tokens);
2621 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002622 }
2623 }
2624
Michael Layzell734adb42017-06-07 16:58:31 -04002625 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002626 impl ToTokens for ExprRange {
2627 fn to_tokens(&self, tokens: &mut Tokens) {
2628 self.from.to_tokens(tokens);
2629 self.limits.to_tokens(tokens);
2630 self.to.to_tokens(tokens);
2631 }
2632 }
2633
2634 impl ToTokens for ExprPath {
2635 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002636 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002637 }
2638 }
2639
Michael Layzell734adb42017-06-07 16:58:31 -04002640 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002641 impl ToTokens for ExprAddrOf {
2642 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002643 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002644 self.mutbl.to_tokens(tokens);
2645 self.expr.to_tokens(tokens);
2646 }
2647 }
2648
Michael Layzell734adb42017-06-07 16:58:31 -04002649 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002650 impl ToTokens for ExprBreak {
2651 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002652 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 self.label.to_tokens(tokens);
2654 self.expr.to_tokens(tokens);
2655 }
2656 }
2657
Michael Layzell734adb42017-06-07 16:58:31 -04002658 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002659 impl ToTokens for ExprContinue {
2660 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002661 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002662 self.label.to_tokens(tokens);
2663 }
2664 }
2665
Michael Layzell734adb42017-06-07 16:58:31 -04002666 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002667 impl ToTokens for ExprRet {
2668 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002669 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002670 self.expr.to_tokens(tokens);
2671 }
2672 }
2673
Michael Layzell734adb42017-06-07 16:58:31 -04002674 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002675 impl ToTokens for ExprStruct {
2676 fn to_tokens(&self, tokens: &mut Tokens) {
2677 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002678 self.brace_token.surround(tokens, |tokens| {
2679 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002680 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002681 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002682 self.rest.to_tokens(tokens);
2683 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002684 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002685 }
2686 }
2687
Michael Layzell734adb42017-06-07 16:58:31 -04002688 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002689 impl ToTokens for ExprRepeat {
2690 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002691 self.bracket_token.surround(tokens, |tokens| {
2692 self.expr.to_tokens(tokens);
2693 self.semi_token.to_tokens(tokens);
2694 self.amt.to_tokens(tokens);
2695 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002696 }
2697 }
2698
Michael Layzell93c36282017-06-04 20:43:14 -04002699 impl ToTokens for ExprGroup {
2700 fn to_tokens(&self, tokens: &mut Tokens) {
2701 self.group_token.surround(tokens, |tokens| {
2702 self.expr.to_tokens(tokens);
2703 });
2704 }
2705 }
2706
Alex Crichton62a0a592017-05-22 13:58:53 -07002707 impl ToTokens for ExprParen {
2708 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002709 self.paren_token.surround(tokens, |tokens| {
2710 self.expr.to_tokens(tokens);
2711 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002712 }
2713 }
2714
Michael Layzell734adb42017-06-07 16:58:31 -04002715 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002716 impl ToTokens for ExprTry {
2717 fn to_tokens(&self, tokens: &mut Tokens) {
2718 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002719 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002720 }
2721 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002722
Michael Layzell734adb42017-06-07 16:58:31 -04002723 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002724 impl ToTokens for FieldValue {
2725 fn to_tokens(&self, tokens: &mut Tokens) {
2726 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002727 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2728 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002729 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002730 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002731 self.expr.to_tokens(tokens);
2732 }
David Tolnay055a7042016-10-02 19:23:54 -07002733 }
2734 }
2735
Michael Layzell734adb42017-06-07 16:58:31 -04002736 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002737 impl ToTokens for Arm {
2738 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002739 tokens.append_all(&self.attrs);
2740 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002741 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002742 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002743 self.guard.to_tokens(tokens);
2744 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002745 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002746 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002747 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002748 }
2749 }
2750
Michael Layzell734adb42017-06-07 16:58:31 -04002751 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002752 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002753 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002754 self.underscore_token.to_tokens(tokens);
2755 }
2756 }
2757
Michael Layzell734adb42017-06-07 16:58:31 -04002758 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002759 impl ToTokens for PatIdent {
2760 fn to_tokens(&self, tokens: &mut Tokens) {
2761 self.mode.to_tokens(tokens);
2762 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002763 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002764 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002765 self.subpat.to_tokens(tokens);
2766 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002767 }
2768 }
2769
Michael Layzell734adb42017-06-07 16:58:31 -04002770 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002771 impl ToTokens for PatStruct {
2772 fn to_tokens(&self, tokens: &mut Tokens) {
2773 self.path.to_tokens(tokens);
2774 self.brace_token.surround(tokens, |tokens| {
2775 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002776 // NOTE: We need a comma before the dot2 token if it is present.
2777 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002778 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002779 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002780 self.dot2_token.to_tokens(tokens);
2781 });
2782 }
2783 }
2784
Michael Layzell734adb42017-06-07 16:58:31 -04002785 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002786 impl ToTokens for PatTupleStruct {
2787 fn to_tokens(&self, tokens: &mut Tokens) {
2788 self.path.to_tokens(tokens);
2789 self.pat.to_tokens(tokens);
2790 }
2791 }
2792
Michael Layzell734adb42017-06-07 16:58:31 -04002793 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002794 impl ToTokens for PatPath {
2795 fn to_tokens(&self, tokens: &mut Tokens) {
2796 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2797 }
2798 }
2799
Michael Layzell734adb42017-06-07 16:58:31 -04002800 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002801 impl ToTokens for PatTuple {
2802 fn to_tokens(&self, tokens: &mut Tokens) {
2803 self.paren_token.surround(tokens, |tokens| {
2804 for (i, token) in self.pats.iter().enumerate() {
2805 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002806 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2807 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002808 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002809 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002810 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002811
2812 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002813 // Ensure there is a comma before the .. token.
2814 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002815 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002816 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002817 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002818 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002819 });
2820 }
2821 }
2822
Michael Layzell734adb42017-06-07 16:58:31 -04002823 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002824 impl ToTokens for PatBox {
2825 fn to_tokens(&self, tokens: &mut Tokens) {
2826 self.box_token.to_tokens(tokens);
2827 self.pat.to_tokens(tokens);
2828 }
2829 }
2830
Michael Layzell734adb42017-06-07 16:58:31 -04002831 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002832 impl ToTokens for PatRef {
2833 fn to_tokens(&self, tokens: &mut Tokens) {
2834 self.and_token.to_tokens(tokens);
2835 self.mutbl.to_tokens(tokens);
2836 self.pat.to_tokens(tokens);
2837 }
2838 }
2839
Michael Layzell734adb42017-06-07 16:58:31 -04002840 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002841 impl ToTokens for PatLit {
2842 fn to_tokens(&self, tokens: &mut Tokens) {
2843 self.expr.to_tokens(tokens);
2844 }
2845 }
2846
Michael Layzell734adb42017-06-07 16:58:31 -04002847 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002848 impl ToTokens for PatRange {
2849 fn to_tokens(&self, tokens: &mut Tokens) {
2850 self.lo.to_tokens(tokens);
2851 self.limits.to_tokens(tokens);
2852 self.hi.to_tokens(tokens);
2853 }
2854 }
2855
Michael Layzell734adb42017-06-07 16:58:31 -04002856 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002857 impl ToTokens for PatSlice {
2858 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002859 // XXX: This is a mess, and it will be so easy to screw it up. How
2860 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002861 self.bracket_token.surround(tokens, |tokens| {
2862 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002863
2864 // If we need a comma before the middle or standalone .. token,
2865 // then make sure it's present.
2866 if !self.front.empty_or_trailing() &&
2867 (self.middle.is_some() || self.dot2_token.is_some())
2868 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002869 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002870 }
2871
2872 // If we have an identifier, we always need a .. token.
2873 if self.middle.is_some() {
2874 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002875 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002876 } else if self.dot2_token.is_some() {
2877 self.dot2_token.to_tokens(tokens);
2878 }
2879
2880 // Make sure we have a comma before the back half.
2881 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002882 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002883 self.back.to_tokens(tokens);
2884 } else {
2885 self.comma_token.to_tokens(tokens);
2886 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002887 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002888 }
2889 }
2890
Michael Layzell734adb42017-06-07 16:58:31 -04002891 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002892 impl ToTokens for RangeLimits {
2893 fn to_tokens(&self, tokens: &mut Tokens) {
2894 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002895 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2896 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002897 }
2898 }
2899 }
2900
Michael Layzell734adb42017-06-07 16:58:31 -04002901 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002902 impl ToTokens for FieldPat {
2903 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002904 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002905 if !self.is_shorthand {
2906 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002907 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002908 }
2909 self.pat.to_tokens(tokens);
2910 }
2911 }
2912
Michael Layzell734adb42017-06-07 16:58:31 -04002913 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002914 impl ToTokens for BindingMode {
2915 fn to_tokens(&self, tokens: &mut Tokens) {
2916 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002917 BindingMode::ByRef(ref t, ref m) => {
2918 t.to_tokens(tokens);
2919 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002920 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002921 BindingMode::ByValue(ref m) => {
2922 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002923 }
2924 }
2925 }
2926 }
David Tolnay42602292016-10-01 22:25:45 -07002927
Michael Layzell734adb42017-06-07 16:58:31 -04002928 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002929 impl ToTokens for CaptureBy {
2930 fn to_tokens(&self, tokens: &mut Tokens) {
2931 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002932 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002933 CaptureBy::Ref => {
2934 // nothing
2935 }
David Tolnay89e05672016-10-02 14:39:42 -07002936 }
2937 }
2938 }
2939
Michael Layzell734adb42017-06-07 16:58:31 -04002940 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002941 impl ToTokens for Block {
2942 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002943 self.brace_token.surround(tokens, |tokens| {
2944 tokens.append_all(&self.stmts);
2945 });
David Tolnay42602292016-10-01 22:25:45 -07002946 }
2947 }
2948
Michael Layzell734adb42017-06-07 16:58:31 -04002949 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002950 impl ToTokens for Stmt {
2951 fn to_tokens(&self, tokens: &mut Tokens) {
2952 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002953 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002954 Stmt::Item(ref item) => item.to_tokens(tokens),
2955 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002956 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002957 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002958 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002959 }
David Tolnaydecf28d2017-11-11 11:56:45 -08002960 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002961 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002962 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002963 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002964 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002965 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002966 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2967 // no semicolon
2968 }
David Tolnay13b3d352016-10-03 00:31:15 -07002969 }
2970 }
David Tolnay42602292016-10-01 22:25:45 -07002971 }
2972 }
2973 }
David Tolnay191e0582016-10-02 18:31:09 -07002974
Michael Layzell734adb42017-06-07 16:58:31 -04002975 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002976 impl ToTokens for Local {
2977 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002978 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002979 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002980 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002981 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002982 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002983 self.ty.to_tokens(tokens);
2984 }
2985 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002986 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002987 self.init.to_tokens(tokens);
2988 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002989 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002990 }
2991 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002992}