blob: 1344b075512777c1f095e0a5264bfd3c441b1bdf [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay85b69a42017-12-27 20:43:10 -05003#[cfg(feature = "full")]
4use proc_macro2::Span;
5#[cfg(feature = "full")]
6use std::hash::{Hash, Hasher};
David Tolnayf4bbbd92016-09-23 14:41:55 -07007
Alex Crichton62a0a592017-05-22 13:58:53 -07008ast_struct! {
9 /// An expression.
10 pub struct Expr {
11 /// Type of the expression.
12 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -050013
Alex Crichton62a0a592017-05-22 13:58:53 -070014 /// Attributes tagged on the expression.
15 pub attrs: Vec<Attribute>,
16 }
David Tolnay7184b132016-10-30 10:06:37 -070017}
18
19impl From<ExprKind> for Expr {
20 fn from(node: ExprKind) -> Expr {
21 Expr {
22 node: node,
23 attrs: Vec::new(),
24 }
25 }
26}
27
Alex Crichton62a0a592017-05-22 13:58:53 -070028ast_enum_of_structs! {
29 pub enum ExprKind {
30 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040031 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070032 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080033 pub box_token: Token![box],
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
Clar Charrd22b5702017-03-10 15:24:56 -050035
Michael Layzellb78f3b52017-06-04 19:03:03 -040036 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040037 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070038 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040039 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070040 pub value: Box<Expr>,
41 }),
Clar Charrd22b5702017-03-10 15:24:56 -050042
Alex Crichton62a0a592017-05-22 13:58:53 -070043 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040044 pub Array(ExprArray #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080045 pub exprs: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050046 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070047 }),
Clar Charrd22b5702017-03-10 15:24:56 -050048
Alex Crichton62a0a592017-05-22 13:58:53 -070049 /// A function call.
50 pub Call(ExprCall {
51 pub func: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080052 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050053 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070054 }),
Clar Charrd22b5702017-03-10 15:24:56 -050055
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
57 ///
58 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080059 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070060 /// (within the angle brackets).
61 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070062 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
63 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040064 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070066 pub method: Ident,
David Tolnayfd6bf5c2017-11-12 09:41:14 -080067 pub typarams: Delimited<Type, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080068 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050069 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080070 pub dot_token: Token![.],
71 pub lt_token: Option<Token![<]>,
72 pub colon2_token: Option<Token![::]>,
73 pub gt_token: Option<Token![>]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 }),
Clar Charrd22b5702017-03-10 15:24:56 -050075
Alex Crichton62a0a592017-05-22 13:58:53 -070076 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050077 pub Tuple(ExprTuple #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -080078 pub args: Delimited<Expr, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -050079 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080080 pub lone_comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070081 }),
Clar Charrd22b5702017-03-10 15:24:56 -050082
Alex Crichton62a0a592017-05-22 13:58:53 -070083 /// A binary operation, e.g. `a + b`, `a * b`.
84 pub Binary(ExprBinary {
85 pub op: BinOp,
86 pub left: Box<Expr>,
87 pub right: Box<Expr>,
88 }),
Clar Charrd22b5702017-03-10 15:24:56 -050089
Alex Crichton62a0a592017-05-22 13:58:53 -070090 /// A unary operation, e.g. `!x`, `*x`.
91 pub Unary(ExprUnary {
92 pub op: UnOp,
93 pub expr: Box<Expr>,
94 }),
Clar Charrd22b5702017-03-10 15:24:56 -050095
Alex Crichton62a0a592017-05-22 13:58:53 -070096 /// A literal, e.g. `1`, `"foo"`.
97 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050098
Alex Crichton62a0a592017-05-22 13:58:53 -070099 /// A cast, e.g. `foo as f64`.
100 pub Cast(ExprCast {
101 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800102 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800103 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500105
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 /// A type ascription, e.g. `foo: f64`.
107 pub Type(ExprType {
108 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800109 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800110 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500112
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 /// An `if` block, with an optional else block
114 ///
115 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400116 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700117 pub cond: Box<Expr>,
118 pub if_true: Block,
119 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800120 pub if_token: Token![if],
121 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700122 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500123
Alex Crichton62a0a592017-05-22 13:58:53 -0700124 /// An `if let` expression with an optional else block
125 ///
126 /// E.g., `if let pat = expr { block } else { expr }`
127 ///
128 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400129 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700130 pub pat: Box<Pat>,
131 pub expr: Box<Expr>,
132 pub if_true: Block,
133 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800134 pub if_token: Token![if],
135 pub let_token: Token![let],
136 pub eq_token: Token![=],
137 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700138 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500139
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 /// A while loop, with an optional label
141 ///
142 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400143 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700144 pub cond: Box<Expr>,
145 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700146 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800147 pub colon_token: Option<Token![:]>,
148 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700149 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500150
Alex Crichton62a0a592017-05-22 13:58:53 -0700151 /// A while-let loop, with an optional label.
152 ///
153 /// E.g., `'label: while let pat = expr { block }`
154 ///
155 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400156 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700157 pub pat: Box<Pat>,
158 pub expr: Box<Expr>,
159 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700160 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800161 pub colon_token: Option<Token![:]>,
162 pub while_token: Token![while],
163 pub let_token: Token![let],
164 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700165 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500166
Alex Crichton62a0a592017-05-22 13:58:53 -0700167 /// A for loop, with an optional label.
168 ///
169 /// E.g., `'label: for pat in expr { block }`
170 ///
171 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400172 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 pub pat: Box<Pat>,
174 pub expr: Box<Expr>,
175 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700176 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800177 pub for_token: Token![for],
178 pub colon_token: Option<Token![:]>,
179 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700180 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500181
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 /// Conditionless loop with an optional label.
183 ///
184 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400185 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700187 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800188 pub loop_token: Token![loop],
189 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500191
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400193 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800194 pub match_token: Token![match],
David Tolnay32954ef2017-12-26 22:43:16 -0500195 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 pub expr: Box<Expr>,
197 pub arms: Vec<Arm>,
198 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500199
Alex Crichton62a0a592017-05-22 13:58:53 -0700200 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400201 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700202 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800203 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500204 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800205 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500206 pub output: ReturnType,
207 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700208 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500209
Nika Layzell640832a2017-12-04 13:37:09 -0500210 /// An unsafe block (`unsafe { ... }`)
211 pub Unsafe(ExprUnsafe #full {
212 pub unsafe_token: Token![unsafe],
213 pub block: Block,
214 }),
215
216 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400217 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 pub block: Block,
219 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700220
Alex Crichton62a0a592017-05-22 13:58:53 -0700221 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400222 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800225 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700226 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500227
Alex Crichton62a0a592017-05-22 13:58:53 -0700228 /// An assignment with an operator
229 ///
230 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400231 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 pub op: BinOp,
233 pub left: Box<Expr>,
234 pub right: Box<Expr>,
235 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500236
David Tolnay85b69a42017-12-27 20:43:10 -0500237 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
238 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400239 pub Field(ExprField #full {
David Tolnay85b69a42017-12-27 20:43:10 -0500240 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800241 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500242 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500244
Alex Crichton62a0a592017-05-22 13:58:53 -0700245 /// An indexing operation (`foo[2]`)
246 pub Index(ExprIndex {
247 pub expr: Box<Expr>,
248 pub index: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500249 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500251
David Tolnaybe55d7b2017-12-17 23:41:20 -0800252 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400253 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 pub from: Option<Box<Expr>>,
255 pub to: Option<Box<Expr>>,
256 pub limits: RangeLimits,
257 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700258
Alex Crichton62a0a592017-05-22 13:58:53 -0700259 /// Variable reference, possibly containing `::` and/or type
260 /// parameters, e.g. foo::bar::<baz>.
261 ///
262 /// Optionally "qualified",
263 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
264 pub Path(ExprPath {
265 pub qself: Option<QSelf>,
266 pub path: Path,
267 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700268
Alex Crichton62a0a592017-05-22 13:58:53 -0700269 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400270 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800271 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700272 pub mutbl: Mutability,
273 pub expr: Box<Expr>,
274 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500275
Alex Crichton62a0a592017-05-22 13:58:53 -0700276 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400277 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700278 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800280 pub break_token: Token![break],
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500282
Alex Crichton62a0a592017-05-22 13:58:53 -0700283 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400284 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700285 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800286 pub continue_token: Token![continue],
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500288
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400290 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800292 pub return_token: Token![return],
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700294
Alex Crichton62a0a592017-05-22 13:58:53 -0700295 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800296 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700297
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 /// A struct literal expression.
299 ///
300 /// For example, `Foo {x: 1, y: 2}`, or
301 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400302 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800304 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700305 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800306 pub dot2_token: Option<Token![..]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500307 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700309
Alex Crichton62a0a592017-05-22 13:58:53 -0700310 /// An array literal constructed from one repeated element.
311 ///
312 /// For example, `[1; 5]`. The first expression is the element
313 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400314 pub Repeat(ExprRepeat #full {
David Tolnay32954ef2017-12-26 22:43:16 -0500315 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800316 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700317 pub expr: Box<Expr>,
318 pub amt: Box<Expr>,
319 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700320
Alex Crichton62a0a592017-05-22 13:58:53 -0700321 /// No-op: used solely so we can pretty-print faithfully
322 pub Paren(ExprParen {
323 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500324 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700325 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700326
Michael Layzell93c36282017-06-04 20:43:14 -0400327 /// No-op: used solely so we can pretty-print faithfully
328 ///
329 /// A `group` represents a `None`-delimited span in the input
330 /// `TokenStream` which affects the precidence of the resulting
331 /// expression. They are used for macro hygiene.
332 pub Group(ExprGroup {
333 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500334 pub group_token: token::Group,
Michael Layzell93c36282017-06-04 20:43:14 -0400335 }),
336
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400338 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800340 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700341 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700342
Alex Crichton62a0a592017-05-22 13:58:53 -0700343 /// A catch expression.
344 ///
345 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400346 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800347 pub do_token: Token![do],
348 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700349 pub block: Block,
350 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700351
352 /// A yield expression.
353 ///
354 /// E.g. `yield expr`
355 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800356 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700357 pub expr: Option<Box<Expr>>,
358 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700359 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700360}
361
Michael Layzell734adb42017-06-07 16:58:31 -0400362#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500363ast_enum! {
364 /// A struct or tuple struct field accessed in a struct literal or field
365 /// expression.
366 pub enum Member {
367 /// A named field like `self.x`.
368 Named(Ident),
369 /// An unnamed field like `self.0`.
370 Unnamed(Index),
371 }
372}
373
374#[cfg(feature = "full")]
375ast_struct! {
376 /// The index of an unnamed tuple struct field.
377 pub struct Index #manual_extra_traits {
378 pub index: u32,
379 pub span: Span,
380 }
381}
382
383#[cfg(feature = "full")]
384impl Eq for Index {}
385
386#[cfg(feature = "full")]
387impl PartialEq for Index {
388 fn eq(&self, other: &Self) -> bool {
389 self.index == other.index
390 }
391}
392
393#[cfg(feature = "full")]
394impl Hash for Index {
395 fn hash<H: Hasher>(&self, state: &mut H) {
396 self.index.hash(state);
397 }
398}
399
400#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700401ast_struct! {
402 /// A field-value pair in a struct literal.
403 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500404 /// Attributes tagged on the field.
405 pub attrs: Vec<Attribute>,
406
407 /// Name or index of the field.
408 pub member: Member,
409
410 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500411
Alex Crichton62a0a592017-05-22 13:58:53 -0700412 /// Value of the field.
413 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500414
Alex Crichton62a0a592017-05-22 13:58:53 -0700415 /// Whether this is a shorthand field, e.g. `Struct { x }`
416 /// instead of `Struct { x: x }`.
417 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 }
David Tolnay055a7042016-10-02 19:23:54 -0700419}
420
Michael Layzell734adb42017-06-07 16:58:31 -0400421#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700422ast_struct! {
423 /// A Block (`{ .. }`).
424 ///
425 /// E.g. `{ .. }` as in `fn foo() { .. }`
426 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500427 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700428 /// Statements in a block
429 pub stmts: Vec<Stmt>,
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_enum! {
435 /// A statement, usually ending in a semicolon.
436 pub enum Stmt {
437 /// A local (let) binding.
438 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700439
Alex Crichton62a0a592017-05-22 13:58:53 -0700440 /// An item definition.
441 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700442
Alex Crichton62a0a592017-05-22 13:58:53 -0700443 /// Expr without trailing semicolon.
444 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700445
Alex Crichton62a0a592017-05-22 13:58:53 -0700446 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800447 Semi(Box<Expr>, Token![;]),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700448
Alex Crichton62a0a592017-05-22 13:58:53 -0700449 /// Macro invocation.
David Tolnaydecf28d2017-11-11 11:56:45 -0800450 Macro(Box<(Macro, MacStmtStyle, Vec<Attribute>)>),
Alex Crichton62a0a592017-05-22 13:58:53 -0700451 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700452}
453
Michael Layzell734adb42017-06-07 16:58:31 -0400454#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700455ast_enum! {
456 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700457 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700458 pub enum MacStmtStyle {
459 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
460 /// `foo!(...);`, `foo![...];`
David Tolnayf8db7ba2017-11-11 22:52:16 -0800461 Semicolon(Token![;]),
Clar Charrd22b5702017-03-10 15:24:56 -0500462
Alex Crichton62a0a592017-05-22 13:58:53 -0700463 /// The macro statement had braces; e.g. foo! { ... }
464 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500465
Alex Crichton62a0a592017-05-22 13:58:53 -0700466 /// The macro statement had parentheses or brackets and no semicolon; e.g.
467 /// `foo!(...)`. All of these will end up being converted into macro
468 /// expressions.
469 NoBraces,
470 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700471}
472
Michael Layzell734adb42017-06-07 16:58:31 -0400473#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700474ast_struct! {
475 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
476 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800477 pub let_token: Token![let],
478 pub colon_token: Option<Token![:]>,
479 pub eq_token: Option<Token![=]>,
480 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 pub pat: Box<Pat>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800483 pub ty: Option<Box<Type>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500484
Alex Crichton62a0a592017-05-22 13:58:53 -0700485 /// Initializer expression to set the value, if any
486 pub init: Option<Box<Expr>>,
487 pub attrs: Vec<Attribute>,
488 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489}
490
Michael Layzell734adb42017-06-07 16:58:31 -0400491#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700492ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700493 // Clippy false positive
494 // https://github.com/Manishearth/rust-clippy/issues/1241
495 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
496 pub enum Pat {
497 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700498 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800499 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700500 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700501
Alex Crichton62a0a592017-05-22 13:58:53 -0700502 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
503 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
504 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
505 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700506 pub Ident(PatIdent {
507 pub mode: BindingMode,
508 pub ident: Ident,
509 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800510 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700511 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700512
Alex Crichton62a0a592017-05-22 13:58:53 -0700513 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
514 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Struct(PatStruct {
516 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800517 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500518 pub brace_token: token::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800519 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700520 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700521
Alex Crichton62a0a592017-05-22 13:58:53 -0700522 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
523 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
524 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub TupleStruct(PatTupleStruct {
526 pub path: Path,
527 pub pat: PatTuple,
528 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700529
Alex Crichton62a0a592017-05-22 13:58:53 -0700530 /// A possibly qualified path pattern.
531 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
532 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
533 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700534 pub Path(PatPath {
535 pub qself: Option<QSelf>,
536 pub path: Path,
537 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700538
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// A tuple pattern `(a, b)`.
540 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
541 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700542 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800543 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700544 pub dots_pos: Option<usize>,
David Tolnay32954ef2017-12-26 22:43:16 -0500545 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800546 pub dot2_token: Option<Token![..]>,
547 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700548 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700549 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700550 pub Box(PatBox {
551 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800552 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700553 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 pub Ref(PatRef {
556 pub pat: Box<Pat>,
557 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800558 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700559 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700561 pub Lit(PatLit {
562 pub expr: Box<Expr>,
563 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800564 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700565 pub Range(PatRange {
566 pub lo: Box<Expr>,
567 pub hi: Box<Expr>,
568 pub limits: RangeLimits,
569 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400570 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700571 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800572 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700573 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800574 pub back: Delimited<Pat, Token![,]>,
575 pub dot2_token: Option<Token![..]>,
576 pub comma_token: Option<Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500577 pub bracket_token: token::Bracket,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700578 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700579 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800580 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700582}
583
Michael Layzell734adb42017-06-07 16:58:31 -0400584#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700585ast_struct! {
586 /// An arm of a 'match'.
587 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800588 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700589 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500590 /// ```rust
591 /// # #![feature(dotdoteq_in_patterns)]
592 /// #
593 /// # fn main() {
594 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700595 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500596 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700597 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500598 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700599 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500600 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700601 /// ```
602 pub struct Arm {
603 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800604 pub pats: Delimited<Pat, Token![|]>,
605 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700606 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800607 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700608 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800609 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700611}
612
Michael Layzell734adb42017-06-07 16:58:31 -0400613#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700614ast_enum! {
615 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700616 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700617 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800618 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700619 Ref,
620 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700621}
622
Michael Layzell734adb42017-06-07 16:58:31 -0400623#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700624ast_enum! {
625 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700626 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700627 pub enum RangeLimits {
628 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800629 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700630 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800631 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700632 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700633}
634
Michael Layzell734adb42017-06-07 16:58:31 -0400635#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700636ast_struct! {
637 /// A single field in a struct pattern
638 ///
639 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
640 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
641 /// except `is_shorthand` is true
642 pub struct FieldPat {
643 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500644 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700645 /// The pattern the field is destructured to
646 pub pat: Box<Pat>,
647 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800648 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700649 pub attrs: Vec<Attribute>,
650 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700651}
652
Michael Layzell734adb42017-06-07 16:58:31 -0400653#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700654ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700655 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700656 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800657 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700658 ByValue(Mutability),
659 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700660}
661
Michael Layzell734adb42017-06-07 16:58:31 -0400662#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400663ast_enum! {
664 #[cfg_attr(feature = "clone-impls", derive(Copy))]
665 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800666 Arrow(Token![<-]),
667 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400668 }
669}
670
Michael Layzell3936ceb2017-07-08 00:28:36 -0400671#[cfg(any(feature = "parsing", feature = "printing"))]
672#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700673fn arm_expr_requires_comma(expr: &Expr) -> bool {
674 // see https://github.com/rust-lang/rust/blob/eb8f2586e
675 // /src/libsyntax/parse/classify.rs#L17-L37
676 match expr.node {
David Tolnay51382052017-12-27 13:46:21 -0500677 ExprKind::Unsafe(..)
678 | ExprKind::Block(..)
679 | ExprKind::If(..)
680 | ExprKind::IfLet(..)
681 | ExprKind::Match(..)
682 | ExprKind::While(..)
683 | ExprKind::WhileLet(..)
684 | ExprKind::Loop(..)
685 | ExprKind::ForLoop(..)
686 | ExprKind::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700687 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400688 }
689}
690
David Tolnayb9c8e322016-09-23 20:48:37 -0700691#[cfg(feature = "parsing")]
692pub mod parsing {
693 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700694 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700695
Michael Layzell734adb42017-06-07 16:58:31 -0400696 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500697 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500698 use synom::Synom;
699 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400700 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500701 use parse_error;
702 use PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700703
David Tolnaybcf26022017-12-25 22:10:52 -0500704 // When we're parsing expressions which occur before blocks, like in an if
705 // statement's condition, we cannot parse a struct literal.
706 //
707 // Struct literals are ambiguous in certain positions
708 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700709 macro_rules! ambiguous_expr {
710 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700711 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700712 };
713 }
714
David Tolnaybcf26022017-12-25 22:10:52 -0500715 // When we are parsing an optional suffix expression, we cannot allow blocks
716 // if structs are not allowed.
717 //
718 // Example:
719 //
720 // if break {} {}
721 //
722 // is ambiguous between:
723 //
724 // if (break {}) {}
725 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400726 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400727 macro_rules! opt_ambiguous_expr {
728 ($i:expr, $allow_struct:ident) => {
729 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
730 };
731 }
732
Alex Crichton954046c2017-05-30 21:49:42 -0700733 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400734 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700735
736 fn description() -> Option<&'static str> {
737 Some("expression")
738 }
739 }
740
Michael Layzell734adb42017-06-07 16:58:31 -0400741 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700742 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
743
David Tolnaybcf26022017-12-25 22:10:52 -0500744 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400745 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500746 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400747 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700748 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400749 call!(assign_expr, allow_struct, allow_block),
750 ExprKind::into
751 )
752 }
753
Michael Layzell734adb42017-06-07 16:58:31 -0400754 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500755 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzell734adb42017-06-07 16:58:31 -0400756 map!(
757 i,
758 // NOTE: We intentionally skip assign_expr, placement_expr, and
759 // range_expr, as they are not parsed in non-full mode.
760 call!(or_expr, allow_struct, allow_block),
761 ExprKind::into
762 )
763 }
764
David Tolnaybcf26022017-12-25 22:10:52 -0500765 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400766 macro_rules! binop {
767 (
768 $name: ident,
769 $next: ident,
770 $submac: ident!( $($args:tt)* )
771 ) => {
772 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
773 mut e: call!($next, allow_struct, allow_block) >>
774 many0!(do_parse!(
775 op: $submac!($($args)*) >>
776 rhs: call!($next, allow_struct, true) >>
777 ({
778 e = ExprBinary {
779 left: Box::new(e.into()),
780 op: op,
781 right: Box::new(rhs.into()),
782 }.into();
783 })
784 )) >>
785 (e)
786 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700787 }
David Tolnay54e854d2016-10-24 12:03:30 -0700788 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700789
David Tolnaybcf26022017-12-25 22:10:52 -0500790 // <placement> = <placement> ..
791 // <placement> += <placement> ..
792 // <placement> -= <placement> ..
793 // <placement> *= <placement> ..
794 // <placement> /= <placement> ..
795 // <placement> %= <placement> ..
796 // <placement> ^= <placement> ..
797 // <placement> &= <placement> ..
798 // <placement> |= <placement> ..
799 // <placement> <<= <placement> ..
800 // <placement> >>= <placement> ..
801 //
802 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400803 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400804 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
805 mut e: call!(placement_expr, allow_struct, allow_block) >>
806 alt!(
807 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800808 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400809 // Recurse into self to parse right-associative operator.
810 rhs: call!(assign_expr, allow_struct, true) >>
811 ({
812 e = ExprAssign {
813 left: Box::new(e.into()),
814 eq_token: eq,
815 right: Box::new(rhs.into()),
816 }.into();
817 })
818 )
819 |
820 do_parse!(
821 op: call!(BinOp::parse_assign_op) >>
822 // Recurse into self to parse right-associative operator.
823 rhs: call!(assign_expr, allow_struct, true) >>
824 ({
825 e = ExprAssignOp {
826 left: Box::new(e.into()),
827 op: op,
828 right: Box::new(rhs.into()),
829 }.into();
830 })
831 )
832 |
833 epsilon!()
834 ) >>
835 (e)
836 ));
837
David Tolnaybcf26022017-12-25 22:10:52 -0500838 // <range> <- <range> ..
839 //
840 // NOTE: The `in place { expr }` version of this syntax is parsed in
841 // `atom_expr`, not here.
842 //
843 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400844 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400845 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
846 mut e: call!(range_expr, allow_struct, allow_block) >>
847 alt!(
848 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800849 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400850 // Recurse into self to parse right-associative operator.
851 rhs: call!(placement_expr, allow_struct, true) >>
852 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400853 e = ExprInPlace {
854 // op: BinOp::Place(larrow),
855 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400856 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400857 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400858 }.into();
859 })
860 )
861 |
862 epsilon!()
863 ) >>
864 (e)
865 ));
866
David Tolnaybcf26022017-12-25 22:10:52 -0500867 // <or> ... <or> ..
868 // <or> .. <or> ..
869 // <or> ..
870 //
871 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
872 // rules are for parsing these expressions are, but this is not correct.
873 // For example, `a .. b .. c` is not a legal expression. It should not
874 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
875 //
876 // NOTE: The form of ranges which don't include a preceding expression are
877 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400878 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400879 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
880 mut e: call!(or_expr, allow_struct, allow_block) >>
881 many0!(do_parse!(
882 limits: syn!(RangeLimits) >>
883 // We don't want to allow blocks here if we don't allow structs. See
884 // the reasoning for `opt_ambiguous_expr!` above.
885 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
886 ({
887 e = ExprRange {
888 from: Some(Box::new(e.into())),
889 limits: limits,
890 to: hi.map(|e| Box::new(e.into())),
891 }.into();
892 })
893 )) >>
894 (e)
895 ));
896
David Tolnaybcf26022017-12-25 22:10:52 -0500897 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800898 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400899
David Tolnaybcf26022017-12-25 22:10:52 -0500900 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800901 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902
David Tolnaybcf26022017-12-25 22:10:52 -0500903 // <bitor> == <bitor> ...
904 // <bitor> != <bitor> ...
905 // <bitor> >= <bitor> ...
906 // <bitor> <= <bitor> ...
907 // <bitor> > <bitor> ...
908 // <bitor> < <bitor> ...
909 //
910 // NOTE: This operator appears to be parsed as left-associative, but errors
911 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500912 binop!(
913 compare_expr,
914 bitor_expr,
915 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800916 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400917 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800918 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400919 |
920 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800921 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400922 |
923 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800924 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400925 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400926 do_parse!(
927 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800928 not!(punct!(<-)) >>
929 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400930 (BinOp::Lt(t))
931 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400932 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800933 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500934 )
935 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400936
David Tolnaybcf26022017-12-25 22:10:52 -0500937 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500938 binop!(
939 bitor_expr,
940 bitxor_expr,
941 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
942 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400943
David Tolnaybcf26022017-12-25 22:10:52 -0500944 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500945 binop!(
946 bitxor_expr,
947 bitand_expr,
948 do_parse!(
949 // NOTE: Make sure we aren't looking at ^=.
950 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
951 )
952 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400953
David Tolnaybcf26022017-12-25 22:10:52 -0500954 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -0500955 binop!(
956 bitand_expr,
957 shift_expr,
958 do_parse!(
959 // NOTE: Make sure we aren't looking at && or &=.
960 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
961 )
962 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400963
David Tolnaybcf26022017-12-25 22:10:52 -0500964 // <arith> << <arith> ...
965 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -0500966 binop!(
967 shift_expr,
968 arith_expr,
969 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800970 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400971 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800972 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -0500973 )
974 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400975
David Tolnaybcf26022017-12-25 22:10:52 -0500976 // <term> + <term> ...
977 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -0500978 binop!(
979 arith_expr,
980 term_expr,
981 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800982 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400983 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800984 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -0500985 )
986 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400987
David Tolnaybcf26022017-12-25 22:10:52 -0500988 // <cast> * <cast> ...
989 // <cast> / <cast> ...
990 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -0500991 binop!(
992 term_expr,
993 cast_expr,
994 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800995 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400996 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800997 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400998 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800999 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -05001000 )
1001 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001002
David Tolnaybcf26022017-12-25 22:10:52 -05001003 // <unary> as <ty>
1004 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001005 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1006 mut e: call!(unary_expr, allow_struct, allow_block) >>
1007 many0!(alt!(
1008 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001009 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001010 // We can't accept `A + B` in cast expressions, as it's
1011 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001012 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001013 ({
1014 e = ExprCast {
1015 expr: Box::new(e.into()),
1016 as_token: as_,
1017 ty: Box::new(ty),
1018 }.into();
1019 })
1020 )
1021 |
1022 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001023 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001024 // We can't accept `A + B` in cast expressions, as it's
1025 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001026 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001027 ({
1028 e = ExprType {
1029 expr: Box::new(e.into()),
1030 colon_token: colon,
1031 ty: Box::new(ty),
1032 }.into();
1033 })
1034 )
1035 )) >>
1036 (e)
1037 ));
1038
David Tolnaybcf26022017-12-25 22:10:52 -05001039 // <UnOp> <trailer>
1040 // & <trailer>
1041 // &mut <trailer>
1042 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001043 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001044 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1045 do_parse!(
1046 op: syn!(UnOp) >>
1047 expr: call!(unary_expr, allow_struct, true) >>
1048 (ExprUnary {
1049 op: op,
1050 expr: Box::new(expr.into()),
1051 }.into())
1052 )
1053 |
1054 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001055 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001056 mutability: syn!(Mutability) >>
1057 expr: call!(unary_expr, allow_struct, true) >>
1058 (ExprAddrOf {
1059 and_token: and,
1060 mutbl: mutability,
1061 expr: Box::new(expr.into()),
1062 }.into())
1063 )
1064 |
1065 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001066 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001067 expr: call!(unary_expr, allow_struct, true) >>
1068 (ExprBox {
1069 box_token: box_,
1070 expr: Box::new(expr.into()),
1071 }.into())
1072 )
1073 |
1074 call!(trailer_expr, allow_struct, allow_block)
1075 ));
1076
Michael Layzell734adb42017-06-07 16:58:31 -04001077 // XXX: This duplication is ugly
1078 #[cfg(not(feature = "full"))]
1079 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1080 do_parse!(
1081 op: syn!(UnOp) >>
1082 expr: call!(unary_expr, allow_struct, true) >>
1083 (ExprUnary {
1084 op: op,
1085 expr: Box::new(expr.into()),
1086 }.into())
1087 )
1088 |
1089 call!(trailer_expr, allow_struct, allow_block)
1090 ));
1091
David Tolnaybcf26022017-12-25 22:10:52 -05001092 // <atom> (..<args>) ...
1093 // <atom> . <ident> (..<args>) ...
1094 // <atom> . <ident> ...
1095 // <atom> . <lit> ...
1096 // <atom> [ <expr> ] ...
1097 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001098 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001099 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1100 mut e: call!(atom_expr, allow_struct, allow_block) >>
1101 many0!(alt!(
1102 tap!(args: and_call => {
1103 let (args, paren) = args;
1104 e = ExprCall {
1105 func: Box::new(e.into()),
1106 args: args,
1107 paren_token: paren,
1108 }.into();
1109 })
1110 |
1111 tap!(more: and_method_call => {
1112 let mut call = more;
1113 call.expr = Box::new(e.into());
1114 e = call.into();
1115 })
1116 |
1117 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001118 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001119 e = ExprField {
David Tolnay85b69a42017-12-27 20:43:10 -05001120 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001121 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001122 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001123 }.into();
1124 })
1125 |
1126 tap!(i: and_index => {
1127 let (i, token) = i;
1128 e = ExprIndex {
1129 expr: Box::new(e.into()),
1130 bracket_token: token,
1131 index: Box::new(i),
1132 }.into();
1133 })
1134 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001135 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001136 e = ExprTry {
1137 expr: Box::new(e.into()),
1138 question_token: question,
1139 }.into();
1140 })
1141 )) >>
1142 (e)
1143 ));
1144
Michael Layzell734adb42017-06-07 16:58:31 -04001145 // XXX: Duplication == ugly
1146 #[cfg(not(feature = "full"))]
1147 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1148 mut e: call!(atom_expr, allow_struct, allow_block) >>
1149 many0!(alt!(
1150 tap!(args: and_call => {
1151 let (args, paren) = args;
1152 e = ExprCall {
1153 func: Box::new(e.into()),
1154 args: args,
1155 paren_token: paren,
1156 }.into();
1157 })
1158 |
1159 tap!(i: and_index => {
1160 let (i, token) = i;
1161 e = ExprIndex {
1162 expr: Box::new(e.into()),
1163 bracket_token: token,
1164 index: Box::new(i),
1165 }.into();
1166 })
1167 )) >>
1168 (e)
1169 ));
1170
David Tolnaybcf26022017-12-25 22:10:52 -05001171 // Parse all atomic expressions which don't have to worry about precidence
1172 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001173 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001174 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001175 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1176 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001177 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1178 |
1179 // must be before expr_path
1180 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1181 |
1182 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1183 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001184 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001185 |
1186 call!(expr_break, allow_struct) // must be before expr_path
1187 |
1188 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1189 |
1190 call!(expr_ret, allow_struct) // must be before expr_path
1191 |
1192 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1193 syn!(ExprInPlace) => { ExprKind::InPlace }
1194 |
1195 syn!(ExprArray) => { ExprKind::Array }
1196 |
David Tolnay05362582017-12-26 01:33:57 -05001197 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001198 |
1199 syn!(ExprIf) => { ExprKind::If }
1200 |
1201 syn!(ExprIfLet) => { ExprKind::IfLet }
1202 |
1203 syn!(ExprWhile) => { ExprKind::While }
1204 |
1205 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1206 |
1207 syn!(ExprForLoop) => { ExprKind::ForLoop }
1208 |
1209 syn!(ExprLoop) => { ExprKind::Loop }
1210 |
1211 syn!(ExprMatch) => { ExprKind::Match }
1212 |
1213 syn!(ExprCatch) => { ExprKind::Catch }
1214 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001215 syn!(ExprYield) => { ExprKind::Yield }
1216 |
Nika Layzell640832a2017-12-04 13:37:09 -05001217 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1218 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001219 call!(expr_closure, allow_struct)
1220 |
1221 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1222 |
1223 // NOTE: This is the prefix-form of range
1224 call!(expr_range, allow_struct)
1225 |
1226 syn!(ExprPath) => { ExprKind::Path }
1227 |
1228 syn!(ExprRepeat) => { ExprKind::Repeat }
1229 ));
1230
Michael Layzell734adb42017-06-07 16:58:31 -04001231 #[cfg(not(feature = "full"))]
1232 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1233 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1234 |
1235 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1236 |
1237 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1238 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001239 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001240 |
1241 syn!(ExprPath) => { ExprKind::Path }
1242 ));
1243
Michael Layzell734adb42017-06-07 16:58:31 -04001244 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001245 named!(expr_nosemi -> Expr, map!(alt!(
1246 syn!(ExprIf) => { ExprKind::If }
1247 |
1248 syn!(ExprIfLet) => { ExprKind::IfLet }
1249 |
1250 syn!(ExprWhile) => { ExprKind::While }
1251 |
1252 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1253 |
1254 syn!(ExprForLoop) => { ExprKind::ForLoop }
1255 |
1256 syn!(ExprLoop) => { ExprKind::Loop }
1257 |
1258 syn!(ExprMatch) => { ExprKind::Match }
1259 |
1260 syn!(ExprCatch) => { ExprKind::Catch }
1261 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001262 syn!(ExprYield) => { ExprKind::Yield }
1263 |
Nika Layzell640832a2017-12-04 13:37:09 -05001264 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1265 |
Michael Layzell35418782017-06-07 09:20:25 -04001266 syn!(ExprBlock) => { ExprKind::Block }
1267 ), Expr::from));
1268
Michael Layzell93c36282017-06-04 20:43:14 -04001269 impl Synom for ExprGroup {
1270 named!(parse -> Self, do_parse!(
1271 e: grouped!(syn!(Expr)) >>
1272 (ExprGroup {
1273 expr: Box::new(e.0),
1274 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001275 })
Michael Layzell93c36282017-06-04 20:43:14 -04001276 ));
1277 }
1278
Alex Crichton954046c2017-05-30 21:49:42 -07001279 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001280 named!(parse -> Self, do_parse!(
1281 e: parens!(syn!(Expr)) >>
1282 (ExprParen {
1283 expr: Box::new(e.0),
1284 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001285 })
Michael Layzell92639a52017-06-01 00:07:44 -04001286 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001287 }
David Tolnay89e05672016-10-02 14:39:42 -07001288
Michael Layzell734adb42017-06-07 16:58:31 -04001289 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001290 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001291 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001292 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001293 place: expr_no_struct >>
1294 value: braces!(call!(Block::parse_within)) >>
1295 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001296 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001297 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001298 value: Box::new(Expr {
1299 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001300 block: Block {
1301 stmts: value.0,
1302 brace_token: value.1,
1303 },
1304 }.into(),
1305 attrs: Vec::new(),
1306 }),
1307 })
1308 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001309 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001310
Michael Layzell734adb42017-06-07 16:58:31 -04001311 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001312 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001313 named!(parse -> Self, do_parse!(
1314 elems: brackets!(call!(Delimited::parse_terminated)) >>
1315 (ExprArray {
1316 exprs: elems.0,
1317 bracket_token: elems.1,
1318 })
1319 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001320 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001321
David Tolnay32954ef2017-12-26 22:43:16 -05001322 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001323 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001324
Michael Layzell734adb42017-06-07 16:58:31 -04001325 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001326 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001327 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001328 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001329 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001330 colon2: punct!(::) >>
1331 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001332 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001333 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001334 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001335 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001336 args: parens!(call!(Delimited::parse_terminated)) >>
1337 ({
1338 let (colon2, lt, tys, gt) = match typarams {
1339 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1340 None => (None, None, None, None),
1341 };
1342 ExprMethodCall {
1343 // this expr will get overwritten after being returned
1344 expr: Box::new(ExprKind::Lit(Lit {
1345 span: Span::default(),
1346 value: LitKind::Bool(false),
1347 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001348
Alex Crichton954046c2017-05-30 21:49:42 -07001349 method: method,
1350 args: args.0,
1351 paren_token: args.1,
1352 dot_token: dot,
1353 lt_token: lt,
1354 gt_token: gt,
1355 colon2_token: colon2,
1356 typarams: tys.unwrap_or_default(),
1357 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001358 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001359 ));
1360
Michael Layzell734adb42017-06-07 16:58:31 -04001361 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001362 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001363 named!(parse -> Self, do_parse!(
1364 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001365 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001366 args: elems.0,
1367 paren_token: elems.1,
1368 lone_comma: None, // TODO: parse this
1369 })
1370 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001371 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001372
Michael Layzell734adb42017-06-07 16:58:31 -04001373 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001374 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001375 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001376 if_: keyword!(if) >>
1377 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001378 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001379 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001380 cond: expr_no_struct >>
1381 then_block: braces!(call!(Block::parse_within)) >>
1382 else_block: option!(else_block) >>
1383 (ExprIfLet {
1384 pat: Box::new(pat),
1385 let_token: let_,
1386 eq_token: eq,
1387 expr: Box::new(cond),
1388 if_true: Block {
1389 stmts: then_block.0,
1390 brace_token: then_block.1,
1391 },
1392 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001393 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001394 if_false: else_block.map(|p| Box::new(p.1.into())),
1395 })
1396 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001397 }
1398
Michael Layzell734adb42017-06-07 16:58:31 -04001399 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001400 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001401 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001402 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001403 cond: expr_no_struct >>
1404 then_block: braces!(call!(Block::parse_within)) >>
1405 else_block: option!(else_block) >>
1406 (ExprIf {
1407 cond: Box::new(cond),
1408 if_true: Block {
1409 stmts: then_block.0,
1410 brace_token: then_block.1,
1411 },
1412 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001413 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001414 if_false: else_block.map(|p| Box::new(p.1.into())),
1415 })
1416 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001417 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001418
Michael Layzell734adb42017-06-07 16:58:31 -04001419 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001420 named!(else_block -> (Token![else], ExprKind), do_parse!(
1421 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001422 expr: alt!(
1423 syn!(ExprIf) => { ExprKind::If }
1424 |
1425 syn!(ExprIfLet) => { ExprKind::IfLet }
1426 |
1427 do_parse!(
1428 else_block: braces!(call!(Block::parse_within)) >>
1429 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001430 block: Block {
1431 stmts: else_block.0,
1432 brace_token: else_block.1,
1433 },
1434 }))
David Tolnay939766a2016-09-23 23:48:12 -07001435 )
Alex Crichton954046c2017-05-30 21:49:42 -07001436 ) >>
1437 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001438 ));
1439
Michael Layzell734adb42017-06-07 16:58:31 -04001440 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001441 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001442 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001443 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1444 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001445 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001446 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001447 expr: expr_no_struct >>
1448 loop_block: syn!(Block) >>
1449 (ExprForLoop {
1450 for_token: for_,
1451 in_token: in_,
1452 pat: Box::new(pat),
1453 expr: Box::new(expr),
1454 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001455 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001456 label: lbl.map(|p| p.0),
1457 })
1458 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001459 }
Gregory Katze5f35682016-09-27 14:20:55 -04001460
Michael Layzell734adb42017-06-07 16:58:31 -04001461 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001462 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001463 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001464 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1465 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001466 loop_block: syn!(Block) >>
1467 (ExprLoop {
1468 loop_token: loop_,
1469 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001470 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001471 label: lbl.map(|p| p.0),
1472 })
1473 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001474 }
1475
Michael Layzell734adb42017-06-07 16:58:31 -04001476 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001477 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001478 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001479 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001480 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001481 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001482 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001483 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001484 ExprMatch {
1485 expr: Box::new(obj),
1486 match_token: match_,
1487 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001488 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001489 }
1490 })
1491 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001492 }
David Tolnay1978c672016-10-27 22:05:52 -07001493
Michael Layzell734adb42017-06-07 16:58:31 -04001494 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001495 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001496 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001497 do_: keyword!(do) >>
1498 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001499 catch_block: syn!(Block) >>
1500 (ExprCatch {
1501 block: catch_block,
1502 do_token: do_,
1503 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001504 })
Michael Layzell92639a52017-06-01 00:07:44 -04001505 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001506 }
Arnavion02ef13f2017-04-25 00:54:31 -07001507
Michael Layzell734adb42017-06-07 16:58:31 -04001508 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001509 impl Synom for ExprYield {
1510 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001511 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001512 expr: option!(syn!(Expr)) >>
1513 (ExprYield {
1514 yield_token: yield_,
1515 expr: expr.map(Box::new),
1516 })
1517 ));
1518 }
1519
1520 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001521 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001522 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001523 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001524 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001525 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1526 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001527 body: do_parse!(
1528 expr: alt!(expr_nosemi | syn!(Expr)) >>
1529 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1530 map!(input_end!(), |_| None)
1531 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001532 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001533 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001534 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001535 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001536 ) >>
1537 (Arm {
1538 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001539 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001540 attrs: attrs,
1541 pats: pats,
1542 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001543 body: Box::new(body.0),
1544 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001545 })
1546 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001547 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001548
Michael Layzell734adb42017-06-07 16:58:31 -04001549 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001550 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001551 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001552 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001553 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001554 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001555 ret_and_body: alt!(
1556 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001557 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001558 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001559 body: syn!(Block) >>
David Tolnay7f675742017-12-27 22:43:21 -05001560 (ReturnType::Type(Box::new(ty), arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001561 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001562 block: body,
1563 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001564 )
1565 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001566 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001567 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001568 (ExprClosure {
1569 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001570 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001571 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001572 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001573 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001574 body: Box::new(ret_and_body.1),
1575 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001576 ));
1577
Michael Layzell734adb42017-06-07 16:58:31 -04001578 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001579 named!(fn_arg -> FnArg, do_parse!(
1580 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001581 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001582 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001583 if let Some((colon, ty)) = ty {
1584 FnArg::Captured(ArgCaptured {
1585 pat: pat,
1586 colon_token: colon,
1587 ty: ty,
1588 })
1589 } else {
1590 FnArg::Inferred(pat)
1591 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001592 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001593 ));
1594
Michael Layzell734adb42017-06-07 16:58:31 -04001595 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001596 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001597 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001598 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1599 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001600 cond: expr_no_struct >>
1601 while_block: syn!(Block) >>
1602 (ExprWhile {
1603 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001604 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001605 cond: Box::new(cond),
1606 body: while_block,
1607 label: lbl.map(|p| p.0),
1608 })
1609 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001610 }
1611
Michael Layzell734adb42017-06-07 16:58:31 -04001612 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001613 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001614 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001615 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1616 while_: keyword!(while) >>
1617 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001618 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001619 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001620 value: expr_no_struct >>
1621 while_block: syn!(Block) >>
1622 (ExprWhileLet {
1623 eq_token: eq,
1624 let_token: let_,
1625 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001626 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001627 pat: Box::new(pat),
1628 expr: Box::new(value),
1629 body: while_block,
1630 label: lbl.map(|p| p.0),
1631 })
1632 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001633 }
1634
Michael Layzell734adb42017-06-07 16:58:31 -04001635 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001636 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001637 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001638 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001639 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001640 (ExprContinue {
1641 continue_token: cont,
1642 label: lbl,
1643 })
1644 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001645 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001646
Michael Layzell734adb42017-06-07 16:58:31 -04001647 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001648 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001649 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001650 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001651 // We can't allow blocks after a `break` expression when we wouldn't
1652 // allow structs, as this expression is ambiguous.
1653 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001654 (ExprBreak {
1655 label: lbl,
1656 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001657 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001658 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001659 ));
1660
Michael Layzell734adb42017-06-07 16:58:31 -04001661 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001662 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001663 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001664 // NOTE: return is greedy and eats blocks after it even when in a
1665 // position where structs are not allowed, such as in if statement
1666 // conditions. For example:
1667 //
David Tolnaybcf26022017-12-25 22:10:52 -05001668 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001669 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001670 (ExprRet {
1671 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001672 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001673 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001674 ));
1675
Michael Layzell734adb42017-06-07 16:58:31 -04001676 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001677 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001678 named!(parse -> Self, do_parse!(
1679 path: syn!(Path) >>
1680 data: braces!(do_parse!(
1681 fields: call!(Delimited::parse_terminated) >>
1682 base: option!(
1683 cond!(fields.is_empty() || fields.trailing_delim(),
1684 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001685 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001686 base: syn!(Expr) >>
1687 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001688 )
Michael Layzell92639a52017-06-01 00:07:44 -04001689 )
1690 ) >>
1691 (fields, base)
1692 )) >>
1693 ({
1694 let ((fields, base), brace) = data;
1695 let (dots, rest) = match base.and_then(|b| b) {
1696 Some((dots, base)) => (Some(dots), Some(base)),
1697 None => (None, None),
1698 };
1699 ExprStruct {
1700 brace_token: brace,
1701 path: path,
1702 fields: fields,
1703 dot2_token: dots,
1704 rest: rest.map(Box::new),
1705 }
1706 })
1707 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001708 }
1709
Michael Layzell734adb42017-06-07 16:58:31 -04001710 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001711 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001712 named!(parse -> Self, alt!(
1713 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001714 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001715 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001716 value: syn!(Expr) >>
1717 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001718 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001719 expr: value,
1720 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001721 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001722 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001723 })
Michael Layzell92639a52017-06-01 00:07:44 -04001724 )
1725 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001726 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001727 member: Member::Named(name),
Michael Layzell92639a52017-06-01 00:07:44 -04001728 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1729 is_shorthand: true,
1730 attrs: Vec::new(),
1731 colon_token: None,
1732 })
1733 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001734 }
David Tolnay055a7042016-10-02 19:23:54 -07001735
Michael Layzell734adb42017-06-07 16:58:31 -04001736 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001737 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001738 named!(parse -> Self, do_parse!(
1739 data: brackets!(do_parse!(
1740 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001741 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001742 times: syn!(Expr) >>
1743 (value, semi, times)
1744 )) >>
1745 (ExprRepeat {
1746 expr: Box::new((data.0).0),
1747 amt: Box::new((data.0).2),
1748 bracket_token: data.1,
1749 semi_token: (data.0).1,
1750 })
1751 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001752 }
David Tolnay055a7042016-10-02 19:23:54 -07001753
Michael Layzell734adb42017-06-07 16:58:31 -04001754 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001755 impl Synom for ExprUnsafe {
1756 named!(parse -> Self, do_parse!(
1757 unsafe_: keyword!(unsafe) >>
1758 b: syn!(Block) >>
1759 (ExprUnsafe {
1760 unsafe_token: unsafe_,
1761 block: b,
1762 })
1763 ));
1764 }
1765
1766 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001767 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001768 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001769 b: syn!(Block) >>
1770 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001771 block: b,
1772 })
1773 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001774 }
David Tolnay89e05672016-10-02 14:39:42 -07001775
Michael Layzell734adb42017-06-07 16:58:31 -04001776 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001777 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001778 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001779 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001780 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001781 ));
1782
Michael Layzell734adb42017-06-07 16:58:31 -04001783 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001784 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001785 named!(parse -> Self, alt!(
1786 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001787 punct!(..=) => { RangeLimits::Closed }
1788 |
1789 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001790 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001791 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001792 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001793 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001794 }
David Tolnay438c9052016-10-07 23:24:48 -07001795
Alex Crichton954046c2017-05-30 21:49:42 -07001796 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001797 named!(parse -> Self, do_parse!(
1798 pair: qpath >>
1799 (ExprPath {
1800 qself: pair.0,
1801 path: pair.1,
1802 })
1803 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001804 }
David Tolnay42602292016-10-01 22:25:45 -07001805
Michael Layzell734adb42017-06-07 16:58:31 -04001806 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001807 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001808
David Tolnay32954ef2017-12-26 22:43:16 -05001809 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001810
Michael Layzell734adb42017-06-07 16:58:31 -04001811 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001812 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001813 named!(parse -> Self, do_parse!(
1814 stmts: braces!(call!(Block::parse_within)) >>
1815 (Block {
1816 stmts: stmts.0,
1817 brace_token: stmts.1,
1818 })
1819 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001820 }
David Tolnay939766a2016-09-23 23:48:12 -07001821
Michael Layzell734adb42017-06-07 16:58:31 -04001822 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001823 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001824 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001825 many0!(punct!(;)) >>
1826 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001827 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001828 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001829 mut e: syn!(Expr) >>
1830 ({
1831 e.attrs = attrs;
1832 Stmt::Expr(Box::new(e))
1833 })
1834 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001835 (match last {
1836 None => standalone,
1837 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001838 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001839 standalone
1840 }
1841 })
1842 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001843 }
1844
Michael Layzell734adb42017-06-07 16:58:31 -04001845 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001846 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001847 named!(parse -> Self, alt!(
1848 stmt_mac
1849 |
1850 stmt_local
1851 |
1852 stmt_item
1853 |
Michael Layzell35418782017-06-07 09:20:25 -04001854 stmt_blockexpr
1855 |
Michael Layzell92639a52017-06-01 00:07:44 -04001856 stmt_expr
1857 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001858 }
David Tolnay939766a2016-09-23 23:48:12 -07001859
Michael Layzell734adb42017-06-07 16:58:31 -04001860 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001861 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001862 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001863 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001864 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001865 // Only parse braces here; paren and bracket will get parsed as
1866 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001867 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001868 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001869 (Stmt::Macro(Box::new((
1870 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001871 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001872 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001873 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001874 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001875 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001876 },
David Tolnayeea28d62016-10-25 20:44:08 -07001877 },
Alex Crichton954046c2017-05-30 21:49:42 -07001878 match semi {
1879 Some(semi) => MacStmtStyle::Semicolon(semi),
1880 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001881 },
David Tolnayeea28d62016-10-25 20:44:08 -07001882 attrs,
1883 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001884 ));
1885
Michael Layzell734adb42017-06-07 16:58:31 -04001886 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001887 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001888 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001889 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001890 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001891 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001892 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1893 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001894 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001895 let_token: let_,
1896 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001897 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1898 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001899 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001900 ty: ty.map(|p| Box::new(p.1)),
1901 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001902 attrs: attrs,
1903 })))
1904 ));
1905
Michael Layzell734adb42017-06-07 16:58:31 -04001906 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001907 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001908
Michael Layzell734adb42017-06-07 16:58:31 -04001909 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001910 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001911 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04001912 mut e: expr_nosemi >>
1913 // If the next token is a `.` or a `?` it is special-cased to parse as
1914 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001915 not!(punct!(.)) >>
1916 not!(punct!(?)) >>
1917 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001918 ({
1919 e.attrs = attrs;
1920 if let Some(semi) = semi {
1921 Stmt::Semi(Box::new(e), semi)
1922 } else {
1923 Stmt::Expr(Box::new(e))
1924 }
1925 })
1926 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001927
Michael Layzell734adb42017-06-07 16:58:31 -04001928 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001929 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001930 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001931 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001932 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001933 ({
1934 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001935 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001936 })
David Tolnay939766a2016-09-23 23:48:12 -07001937 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001938
Michael Layzell734adb42017-06-07 16:58:31 -04001939 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001940 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001941 named!(parse -> Self, alt!(
1942 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1943 |
1944 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1945 |
1946 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1947 |
1948 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1949 |
1950 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1951 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001952 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001953 |
1954 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1955 |
1956 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1957 |
1958 syn!(PatPath) => { Pat::Path }
1959 |
1960 syn!(PatTuple) => { Pat::Tuple }
1961 |
1962 syn!(PatRef) => { Pat::Ref }
1963 |
1964 syn!(PatSlice) => { Pat::Slice }
1965 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001966 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001967
Michael Layzell734adb42017-06-07 16:58:31 -04001968 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001969 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001970 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001971 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001972 |u| PatWild { underscore_token: u }
1973 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001974 }
David Tolnay84aa0752016-10-02 23:01:13 -07001975
Michael Layzell734adb42017-06-07 16:58:31 -04001976 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001977 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001978 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001979 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001980 pat: syn!(Pat) >>
1981 (PatBox {
1982 pat: Box::new(pat),
1983 box_token: boxed,
1984 })
1985 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001986 }
1987
Michael Layzell734adb42017-06-07 16:58:31 -04001988 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001989 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001990 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001991 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001992 mutability: syn!(Mutability) >>
1993 name: alt!(
1994 syn!(Ident)
1995 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001996 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001997 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001998 not!(punct!(<)) >>
1999 not!(punct!(::)) >>
2000 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002001 (PatIdent {
2002 mode: match mode {
2003 Some(mode) => BindingMode::ByRef(mode, mutability),
2004 None => BindingMode::ByValue(mutability),
2005 },
2006 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002007 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002008 subpat: subpat.map(|p| Box::new(p.1)),
2009 })
2010 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002011 }
2012
Michael Layzell734adb42017-06-07 16:58:31 -04002013 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002014 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002015 named!(parse -> Self, do_parse!(
2016 path: syn!(Path) >>
2017 tuple: syn!(PatTuple) >>
2018 (PatTupleStruct {
2019 path: path,
2020 pat: tuple,
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 PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002027 named!(parse -> Self, do_parse!(
2028 path: syn!(Path) >>
2029 data: braces!(do_parse!(
2030 fields: call!(Delimited::parse_terminated) >>
2031 base: option!(
2032 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002033 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002034 ) >>
2035 (fields, base)
2036 )) >>
2037 (PatStruct {
2038 path: path,
2039 fields: (data.0).0,
2040 brace_token: data.1,
2041 dot2_token: (data.0).1.and_then(|m| m),
2042 })
2043 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002044 }
2045
Michael Layzell734adb42017-06-07 16:58:31 -04002046 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002047 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002048 named!(parse -> Self, alt!(
2049 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002050 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002051 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002052 pat: syn!(Pat) >>
2053 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002054 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002055 pat: Box::new(pat),
2056 is_shorthand: false,
2057 attrs: Vec::new(),
2058 colon_token: Some(colon),
2059 })
2060 )
2061 |
2062 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002063 boxed: option!(keyword!(box)) >>
2064 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002065 mutability: syn!(Mutability) >>
2066 ident: syn!(Ident) >>
2067 ({
2068 let mut pat: Pat = PatIdent {
2069 mode: if let Some(mode) = mode {
2070 BindingMode::ByRef(mode, mutability)
2071 } else {
2072 BindingMode::ByValue(mutability)
2073 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002074 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002075 subpat: None,
2076 at_token: None,
2077 }.into();
2078 if let Some(boxed) = boxed {
2079 pat = PatBox {
2080 pat: Box::new(pat),
2081 box_token: boxed,
2082 }.into();
2083 }
2084 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002085 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002086 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002087 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002088 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002089 colon_token: None,
2090 }
2091 })
2092 )
2093 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002094 }
2095
Michael Layzell734adb42017-06-07 16:58:31 -04002096 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002097 impl Synom for Member {
2098 named!(parse -> Self, alt!(
2099 syn!(Ident) => { Member::Named }
2100 |
2101 syn!(Index) => { Member::Unnamed }
2102 ));
2103 }
2104
2105 #[cfg(feature = "full")]
2106 impl Synom for Index {
2107 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002108 lit: syn!(Lit) >>
2109 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002110 if let Ok(i) = lit.value.to_string().parse() {
2111 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002112 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002113 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002114 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002115 })
David Tolnay85b69a42017-12-27 20:43:10 -05002116 ));
2117 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002118
Michael Layzell734adb42017-06-07 16:58:31 -04002119 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002120 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002121 named!(parse -> Self, map!(
2122 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002123 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002124 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002125 }
David Tolnay9636c052016-10-02 17:11:17 -07002126
Michael Layzell734adb42017-06-07 16:58:31 -04002127 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002128 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002129 named!(parse -> Self, do_parse!(
2130 data: parens!(do_parse!(
2131 elems: call!(Delimited::parse_terminated) >>
2132 dotdot: map!(cond!(
2133 elems.is_empty() || elems.trailing_delim(),
2134 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002135 dots: punct!(..) >>
2136 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002137 (dots, trailing)
2138 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002139 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002140 rest: cond!(match dotdot {
2141 Some((_, Some(_))) => true,
2142 _ => false,
2143 },
2144 call!(Delimited::parse_terminated)) >>
2145 (elems, dotdot, rest)
2146 )) >>
2147 ({
2148 let ((mut elems, dotdot, rest), parens) = data;
2149 let (dotdot, trailing) = match dotdot {
2150 Some((a, b)) => (Some(a), Some(b)),
2151 None => (None, None),
2152 };
2153 PatTuple {
2154 paren_token: parens,
2155 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2156 dot2_token: dotdot,
2157 comma_token: trailing.and_then(|b| b),
2158 pats: {
2159 if let Some(rest) = rest {
2160 for elem in rest {
2161 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002162 }
Michael Layzell92639a52017-06-01 00:07:44 -04002163 }
2164 elems
2165 },
2166 }
2167 })
2168 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002169 }
David Tolnayfbb73232016-10-03 01:00:06 -07002170
Michael Layzell734adb42017-06-07 16:58:31 -04002171 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002172 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002173 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002174 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002175 mutability: syn!(Mutability) >>
2176 pat: syn!(Pat) >>
2177 (PatRef {
2178 pat: Box::new(pat),
2179 mutbl: mutability,
2180 and_token: and,
2181 })
2182 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002183 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002184
Michael Layzell734adb42017-06-07 16:58:31 -04002185 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002186 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002187 named!(parse -> Self, do_parse!(
2188 lit: pat_lit_expr >>
2189 (if let ExprKind::Path(_) = lit.node {
2190 return parse_error(); // these need to be parsed by pat_path
2191 } else {
2192 PatLit {
2193 expr: Box::new(lit),
2194 }
2195 })
2196 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002197 }
David Tolnaye1310902016-10-29 23:40:00 -07002198
Michael Layzell734adb42017-06-07 16:58:31 -04002199 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002200 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002201 named!(parse -> Self, do_parse!(
2202 lo: pat_lit_expr >>
2203 limits: syn!(RangeLimits) >>
2204 hi: pat_lit_expr >>
2205 (PatRange {
2206 lo: Box::new(lo),
2207 hi: Box::new(hi),
2208 limits: limits,
2209 })
2210 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002211 }
David Tolnaye1310902016-10-29 23:40:00 -07002212
Michael Layzell734adb42017-06-07 16:58:31 -04002213 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002214 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002215 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002216 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002217 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002218 |
Alex Crichton954046c2017-05-30 21:49:42 -07002219 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002220 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002221 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002222 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002223 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002224 expr: Box::new(v.into())
2225 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002226 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002227 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002228 })
2229 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002230
Michael Layzell734adb42017-06-07 16:58:31 -04002231 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002232 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002233 named!(parse -> Self, map!(
2234 brackets!(do_parse!(
2235 before: call!(Delimited::parse_terminated) >>
2236 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002237 dots: punct!(..) >>
2238 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002239 (dots, trailing)
2240 )) >>
2241 after: cond!(
2242 match middle {
2243 Some((_, ref trailing)) => trailing.is_some(),
2244 _ => false,
2245 },
2246 call!(Delimited::parse_terminated)
2247 ) >>
2248 (before, middle, after)
2249 )),
2250 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002251 let mut before: Delimited<Pat, Token![,]> = before;
2252 let after: Option<Delimited<Pat, Token![,]>> = after;
2253 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002254 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002255 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002256 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002257 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002258 }),
2259 bracket_token: brackets,
2260 middle: middle.and_then(|_| {
2261 if !before.is_empty() && !before.trailing_delim() {
2262 Some(Box::new(before.pop().unwrap().into_item()))
2263 } else {
2264 None
2265 }
2266 }),
2267 front: before,
2268 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002269 }
Alex Crichton954046c2017-05-30 21:49:42 -07002270 }
Michael Layzell92639a52017-06-01 00:07:44 -04002271 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002272 }
David Tolnay435a9a82016-10-29 13:47:20 -07002273
Michael Layzell734adb42017-06-07 16:58:31 -04002274 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002275 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002276 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002277 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002278 |
2279 epsilon!() => { |_| CaptureBy::Ref }
2280 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002281 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002282}
2283
David Tolnayf4bbbd92016-09-23 14:41:55 -07002284#[cfg(feature = "printing")]
2285mod printing {
2286 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002287 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002288 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002289 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002290 #[cfg(feature = "full")]
2291 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002292
David Tolnaybcf26022017-12-25 22:10:52 -05002293 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2294 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002295 #[cfg(feature = "full")]
2296 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2297 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002298 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002299 e.to_tokens(tokens);
2300 });
2301 } else {
2302 e.to_tokens(tokens);
2303 }
2304 }
2305
David Tolnayf4bbbd92016-09-23 14:41:55 -07002306 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002307 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002308 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002309 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002310 self.node.to_tokens(tokens)
2311 }
Michael Layzell734adb42017-06-07 16:58:31 -04002312
2313 #[cfg(not(feature = "full"))]
2314 fn to_tokens(&self, tokens: &mut Tokens) {
2315 self.node.to_tokens(tokens)
2316 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002317 }
2318
Michael Layzell734adb42017-06-07 16:58:31 -04002319 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002320 impl ToTokens for ExprBox {
2321 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002322 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002323 self.expr.to_tokens(tokens);
2324 }
2325 }
2326
Michael Layzell734adb42017-06-07 16:58:31 -04002327 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002328 impl ToTokens for ExprInPlace {
2329 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002330 match self.kind {
2331 InPlaceKind::Arrow(ref arrow) => {
2332 self.place.to_tokens(tokens);
2333 arrow.to_tokens(tokens);
2334 self.value.to_tokens(tokens);
2335 }
2336 InPlaceKind::In(ref _in) => {
2337 _in.to_tokens(tokens);
2338 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002339 // NOTE: The second operand must be in a block, add one if
2340 // it is not present.
2341 if let ExprKind::Block(_) = self.value.node {
2342 self.value.to_tokens(tokens);
2343 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002344 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002345 self.value.to_tokens(tokens);
2346 })
2347 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002348 }
2349 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002350 }
2351 }
2352
Michael Layzell734adb42017-06-07 16:58:31 -04002353 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002354 impl ToTokens for ExprArray {
2355 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002356 self.bracket_token.surround(tokens, |tokens| {
2357 self.exprs.to_tokens(tokens);
2358 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002359 }
2360 }
2361
2362 impl ToTokens for ExprCall {
2363 fn to_tokens(&self, tokens: &mut Tokens) {
2364 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002365 self.paren_token.surround(tokens, |tokens| {
2366 self.args.to_tokens(tokens);
2367 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002368 }
2369 }
2370
Michael Layzell734adb42017-06-07 16:58:31 -04002371 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002372 impl ToTokens for ExprMethodCall {
2373 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002374 self.expr.to_tokens(tokens);
2375 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002376 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002377 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002378 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2379 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002380 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002381 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002382 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002383 self.paren_token.surround(tokens, |tokens| {
2384 self.args.to_tokens(tokens);
2385 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002386 }
2387 }
2388
Michael Layzell734adb42017-06-07 16:58:31 -04002389 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002390 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002391 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002392 self.paren_token.surround(tokens, |tokens| {
2393 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002394 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002395 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002396 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002397 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002398 }
2399 // XXX: Not sure how to handle this, but we never parse it yet.
2400 // Is this for an expression like (0,)? Can't we use the
2401 // trailing delimiter on Delimited for that? (,) isn't a valid
2402 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002403 self.lone_comma.to_tokens(tokens);
2404 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002405 }
2406 }
2407
2408 impl ToTokens for ExprBinary {
2409 fn to_tokens(&self, tokens: &mut Tokens) {
2410 self.left.to_tokens(tokens);
2411 self.op.to_tokens(tokens);
2412 self.right.to_tokens(tokens);
2413 }
2414 }
2415
2416 impl ToTokens for ExprUnary {
2417 fn to_tokens(&self, tokens: &mut Tokens) {
2418 self.op.to_tokens(tokens);
2419 self.expr.to_tokens(tokens);
2420 }
2421 }
2422
2423 impl ToTokens for ExprCast {
2424 fn to_tokens(&self, tokens: &mut Tokens) {
2425 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002426 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002427 self.ty.to_tokens(tokens);
2428 }
2429 }
2430
2431 impl ToTokens for ExprType {
2432 fn to_tokens(&self, tokens: &mut Tokens) {
2433 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002434 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002435 self.ty.to_tokens(tokens);
2436 }
2437 }
2438
Michael Layzell734adb42017-06-07 16:58:31 -04002439 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002440 fn maybe_wrap_else(
2441 tokens: &mut Tokens,
2442 else_token: &Option<Token![else]>,
2443 if_false: &Option<Box<Expr>>,
2444 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002445 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002446 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002447
2448 // If we are not one of the valid expressions to exist in an else
2449 // clause, wrap ourselves in a block.
2450 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002451 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002452 if_false.to_tokens(tokens);
2453 }
2454 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002455 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002456 if_false.to_tokens(tokens);
2457 });
2458 }
2459 }
2460 }
2461 }
2462
2463 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002464 impl ToTokens for ExprIf {
2465 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002466 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002467 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002468 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002469 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002470 }
2471 }
2472
Michael Layzell734adb42017-06-07 16:58:31 -04002473 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002474 impl ToTokens for ExprIfLet {
2475 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002476 self.if_token.to_tokens(tokens);
2477 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002478 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002479 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002480 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002481 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002482 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002483 }
2484 }
2485
Michael Layzell734adb42017-06-07 16:58:31 -04002486 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002487 impl ToTokens for ExprWhile {
2488 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002489 if self.label.is_some() {
2490 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002491 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002492 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002493 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002494 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002495 self.body.to_tokens(tokens);
2496 }
2497 }
2498
Michael Layzell734adb42017-06-07 16:58:31 -04002499 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002500 impl ToTokens for ExprWhileLet {
2501 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002502 if self.label.is_some() {
2503 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002504 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002505 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002506 self.while_token.to_tokens(tokens);
2507 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002508 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002509 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002510 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002511 self.body.to_tokens(tokens);
2512 }
2513 }
2514
Michael Layzell734adb42017-06-07 16:58:31 -04002515 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002516 impl ToTokens for ExprForLoop {
2517 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002518 if self.label.is_some() {
2519 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002520 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002521 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002522 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002523 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002524 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002525 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002526 self.body.to_tokens(tokens);
2527 }
2528 }
2529
Michael Layzell734adb42017-06-07 16:58:31 -04002530 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002531 impl ToTokens for ExprLoop {
2532 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002533 if self.label.is_some() {
2534 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002535 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002536 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002537 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002538 self.body.to_tokens(tokens);
2539 }
2540 }
2541
Michael Layzell734adb42017-06-07 16:58:31 -04002542 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002543 impl ToTokens for ExprMatch {
2544 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002545 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002546 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002547 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002548 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002549 arm.to_tokens(tokens);
2550 // Ensure that we have a comma after a non-block arm, except
2551 // for the last one.
2552 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002553 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002554 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002555 }
2556 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002557 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 }
2559 }
2560
Michael Layzell734adb42017-06-07 16:58:31 -04002561 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002562 impl ToTokens for ExprCatch {
2563 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002564 self.do_token.to_tokens(tokens);
2565 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002566 self.block.to_tokens(tokens);
2567 }
2568 }
2569
Michael Layzell734adb42017-06-07 16:58:31 -04002570 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002571 impl ToTokens for ExprYield {
2572 fn to_tokens(&self, tokens: &mut Tokens) {
2573 self.yield_token.to_tokens(tokens);
2574 self.expr.to_tokens(tokens);
2575 }
2576 }
2577
2578 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002579 impl ToTokens for ExprClosure {
2580 fn to_tokens(&self, tokens: &mut Tokens) {
2581 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002582 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002583 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002584 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002585 FnArg::Captured(ArgCaptured {
2586 ref pat,
2587 ty: Type::Infer(_),
2588 ..
2589 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002590 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002591 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002592 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002593 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002594 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002595 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002596 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002597 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002598 self.body.to_tokens(tokens);
2599 }
2600 }
2601
Michael Layzell734adb42017-06-07 16:58:31 -04002602 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002603 impl ToTokens for ExprUnsafe {
2604 fn to_tokens(&self, tokens: &mut Tokens) {
2605 self.unsafe_token.to_tokens(tokens);
2606 self.block.to_tokens(tokens);
2607 }
2608 }
2609
2610 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002611 impl ToTokens for ExprBlock {
2612 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 self.block.to_tokens(tokens);
2614 }
2615 }
2616
Michael Layzell734adb42017-06-07 16:58:31 -04002617 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002618 impl ToTokens for ExprAssign {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
2620 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002621 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002622 self.right.to_tokens(tokens);
2623 }
2624 }
2625
Michael Layzell734adb42017-06-07 16:58:31 -04002626 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002627 impl ToTokens for ExprAssignOp {
2628 fn to_tokens(&self, tokens: &mut Tokens) {
2629 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002630 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002631 self.right.to_tokens(tokens);
2632 }
2633 }
2634
Michael Layzell734adb42017-06-07 16:58:31 -04002635 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002636 impl ToTokens for ExprField {
2637 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002638 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002639 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002640 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002641 }
2642 }
2643
Michael Layzell734adb42017-06-07 16:58:31 -04002644 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002645 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002646 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002647 match *self {
2648 Member::Named(ident) => ident.to_tokens(tokens),
2649 Member::Unnamed(ref index) => index.to_tokens(tokens),
2650 }
2651 }
2652 }
2653
2654 #[cfg(feature = "full")]
2655 impl ToTokens for Index {
2656 fn to_tokens(&self, tokens: &mut Tokens) {
2657 tokens.append(TokenTree {
2658 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002659 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002660 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002661 }
2662 }
2663
2664 impl ToTokens for ExprIndex {
2665 fn to_tokens(&self, tokens: &mut Tokens) {
2666 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002667 self.bracket_token.surround(tokens, |tokens| {
2668 self.index.to_tokens(tokens);
2669 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002670 }
2671 }
2672
Michael Layzell734adb42017-06-07 16:58:31 -04002673 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002674 impl ToTokens for ExprRange {
2675 fn to_tokens(&self, tokens: &mut Tokens) {
2676 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002677 match self.limits {
2678 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2679 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2680 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002681 self.to.to_tokens(tokens);
2682 }
2683 }
2684
2685 impl ToTokens for ExprPath {
2686 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002687 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002688 }
2689 }
2690
Michael Layzell734adb42017-06-07 16:58:31 -04002691 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002692 impl ToTokens for ExprAddrOf {
2693 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002694 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002695 self.mutbl.to_tokens(tokens);
2696 self.expr.to_tokens(tokens);
2697 }
2698 }
2699
Michael Layzell734adb42017-06-07 16:58:31 -04002700 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002701 impl ToTokens for ExprBreak {
2702 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002703 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002704 self.label.to_tokens(tokens);
2705 self.expr.to_tokens(tokens);
2706 }
2707 }
2708
Michael Layzell734adb42017-06-07 16:58:31 -04002709 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002710 impl ToTokens for ExprContinue {
2711 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002712 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002713 self.label.to_tokens(tokens);
2714 }
2715 }
2716
Michael Layzell734adb42017-06-07 16:58:31 -04002717 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002718 impl ToTokens for ExprRet {
2719 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002720 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002721 self.expr.to_tokens(tokens);
2722 }
2723 }
2724
Michael Layzell734adb42017-06-07 16:58:31 -04002725 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002726 impl ToTokens for ExprStruct {
2727 fn to_tokens(&self, tokens: &mut Tokens) {
2728 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002729 self.brace_token.surround(tokens, |tokens| {
2730 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002731 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002732 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002733 self.rest.to_tokens(tokens);
2734 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002735 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002736 }
2737 }
2738
Michael Layzell734adb42017-06-07 16:58:31 -04002739 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002740 impl ToTokens for ExprRepeat {
2741 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002742 self.bracket_token.surround(tokens, |tokens| {
2743 self.expr.to_tokens(tokens);
2744 self.semi_token.to_tokens(tokens);
2745 self.amt.to_tokens(tokens);
2746 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002747 }
2748 }
2749
Michael Layzell93c36282017-06-04 20:43:14 -04002750 impl ToTokens for ExprGroup {
2751 fn to_tokens(&self, tokens: &mut Tokens) {
2752 self.group_token.surround(tokens, |tokens| {
2753 self.expr.to_tokens(tokens);
2754 });
2755 }
2756 }
2757
Alex Crichton62a0a592017-05-22 13:58:53 -07002758 impl ToTokens for ExprParen {
2759 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002760 self.paren_token.surround(tokens, |tokens| {
2761 self.expr.to_tokens(tokens);
2762 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002763 }
2764 }
2765
Michael Layzell734adb42017-06-07 16:58:31 -04002766 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002767 impl ToTokens for ExprTry {
2768 fn to_tokens(&self, tokens: &mut Tokens) {
2769 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002770 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002771 }
2772 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002773
Michael Layzell734adb42017-06-07 16:58:31 -04002774 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002775 impl ToTokens for FieldValue {
2776 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002777 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002778 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2779 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002780 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002781 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002782 self.expr.to_tokens(tokens);
2783 }
David Tolnay055a7042016-10-02 19:23:54 -07002784 }
2785 }
2786
Michael Layzell734adb42017-06-07 16:58:31 -04002787 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002788 impl ToTokens for Arm {
2789 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002790 tokens.append_all(&self.attrs);
2791 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002792 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002793 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002794 self.guard.to_tokens(tokens);
2795 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002796 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002797 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002798 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002799 }
2800 }
2801
Michael Layzell734adb42017-06-07 16:58:31 -04002802 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002803 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002804 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002805 self.underscore_token.to_tokens(tokens);
2806 }
2807 }
2808
Michael Layzell734adb42017-06-07 16:58:31 -04002809 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002810 impl ToTokens for PatIdent {
2811 fn to_tokens(&self, tokens: &mut Tokens) {
2812 self.mode.to_tokens(tokens);
2813 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002814 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002815 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002816 self.subpat.to_tokens(tokens);
2817 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002818 }
2819 }
2820
Michael Layzell734adb42017-06-07 16:58:31 -04002821 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002822 impl ToTokens for PatStruct {
2823 fn to_tokens(&self, tokens: &mut Tokens) {
2824 self.path.to_tokens(tokens);
2825 self.brace_token.surround(tokens, |tokens| {
2826 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002827 // NOTE: We need a comma before the dot2 token if it is present.
2828 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002829 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002830 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002831 self.dot2_token.to_tokens(tokens);
2832 });
2833 }
2834 }
2835
Michael Layzell734adb42017-06-07 16:58:31 -04002836 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002837 impl ToTokens for PatTupleStruct {
2838 fn to_tokens(&self, tokens: &mut Tokens) {
2839 self.path.to_tokens(tokens);
2840 self.pat.to_tokens(tokens);
2841 }
2842 }
2843
Michael Layzell734adb42017-06-07 16:58:31 -04002844 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002845 impl ToTokens for PatPath {
2846 fn to_tokens(&self, tokens: &mut Tokens) {
2847 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2848 }
2849 }
2850
Michael Layzell734adb42017-06-07 16:58:31 -04002851 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002852 impl ToTokens for PatTuple {
2853 fn to_tokens(&self, tokens: &mut Tokens) {
2854 self.paren_token.surround(tokens, |tokens| {
2855 for (i, token) in self.pats.iter().enumerate() {
2856 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002857 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2858 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002859 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002860 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002861 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002862
2863 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002864 // Ensure there is a comma before the .. token.
2865 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002866 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002867 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002868 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002869 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002870 });
2871 }
2872 }
2873
Michael Layzell734adb42017-06-07 16:58:31 -04002874 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002875 impl ToTokens for PatBox {
2876 fn to_tokens(&self, tokens: &mut Tokens) {
2877 self.box_token.to_tokens(tokens);
2878 self.pat.to_tokens(tokens);
2879 }
2880 }
2881
Michael Layzell734adb42017-06-07 16:58:31 -04002882 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002883 impl ToTokens for PatRef {
2884 fn to_tokens(&self, tokens: &mut Tokens) {
2885 self.and_token.to_tokens(tokens);
2886 self.mutbl.to_tokens(tokens);
2887 self.pat.to_tokens(tokens);
2888 }
2889 }
2890
Michael Layzell734adb42017-06-07 16:58:31 -04002891 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002892 impl ToTokens for PatLit {
2893 fn to_tokens(&self, tokens: &mut Tokens) {
2894 self.expr.to_tokens(tokens);
2895 }
2896 }
2897
Michael Layzell734adb42017-06-07 16:58:31 -04002898 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002899 impl ToTokens for PatRange {
2900 fn to_tokens(&self, tokens: &mut Tokens) {
2901 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002902 match self.limits {
2903 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2904 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2905 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002906 self.hi.to_tokens(tokens);
2907 }
2908 }
2909
Michael Layzell734adb42017-06-07 16:58:31 -04002910 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002911 impl ToTokens for PatSlice {
2912 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002913 // XXX: This is a mess, and it will be so easy to screw it up. How
2914 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002915 self.bracket_token.surround(tokens, |tokens| {
2916 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002917
2918 // If we need a comma before the middle or standalone .. token,
2919 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002920 if !self.front.empty_or_trailing()
2921 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002922 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002923 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002924 }
2925
2926 // If we have an identifier, we always need a .. token.
2927 if self.middle.is_some() {
2928 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002929 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002930 } else if self.dot2_token.is_some() {
2931 self.dot2_token.to_tokens(tokens);
2932 }
2933
2934 // Make sure we have a comma before the back half.
2935 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002936 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002937 self.back.to_tokens(tokens);
2938 } else {
2939 self.comma_token.to_tokens(tokens);
2940 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002941 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002942 }
2943 }
2944
Michael Layzell734adb42017-06-07 16:58:31 -04002945 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002946 impl ToTokens for FieldPat {
2947 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002948 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002949 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05002950 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002951 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002952 }
2953 self.pat.to_tokens(tokens);
2954 }
2955 }
2956
Michael Layzell734adb42017-06-07 16:58:31 -04002957 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002958 impl ToTokens for BindingMode {
2959 fn to_tokens(&self, tokens: &mut Tokens) {
2960 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002961 BindingMode::ByRef(ref t, ref m) => {
2962 t.to_tokens(tokens);
2963 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002964 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002965 BindingMode::ByValue(ref m) => {
2966 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002967 }
2968 }
2969 }
2970 }
David Tolnay42602292016-10-01 22:25:45 -07002971
Michael Layzell734adb42017-06-07 16:58:31 -04002972 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002973 impl ToTokens for CaptureBy {
2974 fn to_tokens(&self, tokens: &mut Tokens) {
2975 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002976 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002977 CaptureBy::Ref => {
2978 // nothing
2979 }
David Tolnay89e05672016-10-02 14:39:42 -07002980 }
2981 }
2982 }
2983
Michael Layzell734adb42017-06-07 16:58:31 -04002984 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002985 impl ToTokens for Block {
2986 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002987 self.brace_token.surround(tokens, |tokens| {
2988 tokens.append_all(&self.stmts);
2989 });
David Tolnay42602292016-10-01 22:25:45 -07002990 }
2991 }
2992
Michael Layzell734adb42017-06-07 16:58:31 -04002993 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002994 impl ToTokens for Stmt {
2995 fn to_tokens(&self, tokens: &mut Tokens) {
2996 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002997 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002998 Stmt::Item(ref item) => item.to_tokens(tokens),
2999 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003000 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003001 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003002 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003003 }
David Tolnaydecf28d2017-11-11 11:56:45 -08003004 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07003005 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07003006 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07003007 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07003008 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003009 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003010 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
3011 // no semicolon
3012 }
David Tolnay13b3d352016-10-03 00:31:15 -07003013 }
3014 }
David Tolnay42602292016-10-01 22:25:45 -07003015 }
3016 }
3017 }
David Tolnay191e0582016-10-02 18:31:09 -07003018
Michael Layzell734adb42017-06-07 16:58:31 -04003019 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003020 impl ToTokens for Local {
3021 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003022 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003023 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003024 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003025 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003026 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003027 self.ty.to_tokens(tokens);
3028 }
3029 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003030 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003031 self.init.to_tokens(tokens);
3032 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003033 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003034 }
3035 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003036}