blob: 0b8f4eed9a56c07c7f5aed344d74c91a710b0eda [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 ({
1583 let (colon, ty) = ty.unwrap_or_else(|| {
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001584 (<Token![:]>::default(), TypeInfer {
David Tolnayf8db7ba2017-11-11 22:52:16 -08001585 underscore_token: <Token![_]>::default(),
Alex Crichton954046c2017-05-30 21:49:42 -07001586 }.into())
1587 });
1588 ArgCaptured {
1589 pat: pat,
1590 colon_token: colon,
1591 ty: ty,
1592 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001593 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001594 ));
1595
Michael Layzell734adb42017-06-07 16:58:31 -04001596 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001597 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001598 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001599 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1600 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001601 cond: expr_no_struct >>
1602 while_block: syn!(Block) >>
1603 (ExprWhile {
1604 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001605 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001606 cond: Box::new(cond),
1607 body: while_block,
1608 label: lbl.map(|p| p.0),
1609 })
1610 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001611 }
1612
Michael Layzell734adb42017-06-07 16:58:31 -04001613 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001614 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001615 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001616 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1617 while_: keyword!(while) >>
1618 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001619 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001620 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001621 value: expr_no_struct >>
1622 while_block: syn!(Block) >>
1623 (ExprWhileLet {
1624 eq_token: eq,
1625 let_token: let_,
1626 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001627 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001628 pat: Box::new(pat),
1629 expr: Box::new(value),
1630 body: while_block,
1631 label: lbl.map(|p| p.0),
1632 })
1633 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001634 }
1635
Michael Layzell734adb42017-06-07 16:58:31 -04001636 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001637 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001638 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001639 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001640 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001641 (ExprContinue {
1642 continue_token: cont,
1643 label: lbl,
1644 })
1645 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001646 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001647
Michael Layzell734adb42017-06-07 16:58:31 -04001648 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001649 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001650 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001651 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001652 // We can't allow blocks after a `break` expression when we wouldn't
1653 // allow structs, as this expression is ambiguous.
1654 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001655 (ExprBreak {
1656 label: lbl,
1657 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001658 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001659 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001660 ));
1661
Michael Layzell734adb42017-06-07 16:58:31 -04001662 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001663 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001664 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001665 // NOTE: return is greedy and eats blocks after it even when in a
1666 // position where structs are not allowed, such as in if statement
1667 // conditions. For example:
1668 //
David Tolnaybcf26022017-12-25 22:10:52 -05001669 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001670 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001671 (ExprRet {
1672 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001673 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001674 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001675 ));
1676
Michael Layzell734adb42017-06-07 16:58:31 -04001677 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001678 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001679 named!(parse -> Self, do_parse!(
1680 path: syn!(Path) >>
1681 data: braces!(do_parse!(
1682 fields: call!(Delimited::parse_terminated) >>
1683 base: option!(
1684 cond!(fields.is_empty() || fields.trailing_delim(),
1685 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001686 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001687 base: syn!(Expr) >>
1688 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001689 )
Michael Layzell92639a52017-06-01 00:07:44 -04001690 )
1691 ) >>
1692 (fields, base)
1693 )) >>
1694 ({
1695 let ((fields, base), brace) = data;
1696 let (dots, rest) = match base.and_then(|b| b) {
1697 Some((dots, base)) => (Some(dots), Some(base)),
1698 None => (None, None),
1699 };
1700 ExprStruct {
1701 brace_token: brace,
1702 path: path,
1703 fields: fields,
1704 dot2_token: dots,
1705 rest: rest.map(Box::new),
1706 }
1707 })
1708 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001709 }
1710
Michael Layzell734adb42017-06-07 16:58:31 -04001711 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001712 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001713 named!(parse -> Self, alt!(
1714 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001715 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001716 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001717 value: syn!(Expr) >>
1718 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001719 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001720 expr: value,
1721 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001722 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001723 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001724 })
Michael Layzell92639a52017-06-01 00:07:44 -04001725 )
1726 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001727 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001728 member: Member::Named(name),
Michael Layzell92639a52017-06-01 00:07:44 -04001729 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1730 is_shorthand: true,
1731 attrs: Vec::new(),
1732 colon_token: None,
1733 })
1734 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001735 }
David Tolnay055a7042016-10-02 19:23:54 -07001736
Michael Layzell734adb42017-06-07 16:58:31 -04001737 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001738 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001739 named!(parse -> Self, do_parse!(
1740 data: brackets!(do_parse!(
1741 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001742 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001743 times: syn!(Expr) >>
1744 (value, semi, times)
1745 )) >>
1746 (ExprRepeat {
1747 expr: Box::new((data.0).0),
1748 amt: Box::new((data.0).2),
1749 bracket_token: data.1,
1750 semi_token: (data.0).1,
1751 })
1752 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001753 }
David Tolnay055a7042016-10-02 19:23:54 -07001754
Michael Layzell734adb42017-06-07 16:58:31 -04001755 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001756 impl Synom for ExprUnsafe {
1757 named!(parse -> Self, do_parse!(
1758 unsafe_: keyword!(unsafe) >>
1759 b: syn!(Block) >>
1760 (ExprUnsafe {
1761 unsafe_token: unsafe_,
1762 block: b,
1763 })
1764 ));
1765 }
1766
1767 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001768 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001769 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001770 b: syn!(Block) >>
1771 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001772 block: b,
1773 })
1774 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001775 }
David Tolnay89e05672016-10-02 14:39:42 -07001776
Michael Layzell734adb42017-06-07 16:58:31 -04001777 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001778 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001779 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001780 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001781 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001782 ));
1783
Michael Layzell734adb42017-06-07 16:58:31 -04001784 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001785 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001786 named!(parse -> Self, alt!(
1787 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001788 punct!(..=) => { RangeLimits::Closed }
1789 |
1790 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001791 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001792 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001793 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001794 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001795 }
David Tolnay438c9052016-10-07 23:24:48 -07001796
Alex Crichton954046c2017-05-30 21:49:42 -07001797 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001798 named!(parse -> Self, do_parse!(
1799 pair: qpath >>
1800 (ExprPath {
1801 qself: pair.0,
1802 path: pair.1,
1803 })
1804 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001805 }
David Tolnay42602292016-10-01 22:25:45 -07001806
Michael Layzell734adb42017-06-07 16:58:31 -04001807 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001808 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001809
David Tolnay32954ef2017-12-26 22:43:16 -05001810 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001811
Michael Layzell734adb42017-06-07 16:58:31 -04001812 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001813 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001814 named!(parse -> Self, do_parse!(
1815 stmts: braces!(call!(Block::parse_within)) >>
1816 (Block {
1817 stmts: stmts.0,
1818 brace_token: stmts.1,
1819 })
1820 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001821 }
David Tolnay939766a2016-09-23 23:48:12 -07001822
Michael Layzell734adb42017-06-07 16:58:31 -04001823 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001824 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001825 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001826 many0!(punct!(;)) >>
1827 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001828 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001829 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001830 mut e: syn!(Expr) >>
1831 ({
1832 e.attrs = attrs;
1833 Stmt::Expr(Box::new(e))
1834 })
1835 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001836 (match last {
1837 None => standalone,
1838 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001839 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001840 standalone
1841 }
1842 })
1843 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001844 }
1845
Michael Layzell734adb42017-06-07 16:58:31 -04001846 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001847 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001848 named!(parse -> Self, alt!(
1849 stmt_mac
1850 |
1851 stmt_local
1852 |
1853 stmt_item
1854 |
Michael Layzell35418782017-06-07 09:20:25 -04001855 stmt_blockexpr
1856 |
Michael Layzell92639a52017-06-01 00:07:44 -04001857 stmt_expr
1858 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001859 }
David Tolnay939766a2016-09-23 23:48:12 -07001860
Michael Layzell734adb42017-06-07 16:58:31 -04001861 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001862 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001863 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001864 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001865 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001866 // Only parse braces here; paren and bracket will get parsed as
1867 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001868 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001869 semi: option!(punct!(;)) >>
David Tolnaydecf28d2017-11-11 11:56:45 -08001870 (Stmt::Macro(Box::new((
1871 Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001872 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001873 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001874 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001875 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001876 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001877 },
David Tolnayeea28d62016-10-25 20:44:08 -07001878 },
Alex Crichton954046c2017-05-30 21:49:42 -07001879 match semi {
1880 Some(semi) => MacStmtStyle::Semicolon(semi),
1881 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001882 },
David Tolnayeea28d62016-10-25 20:44:08 -07001883 attrs,
1884 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001885 ));
1886
Michael Layzell734adb42017-06-07 16:58:31 -04001887 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001888 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001889 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001890 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001891 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001892 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001893 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1894 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001895 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001896 let_token: let_,
1897 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001898 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1899 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001900 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001901 ty: ty.map(|p| Box::new(p.1)),
1902 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001903 attrs: attrs,
1904 })))
1905 ));
1906
Michael Layzell734adb42017-06-07 16:58:31 -04001907 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001908 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001909
Michael Layzell734adb42017-06-07 16:58:31 -04001910 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001911 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001912 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04001913 mut e: expr_nosemi >>
1914 // If the next token is a `.` or a `?` it is special-cased to parse as
1915 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001916 not!(punct!(.)) >>
1917 not!(punct!(?)) >>
1918 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001919 ({
1920 e.attrs = attrs;
1921 if let Some(semi) = semi {
1922 Stmt::Semi(Box::new(e), semi)
1923 } else {
1924 Stmt::Expr(Box::new(e))
1925 }
1926 })
1927 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001928
Michael Layzell734adb42017-06-07 16:58:31 -04001929 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001930 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001931 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001932 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001933 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001934 ({
1935 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001936 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001937 })
David Tolnay939766a2016-09-23 23:48:12 -07001938 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001939
Michael Layzell734adb42017-06-07 16:58:31 -04001940 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001941 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001942 named!(parse -> Self, alt!(
1943 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1944 |
1945 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1946 |
1947 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1948 |
1949 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1950 |
1951 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1952 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001953 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001954 |
1955 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1956 |
1957 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1958 |
1959 syn!(PatPath) => { Pat::Path }
1960 |
1961 syn!(PatTuple) => { Pat::Tuple }
1962 |
1963 syn!(PatRef) => { Pat::Ref }
1964 |
1965 syn!(PatSlice) => { Pat::Slice }
1966 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001967 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001968
Michael Layzell734adb42017-06-07 16:58:31 -04001969 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001970 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001971 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001972 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001973 |u| PatWild { underscore_token: u }
1974 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001975 }
David Tolnay84aa0752016-10-02 23:01:13 -07001976
Michael Layzell734adb42017-06-07 16:58:31 -04001977 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001978 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001979 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001980 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001981 pat: syn!(Pat) >>
1982 (PatBox {
1983 pat: Box::new(pat),
1984 box_token: boxed,
1985 })
1986 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001987 }
1988
Michael Layzell734adb42017-06-07 16:58:31 -04001989 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001990 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001991 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001992 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001993 mutability: syn!(Mutability) >>
1994 name: alt!(
1995 syn!(Ident)
1996 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001997 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001998 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001999 not!(punct!(<)) >>
2000 not!(punct!(::)) >>
2001 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002002 (PatIdent {
2003 mode: match mode {
2004 Some(mode) => BindingMode::ByRef(mode, mutability),
2005 None => BindingMode::ByValue(mutability),
2006 },
2007 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002008 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002009 subpat: subpat.map(|p| Box::new(p.1)),
2010 })
2011 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002012 }
2013
Michael Layzell734adb42017-06-07 16:58:31 -04002014 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002015 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002016 named!(parse -> Self, do_parse!(
2017 path: syn!(Path) >>
2018 tuple: syn!(PatTuple) >>
2019 (PatTupleStruct {
2020 path: path,
2021 pat: tuple,
2022 })
2023 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002024 }
2025
Michael Layzell734adb42017-06-07 16:58:31 -04002026 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002027 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002028 named!(parse -> Self, do_parse!(
2029 path: syn!(Path) >>
2030 data: braces!(do_parse!(
2031 fields: call!(Delimited::parse_terminated) >>
2032 base: option!(
2033 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002034 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002035 ) >>
2036 (fields, base)
2037 )) >>
2038 (PatStruct {
2039 path: path,
2040 fields: (data.0).0,
2041 brace_token: data.1,
2042 dot2_token: (data.0).1.and_then(|m| m),
2043 })
2044 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002045 }
2046
Michael Layzell734adb42017-06-07 16:58:31 -04002047 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002048 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002049 named!(parse -> Self, alt!(
2050 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002051 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002052 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002053 pat: syn!(Pat) >>
2054 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002055 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002056 pat: Box::new(pat),
2057 is_shorthand: false,
2058 attrs: Vec::new(),
2059 colon_token: Some(colon),
2060 })
2061 )
2062 |
2063 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002064 boxed: option!(keyword!(box)) >>
2065 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002066 mutability: syn!(Mutability) >>
2067 ident: syn!(Ident) >>
2068 ({
2069 let mut pat: Pat = PatIdent {
2070 mode: if let Some(mode) = mode {
2071 BindingMode::ByRef(mode, mutability)
2072 } else {
2073 BindingMode::ByValue(mutability)
2074 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002075 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002076 subpat: None,
2077 at_token: None,
2078 }.into();
2079 if let Some(boxed) = boxed {
2080 pat = PatBox {
2081 pat: Box::new(pat),
2082 box_token: boxed,
2083 }.into();
2084 }
2085 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002086 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002087 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002088 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002089 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002090 colon_token: None,
2091 }
2092 })
2093 )
2094 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002095 }
2096
Michael Layzell734adb42017-06-07 16:58:31 -04002097 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002098 impl Synom for Member {
2099 named!(parse -> Self, alt!(
2100 syn!(Ident) => { Member::Named }
2101 |
2102 syn!(Index) => { Member::Unnamed }
2103 ));
2104 }
2105
2106 #[cfg(feature = "full")]
2107 impl Synom for Index {
2108 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002109 lit: syn!(Lit) >>
2110 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002111 if let Ok(i) = lit.value.to_string().parse() {
2112 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002113 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002114 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002115 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002116 })
David Tolnay85b69a42017-12-27 20:43:10 -05002117 ));
2118 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002119
Michael Layzell734adb42017-06-07 16:58:31 -04002120 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002121 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002122 named!(parse -> Self, map!(
2123 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002124 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002125 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002126 }
David Tolnay9636c052016-10-02 17:11:17 -07002127
Michael Layzell734adb42017-06-07 16:58:31 -04002128 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002129 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002130 named!(parse -> Self, do_parse!(
2131 data: parens!(do_parse!(
2132 elems: call!(Delimited::parse_terminated) >>
2133 dotdot: map!(cond!(
2134 elems.is_empty() || elems.trailing_delim(),
2135 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002136 dots: punct!(..) >>
2137 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002138 (dots, trailing)
2139 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002140 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002141 rest: cond!(match dotdot {
2142 Some((_, Some(_))) => true,
2143 _ => false,
2144 },
2145 call!(Delimited::parse_terminated)) >>
2146 (elems, dotdot, rest)
2147 )) >>
2148 ({
2149 let ((mut elems, dotdot, rest), parens) = data;
2150 let (dotdot, trailing) = match dotdot {
2151 Some((a, b)) => (Some(a), Some(b)),
2152 None => (None, None),
2153 };
2154 PatTuple {
2155 paren_token: parens,
2156 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2157 dot2_token: dotdot,
2158 comma_token: trailing.and_then(|b| b),
2159 pats: {
2160 if let Some(rest) = rest {
2161 for elem in rest {
2162 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002163 }
Michael Layzell92639a52017-06-01 00:07:44 -04002164 }
2165 elems
2166 },
2167 }
2168 })
2169 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002170 }
David Tolnayfbb73232016-10-03 01:00:06 -07002171
Michael Layzell734adb42017-06-07 16:58:31 -04002172 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002173 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002174 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002175 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002176 mutability: syn!(Mutability) >>
2177 pat: syn!(Pat) >>
2178 (PatRef {
2179 pat: Box::new(pat),
2180 mutbl: mutability,
2181 and_token: and,
2182 })
2183 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002184 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002185
Michael Layzell734adb42017-06-07 16:58:31 -04002186 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002187 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002188 named!(parse -> Self, do_parse!(
2189 lit: pat_lit_expr >>
2190 (if let ExprKind::Path(_) = lit.node {
2191 return parse_error(); // these need to be parsed by pat_path
2192 } else {
2193 PatLit {
2194 expr: Box::new(lit),
2195 }
2196 })
2197 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002198 }
David Tolnaye1310902016-10-29 23:40:00 -07002199
Michael Layzell734adb42017-06-07 16:58:31 -04002200 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002201 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002202 named!(parse -> Self, do_parse!(
2203 lo: pat_lit_expr >>
2204 limits: syn!(RangeLimits) >>
2205 hi: pat_lit_expr >>
2206 (PatRange {
2207 lo: Box::new(lo),
2208 hi: Box::new(hi),
2209 limits: limits,
2210 })
2211 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002212 }
David Tolnaye1310902016-10-29 23:40:00 -07002213
Michael Layzell734adb42017-06-07 16:58:31 -04002214 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002215 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002216 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002217 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002218 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002219 |
Alex Crichton954046c2017-05-30 21:49:42 -07002220 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002221 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002222 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002223 ExprKind::Unary(ExprUnary {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002224 op: UnOp::Neg(<Token![-]>::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002225 expr: Box::new(v.into())
2226 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002227 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002228 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002229 })
2230 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002231
Michael Layzell734adb42017-06-07 16:58:31 -04002232 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002233 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002234 named!(parse -> Self, map!(
2235 brackets!(do_parse!(
2236 before: call!(Delimited::parse_terminated) >>
2237 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002238 dots: punct!(..) >>
2239 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002240 (dots, trailing)
2241 )) >>
2242 after: cond!(
2243 match middle {
2244 Some((_, ref trailing)) => trailing.is_some(),
2245 _ => false,
2246 },
2247 call!(Delimited::parse_terminated)
2248 ) >>
2249 (before, middle, after)
2250 )),
2251 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002252 let mut before: Delimited<Pat, Token![,]> = before;
2253 let after: Option<Delimited<Pat, Token![,]>> = after;
2254 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002255 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002256 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002257 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002258 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002259 }),
2260 bracket_token: brackets,
2261 middle: middle.and_then(|_| {
2262 if !before.is_empty() && !before.trailing_delim() {
2263 Some(Box::new(before.pop().unwrap().into_item()))
2264 } else {
2265 None
2266 }
2267 }),
2268 front: before,
2269 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002270 }
Alex Crichton954046c2017-05-30 21:49:42 -07002271 }
Michael Layzell92639a52017-06-01 00:07:44 -04002272 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002273 }
David Tolnay435a9a82016-10-29 13:47:20 -07002274
Michael Layzell734adb42017-06-07 16:58:31 -04002275 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002276 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002277 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002278 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002279 |
2280 epsilon!() => { |_| CaptureBy::Ref }
2281 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002282 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002283}
2284
David Tolnayf4bbbd92016-09-23 14:41:55 -07002285#[cfg(feature = "printing")]
2286mod printing {
2287 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002288 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002289 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002290 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002291 #[cfg(feature = "full")]
2292 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002293
David Tolnaybcf26022017-12-25 22:10:52 -05002294 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2295 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002296 #[cfg(feature = "full")]
2297 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2298 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002299 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002300 e.to_tokens(tokens);
2301 });
2302 } else {
2303 e.to_tokens(tokens);
2304 }
2305 }
2306
David Tolnayf4bbbd92016-09-23 14:41:55 -07002307 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002308 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002309 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002310 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002311 self.node.to_tokens(tokens)
2312 }
Michael Layzell734adb42017-06-07 16:58:31 -04002313
2314 #[cfg(not(feature = "full"))]
2315 fn to_tokens(&self, tokens: &mut Tokens) {
2316 self.node.to_tokens(tokens)
2317 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002318 }
2319
Michael Layzell734adb42017-06-07 16:58:31 -04002320 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002321 impl ToTokens for ExprBox {
2322 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002323 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002324 self.expr.to_tokens(tokens);
2325 }
2326 }
2327
Michael Layzell734adb42017-06-07 16:58:31 -04002328 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002329 impl ToTokens for ExprInPlace {
2330 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002331 match self.kind {
2332 InPlaceKind::Arrow(ref arrow) => {
2333 self.place.to_tokens(tokens);
2334 arrow.to_tokens(tokens);
2335 self.value.to_tokens(tokens);
2336 }
2337 InPlaceKind::In(ref _in) => {
2338 _in.to_tokens(tokens);
2339 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002340 // NOTE: The second operand must be in a block, add one if
2341 // it is not present.
2342 if let ExprKind::Block(_) = self.value.node {
2343 self.value.to_tokens(tokens);
2344 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002345 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002346 self.value.to_tokens(tokens);
2347 })
2348 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002349 }
2350 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002351 }
2352 }
2353
Michael Layzell734adb42017-06-07 16:58:31 -04002354 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002355 impl ToTokens for ExprArray {
2356 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002357 self.bracket_token.surround(tokens, |tokens| {
2358 self.exprs.to_tokens(tokens);
2359 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002360 }
2361 }
2362
2363 impl ToTokens for ExprCall {
2364 fn to_tokens(&self, tokens: &mut Tokens) {
2365 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002366 self.paren_token.surround(tokens, |tokens| {
2367 self.args.to_tokens(tokens);
2368 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002369 }
2370 }
2371
Michael Layzell734adb42017-06-07 16:58:31 -04002372 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002373 impl ToTokens for ExprMethodCall {
2374 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002375 self.expr.to_tokens(tokens);
2376 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002377 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002378 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002379 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2380 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002381 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002382 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002383 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002384 self.paren_token.surround(tokens, |tokens| {
2385 self.args.to_tokens(tokens);
2386 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002387 }
2388 }
2389
Michael Layzell734adb42017-06-07 16:58:31 -04002390 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002391 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002392 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002393 self.paren_token.surround(tokens, |tokens| {
2394 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002395 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002396 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002397 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002398 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002399 }
2400 // XXX: Not sure how to handle this, but we never parse it yet.
2401 // Is this for an expression like (0,)? Can't we use the
2402 // trailing delimiter on Delimited for that? (,) isn't a valid
2403 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002404 self.lone_comma.to_tokens(tokens);
2405 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002406 }
2407 }
2408
2409 impl ToTokens for ExprBinary {
2410 fn to_tokens(&self, tokens: &mut Tokens) {
2411 self.left.to_tokens(tokens);
2412 self.op.to_tokens(tokens);
2413 self.right.to_tokens(tokens);
2414 }
2415 }
2416
2417 impl ToTokens for ExprUnary {
2418 fn to_tokens(&self, tokens: &mut Tokens) {
2419 self.op.to_tokens(tokens);
2420 self.expr.to_tokens(tokens);
2421 }
2422 }
2423
2424 impl ToTokens for ExprCast {
2425 fn to_tokens(&self, tokens: &mut Tokens) {
2426 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002427 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002428 self.ty.to_tokens(tokens);
2429 }
2430 }
2431
2432 impl ToTokens for ExprType {
2433 fn to_tokens(&self, tokens: &mut Tokens) {
2434 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002435 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002436 self.ty.to_tokens(tokens);
2437 }
2438 }
2439
Michael Layzell734adb42017-06-07 16:58:31 -04002440 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002441 fn maybe_wrap_else(
2442 tokens: &mut Tokens,
2443 else_token: &Option<Token![else]>,
2444 if_false: &Option<Box<Expr>>,
2445 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002446 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002447 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002448
2449 // If we are not one of the valid expressions to exist in an else
2450 // clause, wrap ourselves in a block.
2451 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002452 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002453 if_false.to_tokens(tokens);
2454 }
2455 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002456 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002457 if_false.to_tokens(tokens);
2458 });
2459 }
2460 }
2461 }
2462 }
2463
2464 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002465 impl ToTokens for ExprIf {
2466 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002467 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002468 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002470 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002471 }
2472 }
2473
Michael Layzell734adb42017-06-07 16:58:31 -04002474 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002475 impl ToTokens for ExprIfLet {
2476 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002477 self.if_token.to_tokens(tokens);
2478 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002479 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002480 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002481 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002482 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002483 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002484 }
2485 }
2486
Michael Layzell734adb42017-06-07 16:58:31 -04002487 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002488 impl ToTokens for ExprWhile {
2489 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002490 if self.label.is_some() {
2491 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002492 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002493 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002494 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002495 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002496 self.body.to_tokens(tokens);
2497 }
2498 }
2499
Michael Layzell734adb42017-06-07 16:58:31 -04002500 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002501 impl ToTokens for ExprWhileLet {
2502 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002503 if self.label.is_some() {
2504 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002505 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002506 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002507 self.while_token.to_tokens(tokens);
2508 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002509 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002510 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002511 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002512 self.body.to_tokens(tokens);
2513 }
2514 }
2515
Michael Layzell734adb42017-06-07 16:58:31 -04002516 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002517 impl ToTokens for ExprForLoop {
2518 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002519 if self.label.is_some() {
2520 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002521 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002522 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002523 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002524 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002525 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002526 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002527 self.body.to_tokens(tokens);
2528 }
2529 }
2530
Michael Layzell734adb42017-06-07 16:58:31 -04002531 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002532 impl ToTokens for ExprLoop {
2533 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002534 if self.label.is_some() {
2535 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002536 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002537 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002538 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002539 self.body.to_tokens(tokens);
2540 }
2541 }
2542
Michael Layzell734adb42017-06-07 16:58:31 -04002543 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002544 impl ToTokens for ExprMatch {
2545 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002546 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002547 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002548 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002549 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002550 arm.to_tokens(tokens);
2551 // Ensure that we have a comma after a non-block arm, except
2552 // for the last one.
2553 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002554 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002555 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002556 }
2557 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002558 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002559 }
2560 }
2561
Michael Layzell734adb42017-06-07 16:58:31 -04002562 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002563 impl ToTokens for ExprCatch {
2564 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002565 self.do_token.to_tokens(tokens);
2566 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002567 self.block.to_tokens(tokens);
2568 }
2569 }
2570
Michael Layzell734adb42017-06-07 16:58:31 -04002571 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002572 impl ToTokens for ExprYield {
2573 fn to_tokens(&self, tokens: &mut Tokens) {
2574 self.yield_token.to_tokens(tokens);
2575 self.expr.to_tokens(tokens);
2576 }
2577 }
2578
2579 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002580 impl ToTokens for ExprClosure {
2581 fn to_tokens(&self, tokens: &mut Tokens) {
2582 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002583 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002584 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002585 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002586 FnArg::Captured(ArgCaptured {
2587 ref pat,
2588 ty: Type::Infer(_),
2589 ..
2590 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002591 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002592 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002593 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002594 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002595 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002596 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002597 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002598 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002599 self.body.to_tokens(tokens);
2600 }
2601 }
2602
Michael Layzell734adb42017-06-07 16:58:31 -04002603 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002604 impl ToTokens for ExprUnsafe {
2605 fn to_tokens(&self, tokens: &mut Tokens) {
2606 self.unsafe_token.to_tokens(tokens);
2607 self.block.to_tokens(tokens);
2608 }
2609 }
2610
2611 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002612 impl ToTokens for ExprBlock {
2613 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002614 self.block.to_tokens(tokens);
2615 }
2616 }
2617
Michael Layzell734adb42017-06-07 16:58:31 -04002618 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002619 impl ToTokens for ExprAssign {
2620 fn to_tokens(&self, tokens: &mut Tokens) {
2621 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002622 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002623 self.right.to_tokens(tokens);
2624 }
2625 }
2626
Michael Layzell734adb42017-06-07 16:58:31 -04002627 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002628 impl ToTokens for ExprAssignOp {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
2630 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002631 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002632 self.right.to_tokens(tokens);
2633 }
2634 }
2635
Michael Layzell734adb42017-06-07 16:58:31 -04002636 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002637 impl ToTokens for ExprField {
2638 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002639 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002640 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002641 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002642 }
2643 }
2644
Michael Layzell734adb42017-06-07 16:58:31 -04002645 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002646 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002647 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002648 match *self {
2649 Member::Named(ident) => ident.to_tokens(tokens),
2650 Member::Unnamed(ref index) => index.to_tokens(tokens),
2651 }
2652 }
2653 }
2654
2655 #[cfg(feature = "full")]
2656 impl ToTokens for Index {
2657 fn to_tokens(&self, tokens: &mut Tokens) {
2658 tokens.append(TokenTree {
2659 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002660 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002661 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002662 }
2663 }
2664
2665 impl ToTokens for ExprIndex {
2666 fn to_tokens(&self, tokens: &mut Tokens) {
2667 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002668 self.bracket_token.surround(tokens, |tokens| {
2669 self.index.to_tokens(tokens);
2670 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 }
2672 }
2673
Michael Layzell734adb42017-06-07 16:58:31 -04002674 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002675 impl ToTokens for ExprRange {
2676 fn to_tokens(&self, tokens: &mut Tokens) {
2677 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002678 match self.limits {
2679 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2680 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2681 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002682 self.to.to_tokens(tokens);
2683 }
2684 }
2685
2686 impl ToTokens for ExprPath {
2687 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002688 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002689 }
2690 }
2691
Michael Layzell734adb42017-06-07 16:58:31 -04002692 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002693 impl ToTokens for ExprAddrOf {
2694 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002695 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002696 self.mutbl.to_tokens(tokens);
2697 self.expr.to_tokens(tokens);
2698 }
2699 }
2700
Michael Layzell734adb42017-06-07 16:58:31 -04002701 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002702 impl ToTokens for ExprBreak {
2703 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002704 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002705 self.label.to_tokens(tokens);
2706 self.expr.to_tokens(tokens);
2707 }
2708 }
2709
Michael Layzell734adb42017-06-07 16:58:31 -04002710 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002711 impl ToTokens for ExprContinue {
2712 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002713 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002714 self.label.to_tokens(tokens);
2715 }
2716 }
2717
Michael Layzell734adb42017-06-07 16:58:31 -04002718 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002719 impl ToTokens for ExprRet {
2720 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002721 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002722 self.expr.to_tokens(tokens);
2723 }
2724 }
2725
Michael Layzell734adb42017-06-07 16:58:31 -04002726 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002727 impl ToTokens for ExprStruct {
2728 fn to_tokens(&self, tokens: &mut Tokens) {
2729 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002730 self.brace_token.surround(tokens, |tokens| {
2731 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002732 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002733 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002734 self.rest.to_tokens(tokens);
2735 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002736 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002737 }
2738 }
2739
Michael Layzell734adb42017-06-07 16:58:31 -04002740 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002741 impl ToTokens for ExprRepeat {
2742 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002743 self.bracket_token.surround(tokens, |tokens| {
2744 self.expr.to_tokens(tokens);
2745 self.semi_token.to_tokens(tokens);
2746 self.amt.to_tokens(tokens);
2747 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002748 }
2749 }
2750
Michael Layzell93c36282017-06-04 20:43:14 -04002751 impl ToTokens for ExprGroup {
2752 fn to_tokens(&self, tokens: &mut Tokens) {
2753 self.group_token.surround(tokens, |tokens| {
2754 self.expr.to_tokens(tokens);
2755 });
2756 }
2757 }
2758
Alex Crichton62a0a592017-05-22 13:58:53 -07002759 impl ToTokens for ExprParen {
2760 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002761 self.paren_token.surround(tokens, |tokens| {
2762 self.expr.to_tokens(tokens);
2763 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002764 }
2765 }
2766
Michael Layzell734adb42017-06-07 16:58:31 -04002767 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002768 impl ToTokens for ExprTry {
2769 fn to_tokens(&self, tokens: &mut Tokens) {
2770 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002771 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002772 }
2773 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002774
Michael Layzell734adb42017-06-07 16:58:31 -04002775 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002776 impl ToTokens for FieldValue {
2777 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002778 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002779 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2780 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002781 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002782 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002783 self.expr.to_tokens(tokens);
2784 }
David Tolnay055a7042016-10-02 19:23:54 -07002785 }
2786 }
2787
Michael Layzell734adb42017-06-07 16:58:31 -04002788 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002789 impl ToTokens for Arm {
2790 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002791 tokens.append_all(&self.attrs);
2792 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002793 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002794 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002795 self.guard.to_tokens(tokens);
2796 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002797 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002798 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002799 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002800 }
2801 }
2802
Michael Layzell734adb42017-06-07 16:58:31 -04002803 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002804 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002805 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002806 self.underscore_token.to_tokens(tokens);
2807 }
2808 }
2809
Michael Layzell734adb42017-06-07 16:58:31 -04002810 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002811 impl ToTokens for PatIdent {
2812 fn to_tokens(&self, tokens: &mut Tokens) {
2813 self.mode.to_tokens(tokens);
2814 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002815 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002816 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002817 self.subpat.to_tokens(tokens);
2818 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002819 }
2820 }
2821
Michael Layzell734adb42017-06-07 16:58:31 -04002822 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002823 impl ToTokens for PatStruct {
2824 fn to_tokens(&self, tokens: &mut Tokens) {
2825 self.path.to_tokens(tokens);
2826 self.brace_token.surround(tokens, |tokens| {
2827 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002828 // NOTE: We need a comma before the dot2 token if it is present.
2829 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002830 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002831 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002832 self.dot2_token.to_tokens(tokens);
2833 });
2834 }
2835 }
2836
Michael Layzell734adb42017-06-07 16:58:31 -04002837 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002838 impl ToTokens for PatTupleStruct {
2839 fn to_tokens(&self, tokens: &mut Tokens) {
2840 self.path.to_tokens(tokens);
2841 self.pat.to_tokens(tokens);
2842 }
2843 }
2844
Michael Layzell734adb42017-06-07 16:58:31 -04002845 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002846 impl ToTokens for PatPath {
2847 fn to_tokens(&self, tokens: &mut Tokens) {
2848 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2849 }
2850 }
2851
Michael Layzell734adb42017-06-07 16:58:31 -04002852 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002853 impl ToTokens for PatTuple {
2854 fn to_tokens(&self, tokens: &mut Tokens) {
2855 self.paren_token.surround(tokens, |tokens| {
2856 for (i, token) in self.pats.iter().enumerate() {
2857 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002858 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2859 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002860 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002861 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002862 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002863
2864 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002865 // Ensure there is a comma before the .. token.
2866 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002867 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002868 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002869 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002870 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002871 });
2872 }
2873 }
2874
Michael Layzell734adb42017-06-07 16:58:31 -04002875 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002876 impl ToTokens for PatBox {
2877 fn to_tokens(&self, tokens: &mut Tokens) {
2878 self.box_token.to_tokens(tokens);
2879 self.pat.to_tokens(tokens);
2880 }
2881 }
2882
Michael Layzell734adb42017-06-07 16:58:31 -04002883 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002884 impl ToTokens for PatRef {
2885 fn to_tokens(&self, tokens: &mut Tokens) {
2886 self.and_token.to_tokens(tokens);
2887 self.mutbl.to_tokens(tokens);
2888 self.pat.to_tokens(tokens);
2889 }
2890 }
2891
Michael Layzell734adb42017-06-07 16:58:31 -04002892 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002893 impl ToTokens for PatLit {
2894 fn to_tokens(&self, tokens: &mut Tokens) {
2895 self.expr.to_tokens(tokens);
2896 }
2897 }
2898
Michael Layzell734adb42017-06-07 16:58:31 -04002899 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002900 impl ToTokens for PatRange {
2901 fn to_tokens(&self, tokens: &mut Tokens) {
2902 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002903 match self.limits {
2904 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2905 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2906 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002907 self.hi.to_tokens(tokens);
2908 }
2909 }
2910
Michael Layzell734adb42017-06-07 16:58:31 -04002911 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002912 impl ToTokens for PatSlice {
2913 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002914 // XXX: This is a mess, and it will be so easy to screw it up. How
2915 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002916 self.bracket_token.surround(tokens, |tokens| {
2917 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002918
2919 // If we need a comma before the middle or standalone .. token,
2920 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002921 if !self.front.empty_or_trailing()
2922 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002923 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002924 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002925 }
2926
2927 // If we have an identifier, we always need a .. token.
2928 if self.middle.is_some() {
2929 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002930 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002931 } else if self.dot2_token.is_some() {
2932 self.dot2_token.to_tokens(tokens);
2933 }
2934
2935 // Make sure we have a comma before the back half.
2936 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002937 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002938 self.back.to_tokens(tokens);
2939 } else {
2940 self.comma_token.to_tokens(tokens);
2941 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002942 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002943 }
2944 }
2945
Michael Layzell734adb42017-06-07 16:58:31 -04002946 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002947 impl ToTokens for FieldPat {
2948 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002949 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002950 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05002951 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002952 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002953 }
2954 self.pat.to_tokens(tokens);
2955 }
2956 }
2957
Michael Layzell734adb42017-06-07 16:58:31 -04002958 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002959 impl ToTokens for BindingMode {
2960 fn to_tokens(&self, tokens: &mut Tokens) {
2961 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002962 BindingMode::ByRef(ref t, ref m) => {
2963 t.to_tokens(tokens);
2964 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002965 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002966 BindingMode::ByValue(ref m) => {
2967 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002968 }
2969 }
2970 }
2971 }
David Tolnay42602292016-10-01 22:25:45 -07002972
Michael Layzell734adb42017-06-07 16:58:31 -04002973 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002974 impl ToTokens for CaptureBy {
2975 fn to_tokens(&self, tokens: &mut Tokens) {
2976 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002977 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002978 CaptureBy::Ref => {
2979 // nothing
2980 }
David Tolnay89e05672016-10-02 14:39:42 -07002981 }
2982 }
2983 }
2984
Michael Layzell734adb42017-06-07 16:58:31 -04002985 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002986 impl ToTokens for Block {
2987 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002988 self.brace_token.surround(tokens, |tokens| {
2989 tokens.append_all(&self.stmts);
2990 });
David Tolnay42602292016-10-01 22:25:45 -07002991 }
2992 }
2993
Michael Layzell734adb42017-06-07 16:58:31 -04002994 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002995 impl ToTokens for Stmt {
2996 fn to_tokens(&self, tokens: &mut Tokens) {
2997 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002998 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002999 Stmt::Item(ref item) => item.to_tokens(tokens),
3000 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003001 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003002 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003003 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003004 }
David Tolnaydecf28d2017-11-11 11:56:45 -08003005 Stmt::Macro(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07003006 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07003007 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07003008 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07003009 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003010 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003011 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
3012 // no semicolon
3013 }
David Tolnay13b3d352016-10-03 00:31:15 -07003014 }
3015 }
David Tolnay42602292016-10-01 22:25:45 -07003016 }
3017 }
3018 }
David Tolnay191e0582016-10-02 18:31:09 -07003019
Michael Layzell734adb42017-06-07 16:58:31 -04003020 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003021 impl ToTokens for Local {
3022 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003023 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003024 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003025 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003026 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003027 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003028 self.ty.to_tokens(tokens);
3029 }
3030 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003031 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003032 self.init.to_tokens(tokens);
3033 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003034 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003035 }
3036 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003037}