blob: b0007fe167d20970f9d37069f2e95a9c45dd98ce [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,
Alex Crichton62a0a592017-05-22 13:58:53 -070080 }),
Clar Charrd22b5702017-03-10 15:24:56 -050081
Alex Crichton62a0a592017-05-22 13:58:53 -070082 /// A binary operation, e.g. `a + b`, `a * b`.
83 pub Binary(ExprBinary {
84 pub op: BinOp,
85 pub left: Box<Expr>,
86 pub right: Box<Expr>,
87 }),
Clar Charrd22b5702017-03-10 15:24:56 -050088
Alex Crichton62a0a592017-05-22 13:58:53 -070089 /// A unary operation, e.g. `!x`, `*x`.
90 pub Unary(ExprUnary {
91 pub op: UnOp,
92 pub expr: Box<Expr>,
93 }),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A literal, e.g. `1`, `"foo"`.
96 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050097
Alex Crichton62a0a592017-05-22 13:58:53 -070098 /// A cast, e.g. `foo as f64`.
99 pub Cast(ExprCast {
100 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800101 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800102 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500104
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 /// A type ascription, e.g. `foo: f64`.
106 pub Type(ExprType {
107 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800108 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800109 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500111
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 /// An `if` block, with an optional else block
113 ///
114 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400115 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700116 pub cond: Box<Expr>,
117 pub if_true: Block,
118 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800119 pub if_token: Token![if],
120 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700121 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500122
Alex Crichton62a0a592017-05-22 13:58:53 -0700123 /// An `if let` expression with an optional else block
124 ///
125 /// E.g., `if let pat = expr { block } else { expr }`
126 ///
127 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400128 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700129 pub pat: Box<Pat>,
130 pub expr: Box<Expr>,
131 pub if_true: Block,
132 pub if_false: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800133 pub if_token: Token![if],
134 pub let_token: Token![let],
135 pub eq_token: Token![=],
136 pub else_token: Option<Token![else]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700137 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500138
Alex Crichton62a0a592017-05-22 13:58:53 -0700139 /// A while loop, with an optional label
140 ///
141 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400142 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700143 pub cond: Box<Expr>,
144 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700145 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800146 pub colon_token: Option<Token![:]>,
147 pub while_token: Token![while],
Alex Crichton62a0a592017-05-22 13:58:53 -0700148 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500149
Alex Crichton62a0a592017-05-22 13:58:53 -0700150 /// A while-let loop, with an optional label.
151 ///
152 /// E.g., `'label: while let pat = expr { block }`
153 ///
154 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400155 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700156 pub pat: Box<Pat>,
157 pub expr: Box<Expr>,
158 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700159 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800160 pub colon_token: Option<Token![:]>,
161 pub while_token: Token![while],
162 pub let_token: Token![let],
163 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700164 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500165
Alex Crichton62a0a592017-05-22 13:58:53 -0700166 /// A for loop, with an optional label.
167 ///
168 /// E.g., `'label: for pat in expr { block }`
169 ///
170 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400171 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700172 pub pat: Box<Pat>,
173 pub expr: Box<Expr>,
174 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700175 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800176 pub for_token: Token![for],
177 pub colon_token: Option<Token![:]>,
178 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700179 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500180
Alex Crichton62a0a592017-05-22 13:58:53 -0700181 /// Conditionless loop with an optional label.
182 ///
183 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400184 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700185 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700186 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800187 pub loop_token: Token![loop],
188 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700189 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500190
Alex Crichton62a0a592017-05-22 13:58:53 -0700191 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400192 pub Match(ExprMatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800193 pub match_token: Token![match],
David Tolnay32954ef2017-12-26 22:43:16 -0500194 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700195 pub expr: Box<Expr>,
196 pub arms: Vec<Arm>,
197 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500198
Alex Crichton62a0a592017-05-22 13:58:53 -0700199 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400200 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800202 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500203 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800204 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500205 pub output: ReturnType,
206 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500208
Nika Layzell640832a2017-12-04 13:37:09 -0500209 /// An unsafe block (`unsafe { ... }`)
210 pub Unsafe(ExprUnsafe #full {
211 pub unsafe_token: Token![unsafe],
212 pub block: Block,
213 }),
214
215 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400216 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700217 pub block: Block,
218 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700219
Alex Crichton62a0a592017-05-22 13:58:53 -0700220 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub left: Box<Expr>,
223 pub right: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800224 pub eq_token: Token![=],
Alex Crichton62a0a592017-05-22 13:58:53 -0700225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// An assignment with an operator
228 ///
229 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400230 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 pub op: BinOp,
232 pub left: Box<Expr>,
233 pub right: Box<Expr>,
234 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500235
David Tolnay85b69a42017-12-27 20:43:10 -0500236 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
237 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400238 pub Field(ExprField #full {
David Tolnay85b69a42017-12-27 20:43:10 -0500239 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800240 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500241 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500243
Alex Crichton62a0a592017-05-22 13:58:53 -0700244 /// An indexing operation (`foo[2]`)
245 pub Index(ExprIndex {
246 pub expr: Box<Expr>,
247 pub index: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500248 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500250
David Tolnaybe55d7b2017-12-17 23:41:20 -0800251 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400252 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 pub from: Option<Box<Expr>>,
254 pub to: Option<Box<Expr>>,
255 pub limits: RangeLimits,
256 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700257
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 /// Variable reference, possibly containing `::` and/or type
259 /// parameters, e.g. foo::bar::<baz>.
260 ///
261 /// Optionally "qualified",
262 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
263 pub Path(ExprPath {
264 pub qself: Option<QSelf>,
265 pub path: Path,
266 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700267
Alex Crichton62a0a592017-05-22 13:58:53 -0700268 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400269 pub AddrOf(ExprAddrOf #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800270 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700271 pub mutbl: Mutability,
272 pub expr: Box<Expr>,
273 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500274
Alex Crichton62a0a592017-05-22 13:58:53 -0700275 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400276 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700277 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700278 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800279 pub break_token: Token![break],
Alex Crichton62a0a592017-05-22 13:58:53 -0700280 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500281
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400283 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700284 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800285 pub continue_token: Token![continue],
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500287
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400289 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700290 pub expr: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800291 pub return_token: Token![return],
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700293
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 /// A macro invocation; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800295 pub Macro(Macro),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700296
Alex Crichton62a0a592017-05-22 13:58:53 -0700297 /// A struct literal expression.
298 ///
299 /// For example, `Foo {x: 1, y: 2}`, or
300 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400301 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700302 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800303 pub fields: Delimited<FieldValue, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700304 pub rest: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800305 pub dot2_token: Option<Token![..]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500306 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700307 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700308
Alex Crichton62a0a592017-05-22 13:58:53 -0700309 /// An array literal constructed from one repeated element.
310 ///
311 /// For example, `[1; 5]`. The first expression is the element
312 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400313 pub Repeat(ExprRepeat #full {
David Tolnay32954ef2017-12-26 22:43:16 -0500314 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800315 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700316 pub expr: Box<Expr>,
317 pub amt: Box<Expr>,
318 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700319
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 /// No-op: used solely so we can pretty-print faithfully
321 pub Paren(ExprParen {
322 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500323 pub paren_token: token::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700324 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700325
Michael Layzell93c36282017-06-04 20:43:14 -0400326 /// No-op: used solely so we can pretty-print faithfully
327 ///
328 /// A `group` represents a `None`-delimited span in the input
329 /// `TokenStream` which affects the precidence of the resulting
330 /// expression. They are used for macro hygiene.
331 pub Group(ExprGroup {
332 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500333 pub group_token: token::Group,
Michael Layzell93c36282017-06-04 20:43:14 -0400334 }),
335
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400337 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700338 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800339 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700340 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700341
Alex Crichton62a0a592017-05-22 13:58:53 -0700342 /// A catch expression.
343 ///
344 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400345 pub Catch(ExprCatch #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800346 pub do_token: Token![do],
347 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700348 pub block: Block,
349 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700350
351 /// A yield expression.
352 ///
353 /// E.g. `yield expr`
354 pub Yield(ExprYield #full {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800355 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700356 pub expr: Option<Box<Expr>>,
357 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700358 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700359}
360
Michael Layzell734adb42017-06-07 16:58:31 -0400361#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500362ast_enum! {
363 /// A struct or tuple struct field accessed in a struct literal or field
364 /// expression.
365 pub enum Member {
366 /// A named field like `self.x`.
367 Named(Ident),
368 /// An unnamed field like `self.0`.
369 Unnamed(Index),
370 }
371}
372
373#[cfg(feature = "full")]
374ast_struct! {
375 /// The index of an unnamed tuple struct field.
376 pub struct Index #manual_extra_traits {
377 pub index: u32,
378 pub span: Span,
379 }
380}
381
382#[cfg(feature = "full")]
383impl Eq for Index {}
384
385#[cfg(feature = "full")]
386impl PartialEq for Index {
387 fn eq(&self, other: &Self) -> bool {
388 self.index == other.index
389 }
390}
391
392#[cfg(feature = "full")]
393impl Hash for Index {
394 fn hash<H: Hasher>(&self, state: &mut H) {
395 self.index.hash(state);
396 }
397}
398
399#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700400ast_struct! {
401 /// A field-value pair in a struct literal.
402 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500403 /// Attributes tagged on the field.
404 pub attrs: Vec<Attribute>,
405
406 /// Name or index of the field.
407 pub member: Member,
408
409 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500410
Alex Crichton62a0a592017-05-22 13:58:53 -0700411 /// Value of the field.
412 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500413
Alex Crichton62a0a592017-05-22 13:58:53 -0700414 /// Whether this is a shorthand field, e.g. `Struct { x }`
415 /// instead of `Struct { x: x }`.
416 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700417 }
David Tolnay055a7042016-10-02 19:23:54 -0700418}
419
Michael Layzell734adb42017-06-07 16:58:31 -0400420#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700421ast_struct! {
422 /// A Block (`{ .. }`).
423 ///
424 /// E.g. `{ .. }` as in `fn foo() { .. }`
425 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500426 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700427 /// Statements in a block
428 pub stmts: Vec<Stmt>,
429 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700430}
431
Michael Layzell734adb42017-06-07 16:58:31 -0400432#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700433ast_enum! {
434 /// A statement, usually ending in a semicolon.
435 pub enum Stmt {
436 /// A local (let) binding.
437 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700438
Alex Crichton62a0a592017-05-22 13:58:53 -0700439 /// An item definition.
440 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 /// Expr without trailing semicolon.
443 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800446 Semi(Box<Expr>, Token![;]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700447 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700448}
449
Michael Layzell734adb42017-06-07 16:58:31 -0400450#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700451ast_struct! {
452 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
453 pub struct Local {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800454 pub let_token: Token![let],
455 pub colon_token: Option<Token![:]>,
456 pub eq_token: Option<Token![=]>,
457 pub semi_token: Token![;],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458
Alex Crichton62a0a592017-05-22 13:58:53 -0700459 pub pat: Box<Pat>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800460 pub ty: Option<Box<Type>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// Initializer expression to set the value, if any
463 pub init: Option<Box<Expr>>,
464 pub attrs: Vec<Attribute>,
465 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700466}
467
Michael Layzell734adb42017-06-07 16:58:31 -0400468#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700469ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700470 // Clippy false positive
471 // https://github.com/Manishearth/rust-clippy/issues/1241
472 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
473 pub enum Pat {
474 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800476 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700477 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700478
Alex Crichton62a0a592017-05-22 13:58:53 -0700479 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
480 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
481 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
482 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700483 pub Ident(PatIdent {
484 pub mode: BindingMode,
485 pub ident: Ident,
486 pub subpat: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800487 pub at_token: Option<Token![@]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700488 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
491 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700492 pub Struct(PatStruct {
493 pub path: Path,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800494 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500495 pub brace_token: token::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800496 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700497 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700498
Alex Crichton62a0a592017-05-22 13:58:53 -0700499 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
500 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
501 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub TupleStruct(PatTupleStruct {
503 pub path: Path,
504 pub pat: PatTuple,
505 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700506
Alex Crichton62a0a592017-05-22 13:58:53 -0700507 /// A possibly qualified path pattern.
508 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
509 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
510 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700511 pub Path(PatPath {
512 pub qself: Option<QSelf>,
513 pub path: Path,
514 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700515
Alex Crichton62a0a592017-05-22 13:58:53 -0700516 /// A tuple pattern `(a, b)`.
517 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
518 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700519 pub Tuple(PatTuple {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800520 pub pats: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 pub dots_pos: Option<usize>,
David Tolnay32954ef2017-12-26 22:43:16 -0500522 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800523 pub dot2_token: Option<Token![..]>,
524 pub comma_token: Option<Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700526 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700527 pub Box(PatBox {
528 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800529 pub box_token: Token![box],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700530 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700531 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700532 pub Ref(PatRef {
533 pub pat: Box<Pat>,
534 pub mutbl: Mutability,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800535 pub and_token: Token![&],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700536 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700537 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700538 pub Lit(PatLit {
539 pub expr: Box<Expr>,
540 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800541 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700542 pub Range(PatRange {
543 pub lo: Box<Expr>,
544 pub hi: Box<Expr>,
545 pub limits: RangeLimits,
546 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400547 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700548 pub Slice(PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800549 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700550 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800551 pub back: Delimited<Pat, Token![,]>,
552 pub dot2_token: Option<Token![..]>,
553 pub comma_token: Option<Token![,]>,
David Tolnay32954ef2017-12-26 22:43:16 -0500554 pub bracket_token: token::Bracket,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700556 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800557 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700558 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700559}
560
Michael Layzell734adb42017-06-07 16:58:31 -0400561#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700562ast_struct! {
563 /// An arm of a 'match'.
564 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800565 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700566 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500567 /// ```rust
568 /// # #![feature(dotdoteq_in_patterns)]
569 /// #
570 /// # fn main() {
571 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700572 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500573 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700574 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500575 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500577 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700578 /// ```
579 pub struct Arm {
580 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800581 pub pats: Delimited<Pat, Token![|]>,
582 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700583 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800584 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700585 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800586 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700587 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700588}
589
Michael Layzell734adb42017-06-07 16:58:31 -0400590#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700591ast_enum! {
592 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700593 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700594 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800595 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700596 Ref,
597 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700598}
599
Michael Layzell734adb42017-06-07 16:58:31 -0400600#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700601ast_enum! {
602 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700603 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700604 pub enum RangeLimits {
605 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800606 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700607 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800608 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700609 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700610}
611
Michael Layzell734adb42017-06-07 16:58:31 -0400612#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700613ast_struct! {
614 /// A single field in a struct pattern
615 ///
616 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
617 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
618 /// except `is_shorthand` is true
619 pub struct FieldPat {
620 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500621 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700622 /// The pattern the field is destructured to
623 pub pat: Box<Pat>,
624 pub is_shorthand: bool,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800625 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700626 pub attrs: Vec<Attribute>,
627 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700628}
629
Michael Layzell734adb42017-06-07 16:58:31 -0400630#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700631ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700632 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700633 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800634 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700635 ByValue(Mutability),
636 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700637}
638
Michael Layzell734adb42017-06-07 16:58:31 -0400639#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400640ast_enum! {
641 #[cfg_attr(feature = "clone-impls", derive(Copy))]
642 pub enum InPlaceKind {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800643 Arrow(Token![<-]),
644 In(Token![in]),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400645 }
646}
647
Michael Layzell3936ceb2017-07-08 00:28:36 -0400648#[cfg(any(feature = "parsing", feature = "printing"))]
649#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700650fn arm_expr_requires_comma(expr: &Expr) -> bool {
651 // see https://github.com/rust-lang/rust/blob/eb8f2586e
652 // /src/libsyntax/parse/classify.rs#L17-L37
653 match expr.node {
David Tolnay51382052017-12-27 13:46:21 -0500654 ExprKind::Unsafe(..)
655 | ExprKind::Block(..)
656 | ExprKind::If(..)
657 | ExprKind::IfLet(..)
658 | ExprKind::Match(..)
659 | ExprKind::While(..)
660 | ExprKind::WhileLet(..)
661 | ExprKind::Loop(..)
662 | ExprKind::ForLoop(..)
663 | ExprKind::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700664 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400665 }
666}
667
David Tolnayb9c8e322016-09-23 20:48:37 -0700668#[cfg(feature = "parsing")]
669pub mod parsing {
670 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700671 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700672
Michael Layzell734adb42017-06-07 16:58:31 -0400673 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500674 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500675 use synom::Synom;
676 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400677 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500678 use parse_error;
David Tolnay203557a2017-12-27 23:59:33 -0500679 use synom::PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700680
David Tolnaybcf26022017-12-25 22:10:52 -0500681 // When we're parsing expressions which occur before blocks, like in an if
682 // statement's condition, we cannot parse a struct literal.
683 //
684 // Struct literals are ambiguous in certain positions
685 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700686 macro_rules! ambiguous_expr {
687 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700688 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700689 };
690 }
691
David Tolnaybcf26022017-12-25 22:10:52 -0500692 // When we are parsing an optional suffix expression, we cannot allow blocks
693 // if structs are not allowed.
694 //
695 // Example:
696 //
697 // if break {} {}
698 //
699 // is ambiguous between:
700 //
701 // if (break {}) {}
702 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400703 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400704 macro_rules! opt_ambiguous_expr {
705 ($i:expr, $allow_struct:ident) => {
706 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
707 };
708 }
709
Alex Crichton954046c2017-05-30 21:49:42 -0700710 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400711 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700712
713 fn description() -> Option<&'static str> {
714 Some("expression")
715 }
716 }
717
Michael Layzell734adb42017-06-07 16:58:31 -0400718 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700719 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
720
David Tolnaybcf26022017-12-25 22:10:52 -0500721 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400722 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500723 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400724 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700725 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400726 call!(assign_expr, allow_struct, allow_block),
727 ExprKind::into
728 )
729 }
730
Michael Layzell734adb42017-06-07 16:58:31 -0400731 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500732 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
Michael Layzell734adb42017-06-07 16:58:31 -0400733 map!(
734 i,
735 // NOTE: We intentionally skip assign_expr, placement_expr, and
736 // range_expr, as they are not parsed in non-full mode.
737 call!(or_expr, allow_struct, allow_block),
738 ExprKind::into
739 )
740 }
741
David Tolnaybcf26022017-12-25 22:10:52 -0500742 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400743 macro_rules! binop {
744 (
745 $name: ident,
746 $next: ident,
747 $submac: ident!( $($args:tt)* )
748 ) => {
749 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
750 mut e: call!($next, allow_struct, allow_block) >>
751 many0!(do_parse!(
752 op: $submac!($($args)*) >>
753 rhs: call!($next, allow_struct, true) >>
754 ({
755 e = ExprBinary {
756 left: Box::new(e.into()),
757 op: op,
758 right: Box::new(rhs.into()),
759 }.into();
760 })
761 )) >>
762 (e)
763 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700764 }
David Tolnay54e854d2016-10-24 12:03:30 -0700765 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700766
David Tolnaybcf26022017-12-25 22:10:52 -0500767 // <placement> = <placement> ..
768 // <placement> += <placement> ..
769 // <placement> -= <placement> ..
770 // <placement> *= <placement> ..
771 // <placement> /= <placement> ..
772 // <placement> %= <placement> ..
773 // <placement> ^= <placement> ..
774 // <placement> &= <placement> ..
775 // <placement> |= <placement> ..
776 // <placement> <<= <placement> ..
777 // <placement> >>= <placement> ..
778 //
779 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400780 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400781 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
782 mut e: call!(placement_expr, allow_struct, allow_block) >>
783 alt!(
784 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800785 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400786 // Recurse into self to parse right-associative operator.
787 rhs: call!(assign_expr, allow_struct, true) >>
788 ({
789 e = ExprAssign {
790 left: Box::new(e.into()),
791 eq_token: eq,
792 right: Box::new(rhs.into()),
793 }.into();
794 })
795 )
796 |
797 do_parse!(
798 op: call!(BinOp::parse_assign_op) >>
799 // Recurse into self to parse right-associative operator.
800 rhs: call!(assign_expr, allow_struct, true) >>
801 ({
802 e = ExprAssignOp {
803 left: Box::new(e.into()),
804 op: op,
805 right: Box::new(rhs.into()),
806 }.into();
807 })
808 )
809 |
810 epsilon!()
811 ) >>
812 (e)
813 ));
814
David Tolnaybcf26022017-12-25 22:10:52 -0500815 // <range> <- <range> ..
816 //
817 // NOTE: The `in place { expr }` version of this syntax is parsed in
818 // `atom_expr`, not here.
819 //
820 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400821 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400822 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
823 mut e: call!(range_expr, allow_struct, allow_block) >>
824 alt!(
825 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800826 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400827 // Recurse into self to parse right-associative operator.
828 rhs: call!(placement_expr, allow_struct, true) >>
829 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400830 e = ExprInPlace {
831 // op: BinOp::Place(larrow),
832 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400833 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400834 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400835 }.into();
836 })
837 )
838 |
839 epsilon!()
840 ) >>
841 (e)
842 ));
843
David Tolnaybcf26022017-12-25 22:10:52 -0500844 // <or> ... <or> ..
845 // <or> .. <or> ..
846 // <or> ..
847 //
848 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
849 // rules are for parsing these expressions are, but this is not correct.
850 // For example, `a .. b .. c` is not a legal expression. It should not
851 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
852 //
853 // NOTE: The form of ranges which don't include a preceding expression are
854 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400855 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400856 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
857 mut e: call!(or_expr, allow_struct, allow_block) >>
858 many0!(do_parse!(
859 limits: syn!(RangeLimits) >>
860 // We don't want to allow blocks here if we don't allow structs. See
861 // the reasoning for `opt_ambiguous_expr!` above.
862 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
863 ({
864 e = ExprRange {
865 from: Some(Box::new(e.into())),
866 limits: limits,
867 to: hi.map(|e| Box::new(e.into())),
868 }.into();
869 })
870 )) >>
871 (e)
872 ));
873
David Tolnaybcf26022017-12-25 22:10:52 -0500874 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800875 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400876
David Tolnaybcf26022017-12-25 22:10:52 -0500877 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800878 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400879
David Tolnaybcf26022017-12-25 22:10:52 -0500880 // <bitor> == <bitor> ...
881 // <bitor> != <bitor> ...
882 // <bitor> >= <bitor> ...
883 // <bitor> <= <bitor> ...
884 // <bitor> > <bitor> ...
885 // <bitor> < <bitor> ...
886 //
887 // NOTE: This operator appears to be parsed as left-associative, but errors
888 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500889 binop!(
890 compare_expr,
891 bitor_expr,
892 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800893 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400894 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800895 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400896 |
897 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800898 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400899 |
900 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800901 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400903 do_parse!(
904 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800905 not!(punct!(<-)) >>
906 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400907 (BinOp::Lt(t))
908 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400909 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800910 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500911 )
912 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400913
David Tolnaybcf26022017-12-25 22:10:52 -0500914 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500915 binop!(
916 bitor_expr,
917 bitxor_expr,
918 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
919 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400920
David Tolnaybcf26022017-12-25 22:10:52 -0500921 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500922 binop!(
923 bitxor_expr,
924 bitand_expr,
925 do_parse!(
926 // NOTE: Make sure we aren't looking at ^=.
927 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
928 )
929 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400930
David Tolnaybcf26022017-12-25 22:10:52 -0500931 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -0500932 binop!(
933 bitand_expr,
934 shift_expr,
935 do_parse!(
936 // NOTE: Make sure we aren't looking at && or &=.
937 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
938 )
939 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400940
David Tolnaybcf26022017-12-25 22:10:52 -0500941 // <arith> << <arith> ...
942 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -0500943 binop!(
944 shift_expr,
945 arith_expr,
946 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800947 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400948 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800949 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -0500950 )
951 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400952
David Tolnaybcf26022017-12-25 22:10:52 -0500953 // <term> + <term> ...
954 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -0500955 binop!(
956 arith_expr,
957 term_expr,
958 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800959 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400960 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800961 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -0500962 )
963 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400964
David Tolnaybcf26022017-12-25 22:10:52 -0500965 // <cast> * <cast> ...
966 // <cast> / <cast> ...
967 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -0500968 binop!(
969 term_expr,
970 cast_expr,
971 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800972 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400973 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800974 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400975 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800976 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -0500977 )
978 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400979
David Tolnaybcf26022017-12-25 22:10:52 -0500980 // <unary> as <ty>
981 // <unary> : <ty>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400982 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
983 mut e: call!(unary_expr, allow_struct, allow_block) >>
984 many0!(alt!(
985 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800986 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400987 // We can't accept `A + B` in cast expressions, as it's
988 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800989 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400990 ({
991 e = ExprCast {
992 expr: Box::new(e.into()),
993 as_token: as_,
994 ty: Box::new(ty),
995 }.into();
996 })
997 )
998 |
999 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001000 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001001 // We can't accept `A + B` in cast expressions, as it's
1002 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001003 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001004 ({
1005 e = ExprType {
1006 expr: Box::new(e.into()),
1007 colon_token: colon,
1008 ty: Box::new(ty),
1009 }.into();
1010 })
1011 )
1012 )) >>
1013 (e)
1014 ));
1015
David Tolnaybcf26022017-12-25 22:10:52 -05001016 // <UnOp> <trailer>
1017 // & <trailer>
1018 // &mut <trailer>
1019 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001020 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001021 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1022 do_parse!(
1023 op: syn!(UnOp) >>
1024 expr: call!(unary_expr, allow_struct, true) >>
1025 (ExprUnary {
1026 op: op,
1027 expr: Box::new(expr.into()),
1028 }.into())
1029 )
1030 |
1031 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001032 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001033 mutability: syn!(Mutability) >>
1034 expr: call!(unary_expr, allow_struct, true) >>
1035 (ExprAddrOf {
1036 and_token: and,
1037 mutbl: mutability,
1038 expr: Box::new(expr.into()),
1039 }.into())
1040 )
1041 |
1042 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001043 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001044 expr: call!(unary_expr, allow_struct, true) >>
1045 (ExprBox {
1046 box_token: box_,
1047 expr: Box::new(expr.into()),
1048 }.into())
1049 )
1050 |
1051 call!(trailer_expr, allow_struct, allow_block)
1052 ));
1053
Michael Layzell734adb42017-06-07 16:58:31 -04001054 // XXX: This duplication is ugly
1055 #[cfg(not(feature = "full"))]
1056 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1057 do_parse!(
1058 op: syn!(UnOp) >>
1059 expr: call!(unary_expr, allow_struct, true) >>
1060 (ExprUnary {
1061 op: op,
1062 expr: Box::new(expr.into()),
1063 }.into())
1064 )
1065 |
1066 call!(trailer_expr, allow_struct, allow_block)
1067 ));
1068
David Tolnaybcf26022017-12-25 22:10:52 -05001069 // <atom> (..<args>) ...
1070 // <atom> . <ident> (..<args>) ...
1071 // <atom> . <ident> ...
1072 // <atom> . <lit> ...
1073 // <atom> [ <expr> ] ...
1074 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001075 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001076 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1077 mut e: call!(atom_expr, allow_struct, allow_block) >>
1078 many0!(alt!(
1079 tap!(args: and_call => {
1080 let (args, paren) = args;
1081 e = ExprCall {
1082 func: Box::new(e.into()),
1083 args: args,
1084 paren_token: paren,
1085 }.into();
1086 })
1087 |
1088 tap!(more: and_method_call => {
1089 let mut call = more;
1090 call.expr = Box::new(e.into());
1091 e = call.into();
1092 })
1093 |
1094 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001095 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001096 e = ExprField {
David Tolnay85b69a42017-12-27 20:43:10 -05001097 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001098 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001099 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001100 }.into();
1101 })
1102 |
1103 tap!(i: and_index => {
1104 let (i, token) = i;
1105 e = ExprIndex {
1106 expr: Box::new(e.into()),
1107 bracket_token: token,
1108 index: Box::new(i),
1109 }.into();
1110 })
1111 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001112 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001113 e = ExprTry {
1114 expr: Box::new(e.into()),
1115 question_token: question,
1116 }.into();
1117 })
1118 )) >>
1119 (e)
1120 ));
1121
Michael Layzell734adb42017-06-07 16:58:31 -04001122 // XXX: Duplication == ugly
1123 #[cfg(not(feature = "full"))]
1124 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1125 mut e: call!(atom_expr, allow_struct, allow_block) >>
1126 many0!(alt!(
1127 tap!(args: and_call => {
1128 let (args, paren) = args;
1129 e = ExprCall {
1130 func: Box::new(e.into()),
1131 args: args,
1132 paren_token: paren,
1133 }.into();
1134 })
1135 |
1136 tap!(i: and_index => {
1137 let (i, token) = i;
1138 e = ExprIndex {
1139 expr: Box::new(e.into()),
1140 bracket_token: token,
1141 index: Box::new(i),
1142 }.into();
1143 })
1144 )) >>
1145 (e)
1146 ));
1147
David Tolnaybcf26022017-12-25 22:10:52 -05001148 // Parse all atomic expressions which don't have to worry about precidence
1149 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001150 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001151 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001152 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1153 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001154 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1155 |
1156 // must be before expr_path
1157 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1158 |
1159 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1160 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001161 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001162 |
1163 call!(expr_break, allow_struct) // must be before expr_path
1164 |
1165 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1166 |
1167 call!(expr_ret, allow_struct) // must be before expr_path
1168 |
1169 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1170 syn!(ExprInPlace) => { ExprKind::InPlace }
1171 |
1172 syn!(ExprArray) => { ExprKind::Array }
1173 |
David Tolnay05362582017-12-26 01:33:57 -05001174 syn!(ExprTuple) => { ExprKind::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001175 |
1176 syn!(ExprIf) => { ExprKind::If }
1177 |
1178 syn!(ExprIfLet) => { ExprKind::IfLet }
1179 |
1180 syn!(ExprWhile) => { ExprKind::While }
1181 |
1182 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1183 |
1184 syn!(ExprForLoop) => { ExprKind::ForLoop }
1185 |
1186 syn!(ExprLoop) => { ExprKind::Loop }
1187 |
1188 syn!(ExprMatch) => { ExprKind::Match }
1189 |
1190 syn!(ExprCatch) => { ExprKind::Catch }
1191 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001192 syn!(ExprYield) => { ExprKind::Yield }
1193 |
Nika Layzell640832a2017-12-04 13:37:09 -05001194 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1195 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001196 call!(expr_closure, allow_struct)
1197 |
1198 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1199 |
1200 // NOTE: This is the prefix-form of range
1201 call!(expr_range, allow_struct)
1202 |
1203 syn!(ExprPath) => { ExprKind::Path }
1204 |
1205 syn!(ExprRepeat) => { ExprKind::Repeat }
1206 ));
1207
Michael Layzell734adb42017-06-07 16:58:31 -04001208 #[cfg(not(feature = "full"))]
1209 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1210 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1211 |
1212 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1213 |
1214 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1215 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001216 syn!(Macro) => { ExprKind::Macro } // must be before expr_path
Michael Layzell734adb42017-06-07 16:58:31 -04001217 |
1218 syn!(ExprPath) => { ExprKind::Path }
1219 ));
1220
Michael Layzell734adb42017-06-07 16:58:31 -04001221 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001222 named!(expr_nosemi -> Expr, map!(alt!(
1223 syn!(ExprIf) => { ExprKind::If }
1224 |
1225 syn!(ExprIfLet) => { ExprKind::IfLet }
1226 |
1227 syn!(ExprWhile) => { ExprKind::While }
1228 |
1229 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1230 |
1231 syn!(ExprForLoop) => { ExprKind::ForLoop }
1232 |
1233 syn!(ExprLoop) => { ExprKind::Loop }
1234 |
1235 syn!(ExprMatch) => { ExprKind::Match }
1236 |
1237 syn!(ExprCatch) => { ExprKind::Catch }
1238 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001239 syn!(ExprYield) => { ExprKind::Yield }
1240 |
Nika Layzell640832a2017-12-04 13:37:09 -05001241 syn!(ExprUnsafe) => { ExprKind::Unsafe }
1242 |
Michael Layzell35418782017-06-07 09:20:25 -04001243 syn!(ExprBlock) => { ExprKind::Block }
1244 ), Expr::from));
1245
Michael Layzell93c36282017-06-04 20:43:14 -04001246 impl Synom for ExprGroup {
1247 named!(parse -> Self, do_parse!(
1248 e: grouped!(syn!(Expr)) >>
1249 (ExprGroup {
1250 expr: Box::new(e.0),
1251 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001252 })
Michael Layzell93c36282017-06-04 20:43:14 -04001253 ));
1254 }
1255
Alex Crichton954046c2017-05-30 21:49:42 -07001256 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001257 named!(parse -> Self, do_parse!(
1258 e: parens!(syn!(Expr)) >>
1259 (ExprParen {
1260 expr: Box::new(e.0),
1261 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001262 })
Michael Layzell92639a52017-06-01 00:07:44 -04001263 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001264 }
David Tolnay89e05672016-10-02 14:39:42 -07001265
Michael Layzell734adb42017-06-07 16:58:31 -04001266 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001267 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001268 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001269 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001270 place: expr_no_struct >>
1271 value: braces!(call!(Block::parse_within)) >>
1272 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001273 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001274 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001275 value: Box::new(Expr {
1276 node: ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001277 block: Block {
1278 stmts: value.0,
1279 brace_token: value.1,
1280 },
1281 }.into(),
1282 attrs: Vec::new(),
1283 }),
1284 })
1285 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001286 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001287
Michael Layzell734adb42017-06-07 16:58:31 -04001288 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001289 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001290 named!(parse -> Self, do_parse!(
1291 elems: brackets!(call!(Delimited::parse_terminated)) >>
1292 (ExprArray {
1293 exprs: elems.0,
1294 bracket_token: elems.1,
1295 })
1296 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001297 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001298
David Tolnay32954ef2017-12-26 22:43:16 -05001299 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001300 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001301
Michael Layzell734adb42017-06-07 16:58:31 -04001302 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001303 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001304 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001305 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001306 typarams: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001307 colon2: punct!(::) >>
1308 lt: punct!(<) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001309 tys: call!(Delimited::parse_terminated) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001310 gt: punct!(>) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001311 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001312 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001313 args: parens!(call!(Delimited::parse_terminated)) >>
1314 ({
1315 let (colon2, lt, tys, gt) = match typarams {
1316 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1317 None => (None, None, None, None),
1318 };
1319 ExprMethodCall {
1320 // this expr will get overwritten after being returned
1321 expr: Box::new(ExprKind::Lit(Lit {
1322 span: Span::default(),
1323 value: LitKind::Bool(false),
1324 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001325
Alex Crichton954046c2017-05-30 21:49:42 -07001326 method: method,
1327 args: args.0,
1328 paren_token: args.1,
1329 dot_token: dot,
1330 lt_token: lt,
1331 gt_token: gt,
1332 colon2_token: colon2,
1333 typarams: tys.unwrap_or_default(),
1334 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001335 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001336 ));
1337
Michael Layzell734adb42017-06-07 16:58:31 -04001338 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001339 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001340 named!(parse -> Self, do_parse!(
1341 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001342 (ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001343 args: elems.0,
1344 paren_token: elems.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001345 })
1346 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001347 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001348
Michael Layzell734adb42017-06-07 16:58:31 -04001349 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001350 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001351 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001352 if_: keyword!(if) >>
1353 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001354 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001355 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001356 cond: expr_no_struct >>
1357 then_block: braces!(call!(Block::parse_within)) >>
1358 else_block: option!(else_block) >>
1359 (ExprIfLet {
1360 pat: Box::new(pat),
1361 let_token: let_,
1362 eq_token: eq,
1363 expr: Box::new(cond),
1364 if_true: Block {
1365 stmts: then_block.0,
1366 brace_token: then_block.1,
1367 },
1368 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001369 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001370 if_false: else_block.map(|p| Box::new(p.1.into())),
1371 })
1372 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001373 }
1374
Michael Layzell734adb42017-06-07 16:58:31 -04001375 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001376 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001377 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001378 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001379 cond: expr_no_struct >>
1380 then_block: braces!(call!(Block::parse_within)) >>
1381 else_block: option!(else_block) >>
1382 (ExprIf {
1383 cond: Box::new(cond),
1384 if_true: Block {
1385 stmts: then_block.0,
1386 brace_token: then_block.1,
1387 },
1388 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001389 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001390 if_false: else_block.map(|p| Box::new(p.1.into())),
1391 })
1392 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001393 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001394
Michael Layzell734adb42017-06-07 16:58:31 -04001395 #[cfg(feature = "full")]
David Tolnayf8db7ba2017-11-11 22:52:16 -08001396 named!(else_block -> (Token![else], ExprKind), do_parse!(
1397 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001398 expr: alt!(
1399 syn!(ExprIf) => { ExprKind::If }
1400 |
1401 syn!(ExprIfLet) => { ExprKind::IfLet }
1402 |
1403 do_parse!(
1404 else_block: braces!(call!(Block::parse_within)) >>
1405 (ExprKind::Block(ExprBlock {
Alex Crichton954046c2017-05-30 21:49:42 -07001406 block: Block {
1407 stmts: else_block.0,
1408 brace_token: else_block.1,
1409 },
1410 }))
David Tolnay939766a2016-09-23 23:48:12 -07001411 )
Alex Crichton954046c2017-05-30 21:49:42 -07001412 ) >>
1413 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001414 ));
1415
Michael Layzell734adb42017-06-07 16:58:31 -04001416 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001417 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001418 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001419 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1420 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001421 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001422 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001423 expr: expr_no_struct >>
1424 loop_block: syn!(Block) >>
1425 (ExprForLoop {
1426 for_token: for_,
1427 in_token: in_,
1428 pat: Box::new(pat),
1429 expr: Box::new(expr),
1430 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001431 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001432 label: lbl.map(|p| p.0),
1433 })
1434 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001435 }
Gregory Katze5f35682016-09-27 14:20:55 -04001436
Michael Layzell734adb42017-06-07 16:58:31 -04001437 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001438 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001439 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001440 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1441 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001442 loop_block: syn!(Block) >>
1443 (ExprLoop {
1444 loop_token: loop_,
1445 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001446 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001447 label: lbl.map(|p| p.0),
1448 })
1449 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001450 }
1451
Michael Layzell734adb42017-06-07 16:58:31 -04001452 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001453 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001454 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001455 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001456 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001457 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001458 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001459 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001460 ExprMatch {
1461 expr: Box::new(obj),
1462 match_token: match_,
1463 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001464 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001465 }
1466 })
1467 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001468 }
David Tolnay1978c672016-10-27 22:05:52 -07001469
Michael Layzell734adb42017-06-07 16:58:31 -04001470 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001471 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001472 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001473 do_: keyword!(do) >>
1474 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001475 catch_block: syn!(Block) >>
1476 (ExprCatch {
1477 block: catch_block,
1478 do_token: do_,
1479 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001480 })
Michael Layzell92639a52017-06-01 00:07:44 -04001481 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001482 }
Arnavion02ef13f2017-04-25 00:54:31 -07001483
Michael Layzell734adb42017-06-07 16:58:31 -04001484 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001485 impl Synom for ExprYield {
1486 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001487 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001488 expr: option!(syn!(Expr)) >>
1489 (ExprYield {
1490 yield_token: yield_,
1491 expr: expr.map(Box::new),
1492 })
1493 ));
1494 }
1495
1496 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001497 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001498 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001499 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001500 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001501 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1502 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001503 body: do_parse!(
1504 expr: alt!(expr_nosemi | syn!(Expr)) >>
1505 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1506 map!(input_end!(), |_| None)
1507 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001508 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001509 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001510 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001511 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001512 ) >>
1513 (Arm {
1514 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001515 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001516 attrs: attrs,
1517 pats: pats,
1518 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001519 body: Box::new(body.0),
1520 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001521 })
1522 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001523 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001524
Michael Layzell734adb42017-06-07 16:58:31 -04001525 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001526 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001527 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001528 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001529 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001530 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001531 ret_and_body: alt!(
1532 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001533 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001534 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001535 body: syn!(Block) >>
David Tolnay7f675742017-12-27 22:43:21 -05001536 (ReturnType::Type(Box::new(ty), arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001537 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001538 block: body,
1539 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001540 )
1541 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001542 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001543 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001544 (ExprClosure {
1545 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001546 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001547 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001548 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001549 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001550 body: Box::new(ret_and_body.1),
1551 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001552 ));
1553
Michael Layzell734adb42017-06-07 16:58:31 -04001554 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001555 named!(fn_arg -> FnArg, do_parse!(
1556 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001557 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001558 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001559 if let Some((colon, ty)) = ty {
1560 FnArg::Captured(ArgCaptured {
1561 pat: pat,
1562 colon_token: colon,
1563 ty: ty,
1564 })
1565 } else {
1566 FnArg::Inferred(pat)
1567 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001568 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001569 ));
1570
Michael Layzell734adb42017-06-07 16:58:31 -04001571 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001572 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001573 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001574 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1575 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001576 cond: expr_no_struct >>
1577 while_block: syn!(Block) >>
1578 (ExprWhile {
1579 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001580 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001581 cond: Box::new(cond),
1582 body: while_block,
1583 label: lbl.map(|p| p.0),
1584 })
1585 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001586 }
1587
Michael Layzell734adb42017-06-07 16:58:31 -04001588 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001589 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001590 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001591 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1592 while_: keyword!(while) >>
1593 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001594 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001595 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001596 value: expr_no_struct >>
1597 while_block: syn!(Block) >>
1598 (ExprWhileLet {
1599 eq_token: eq,
1600 let_token: let_,
1601 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001602 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001603 pat: Box::new(pat),
1604 expr: Box::new(value),
1605 body: while_block,
1606 label: lbl.map(|p| p.0),
1607 })
1608 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001609 }
1610
Michael Layzell734adb42017-06-07 16:58:31 -04001611 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001612 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001613 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001614 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001615 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001616 (ExprContinue {
1617 continue_token: cont,
1618 label: lbl,
1619 })
1620 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001621 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001622
Michael Layzell734adb42017-06-07 16:58:31 -04001623 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001624 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001625 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001626 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001627 // We can't allow blocks after a `break` expression when we wouldn't
1628 // allow structs, as this expression is ambiguous.
1629 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001630 (ExprBreak {
1631 label: lbl,
1632 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001633 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001634 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001635 ));
1636
Michael Layzell734adb42017-06-07 16:58:31 -04001637 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001638 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001639 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001640 // NOTE: return is greedy and eats blocks after it even when in a
1641 // position where structs are not allowed, such as in if statement
1642 // conditions. For example:
1643 //
David Tolnaybcf26022017-12-25 22:10:52 -05001644 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001645 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001646 (ExprRet {
1647 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001648 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001649 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001650 ));
1651
Michael Layzell734adb42017-06-07 16:58:31 -04001652 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001653 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001654 named!(parse -> Self, do_parse!(
1655 path: syn!(Path) >>
1656 data: braces!(do_parse!(
1657 fields: call!(Delimited::parse_terminated) >>
1658 base: option!(
1659 cond!(fields.is_empty() || fields.trailing_delim(),
1660 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001661 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001662 base: syn!(Expr) >>
1663 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001664 )
Michael Layzell92639a52017-06-01 00:07:44 -04001665 )
1666 ) >>
1667 (fields, base)
1668 )) >>
1669 ({
1670 let ((fields, base), brace) = data;
1671 let (dots, rest) = match base.and_then(|b| b) {
1672 Some((dots, base)) => (Some(dots), Some(base)),
1673 None => (None, None),
1674 };
1675 ExprStruct {
1676 brace_token: brace,
1677 path: path,
1678 fields: fields,
1679 dot2_token: dots,
1680 rest: rest.map(Box::new),
1681 }
1682 })
1683 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001684 }
1685
Michael Layzell734adb42017-06-07 16:58:31 -04001686 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001687 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001688 named!(parse -> Self, alt!(
1689 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001690 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001691 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001692 value: syn!(Expr) >>
1693 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001694 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001695 expr: value,
1696 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001697 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001698 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001699 })
Michael Layzell92639a52017-06-01 00:07:44 -04001700 )
1701 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001702 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001703 member: Member::Named(name),
Michael Layzell92639a52017-06-01 00:07:44 -04001704 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1705 is_shorthand: true,
1706 attrs: Vec::new(),
1707 colon_token: None,
1708 })
1709 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001710 }
David Tolnay055a7042016-10-02 19:23:54 -07001711
Michael Layzell734adb42017-06-07 16:58:31 -04001712 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001713 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001714 named!(parse -> Self, do_parse!(
1715 data: brackets!(do_parse!(
1716 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001717 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001718 times: syn!(Expr) >>
1719 (value, semi, times)
1720 )) >>
1721 (ExprRepeat {
1722 expr: Box::new((data.0).0),
1723 amt: Box::new((data.0).2),
1724 bracket_token: data.1,
1725 semi_token: (data.0).1,
1726 })
1727 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001728 }
David Tolnay055a7042016-10-02 19:23:54 -07001729
Michael Layzell734adb42017-06-07 16:58:31 -04001730 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001731 impl Synom for ExprUnsafe {
1732 named!(parse -> Self, do_parse!(
1733 unsafe_: keyword!(unsafe) >>
1734 b: syn!(Block) >>
1735 (ExprUnsafe {
1736 unsafe_token: unsafe_,
1737 block: b,
1738 })
1739 ));
1740 }
1741
1742 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001743 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001744 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001745 b: syn!(Block) >>
1746 (ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001747 block: b,
1748 })
1749 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001750 }
David Tolnay89e05672016-10-02 14:39:42 -07001751
Michael Layzell734adb42017-06-07 16:58:31 -04001752 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001753 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001754 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001755 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001756 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001757 ));
1758
Michael Layzell734adb42017-06-07 16:58:31 -04001759 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001760 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001761 named!(parse -> Self, alt!(
1762 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001763 punct!(..=) => { RangeLimits::Closed }
1764 |
1765 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001766 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001767 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001768 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001769 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001770 }
David Tolnay438c9052016-10-07 23:24:48 -07001771
Alex Crichton954046c2017-05-30 21:49:42 -07001772 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001773 named!(parse -> Self, do_parse!(
1774 pair: qpath >>
1775 (ExprPath {
1776 qself: pair.0,
1777 path: pair.1,
1778 })
1779 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001780 }
David Tolnay42602292016-10-01 22:25:45 -07001781
Michael Layzell734adb42017-06-07 16:58:31 -04001782 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001783 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001784
David Tolnay32954ef2017-12-26 22:43:16 -05001785 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001786
Michael Layzell734adb42017-06-07 16:58:31 -04001787 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001788 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001789 named!(parse -> Self, do_parse!(
1790 stmts: braces!(call!(Block::parse_within)) >>
1791 (Block {
1792 stmts: stmts.0,
1793 brace_token: stmts.1,
1794 })
1795 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001796 }
David Tolnay939766a2016-09-23 23:48:12 -07001797
Michael Layzell734adb42017-06-07 16:58:31 -04001798 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001799 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001800 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001801 many0!(punct!(;)) >>
1802 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001803 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001804 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001805 mut e: syn!(Expr) >>
1806 ({
1807 e.attrs = attrs;
1808 Stmt::Expr(Box::new(e))
1809 })
1810 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001811 (match last {
1812 None => standalone,
1813 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001814 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001815 standalone
1816 }
1817 })
1818 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001819 }
1820
Michael Layzell734adb42017-06-07 16:58:31 -04001821 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001822 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001823 named!(parse -> Self, alt!(
1824 stmt_mac
1825 |
1826 stmt_local
1827 |
1828 stmt_item
1829 |
Michael Layzell35418782017-06-07 09:20:25 -04001830 stmt_blockexpr
1831 |
Michael Layzell92639a52017-06-01 00:07:44 -04001832 stmt_expr
1833 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001834 }
David Tolnay939766a2016-09-23 23:48:12 -07001835
Michael Layzell734adb42017-06-07 16:58:31 -04001836 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001837 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001838 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001839 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001840 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001841 // Only parse braces here; paren and bracket will get parsed as
1842 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001843 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001844 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05001845 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
1846 attrs: attrs,
1847 ident: None,
1848 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001849 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001850 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001851 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001852 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001853 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001854 },
David Tolnayeea28d62016-10-25 20:44:08 -07001855 },
David Tolnay57b52bc2017-12-28 18:06:38 -05001856 semi_token: semi,
1857 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07001858 ));
1859
Michael Layzell734adb42017-06-07 16:58:31 -04001860 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001861 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001862 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001863 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001864 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001865 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001866 init: option!(tuple!(punct!(=), syn!(Expr))) >>
1867 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07001868 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001869 let_token: let_,
1870 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001871 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
1872 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001873 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001874 ty: ty.map(|p| Box::new(p.1)),
1875 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001876 attrs: attrs,
1877 })))
1878 ));
1879
Michael Layzell734adb42017-06-07 16:58:31 -04001880 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001881 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001882
Michael Layzell734adb42017-06-07 16:58:31 -04001883 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001884 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001885 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04001886 mut e: expr_nosemi >>
1887 // If the next token is a `.` or a `?` it is special-cased to parse as
1888 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08001889 not!(punct!(.)) >>
1890 not!(punct!(?)) >>
1891 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04001892 ({
1893 e.attrs = attrs;
1894 if let Some(semi) = semi {
1895 Stmt::Semi(Box::new(e), semi)
1896 } else {
1897 Stmt::Expr(Box::new(e))
1898 }
1899 })
1900 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001901
Michael Layzell734adb42017-06-07 16:58:31 -04001902 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001903 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001904 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001905 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001906 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07001907 ({
1908 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001909 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001910 })
David Tolnay939766a2016-09-23 23:48:12 -07001911 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001912
Michael Layzell734adb42017-06-07 16:58:31 -04001913 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001914 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001915 named!(parse -> Self, alt!(
1916 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1917 |
1918 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1919 |
1920 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1921 |
1922 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1923 |
1924 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1925 |
David Tolnaydecf28d2017-11-11 11:56:45 -08001926 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04001927 |
1928 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1929 |
1930 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1931 |
1932 syn!(PatPath) => { Pat::Path }
1933 |
1934 syn!(PatTuple) => { Pat::Tuple }
1935 |
1936 syn!(PatRef) => { Pat::Ref }
1937 |
1938 syn!(PatSlice) => { Pat::Slice }
1939 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001940 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001941
Michael Layzell734adb42017-06-07 16:58:31 -04001942 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001943 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001944 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001945 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04001946 |u| PatWild { underscore_token: u }
1947 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001948 }
David Tolnay84aa0752016-10-02 23:01:13 -07001949
Michael Layzell734adb42017-06-07 16:58:31 -04001950 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001951 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001952 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001953 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001954 pat: syn!(Pat) >>
1955 (PatBox {
1956 pat: Box::new(pat),
1957 box_token: boxed,
1958 })
1959 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001960 }
1961
Michael Layzell734adb42017-06-07 16:58:31 -04001962 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001963 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001964 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001965 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001966 mutability: syn!(Mutability) >>
1967 name: alt!(
1968 syn!(Ident)
1969 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001970 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04001971 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001972 not!(punct!(<)) >>
1973 not!(punct!(::)) >>
1974 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001975 (PatIdent {
1976 mode: match mode {
1977 Some(mode) => BindingMode::ByRef(mode, mutability),
1978 None => BindingMode::ByValue(mutability),
1979 },
1980 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001981 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001982 subpat: subpat.map(|p| Box::new(p.1)),
1983 })
1984 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001985 }
1986
Michael Layzell734adb42017-06-07 16:58:31 -04001987 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001988 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001989 named!(parse -> Self, do_parse!(
1990 path: syn!(Path) >>
1991 tuple: syn!(PatTuple) >>
1992 (PatTupleStruct {
1993 path: path,
1994 pat: tuple,
1995 })
1996 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001997 }
1998
Michael Layzell734adb42017-06-07 16:58:31 -04001999 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002000 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002001 named!(parse -> Self, do_parse!(
2002 path: syn!(Path) >>
2003 data: braces!(do_parse!(
2004 fields: call!(Delimited::parse_terminated) >>
2005 base: option!(
2006 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002007 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002008 ) >>
2009 (fields, base)
2010 )) >>
2011 (PatStruct {
2012 path: path,
2013 fields: (data.0).0,
2014 brace_token: data.1,
2015 dot2_token: (data.0).1.and_then(|m| m),
2016 })
2017 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002018 }
2019
Michael Layzell734adb42017-06-07 16:58:31 -04002020 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002021 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002022 named!(parse -> Self, alt!(
2023 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002024 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002025 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002026 pat: syn!(Pat) >>
2027 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002028 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002029 pat: Box::new(pat),
2030 is_shorthand: false,
2031 attrs: Vec::new(),
2032 colon_token: Some(colon),
2033 })
2034 )
2035 |
2036 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002037 boxed: option!(keyword!(box)) >>
2038 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002039 mutability: syn!(Mutability) >>
2040 ident: syn!(Ident) >>
2041 ({
2042 let mut pat: Pat = PatIdent {
2043 mode: if let Some(mode) = mode {
2044 BindingMode::ByRef(mode, mutability)
2045 } else {
2046 BindingMode::ByValue(mutability)
2047 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002048 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002049 subpat: None,
2050 at_token: None,
2051 }.into();
2052 if let Some(boxed) = boxed {
2053 pat = PatBox {
2054 pat: Box::new(pat),
2055 box_token: boxed,
2056 }.into();
2057 }
2058 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002059 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002060 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002061 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002062 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002063 colon_token: None,
2064 }
2065 })
2066 )
2067 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002068 }
2069
Michael Layzell734adb42017-06-07 16:58:31 -04002070 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002071 impl Synom for Member {
2072 named!(parse -> Self, alt!(
2073 syn!(Ident) => { Member::Named }
2074 |
2075 syn!(Index) => { Member::Unnamed }
2076 ));
2077 }
2078
2079 #[cfg(feature = "full")]
2080 impl Synom for Index {
2081 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002082 lit: syn!(Lit) >>
2083 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002084 if let Ok(i) = lit.value.to_string().parse() {
2085 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002086 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002087 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002088 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002089 })
David Tolnay85b69a42017-12-27 20:43:10 -05002090 ));
2091 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002092
Michael Layzell734adb42017-06-07 16:58:31 -04002093 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002094 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002095 named!(parse -> Self, map!(
2096 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002097 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002098 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002099 }
David Tolnay9636c052016-10-02 17:11:17 -07002100
Michael Layzell734adb42017-06-07 16:58:31 -04002101 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002102 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002103 named!(parse -> Self, do_parse!(
2104 data: parens!(do_parse!(
2105 elems: call!(Delimited::parse_terminated) >>
2106 dotdot: map!(cond!(
2107 elems.is_empty() || elems.trailing_delim(),
2108 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002109 dots: punct!(..) >>
2110 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002111 (dots, trailing)
2112 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002113 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002114 rest: cond!(match dotdot {
2115 Some((_, Some(_))) => true,
2116 _ => false,
2117 },
2118 call!(Delimited::parse_terminated)) >>
2119 (elems, dotdot, rest)
2120 )) >>
2121 ({
2122 let ((mut elems, dotdot, rest), parens) = data;
2123 let (dotdot, trailing) = match dotdot {
2124 Some((a, b)) => (Some(a), Some(b)),
2125 None => (None, None),
2126 };
2127 PatTuple {
2128 paren_token: parens,
2129 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2130 dot2_token: dotdot,
2131 comma_token: trailing.and_then(|b| b),
2132 pats: {
2133 if let Some(rest) = rest {
2134 for elem in rest {
2135 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002136 }
Michael Layzell92639a52017-06-01 00:07:44 -04002137 }
2138 elems
2139 },
2140 }
2141 })
2142 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002143 }
David Tolnayfbb73232016-10-03 01:00:06 -07002144
Michael Layzell734adb42017-06-07 16:58:31 -04002145 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002146 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002147 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002148 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002149 mutability: syn!(Mutability) >>
2150 pat: syn!(Pat) >>
2151 (PatRef {
2152 pat: Box::new(pat),
2153 mutbl: mutability,
2154 and_token: and,
2155 })
2156 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002157 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002158
Michael Layzell734adb42017-06-07 16:58:31 -04002159 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002160 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002161 named!(parse -> Self, do_parse!(
2162 lit: pat_lit_expr >>
2163 (if let ExprKind::Path(_) = lit.node {
2164 return parse_error(); // these need to be parsed by pat_path
2165 } else {
2166 PatLit {
2167 expr: Box::new(lit),
2168 }
2169 })
2170 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002171 }
David Tolnaye1310902016-10-29 23:40:00 -07002172
Michael Layzell734adb42017-06-07 16:58:31 -04002173 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002174 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002175 named!(parse -> Self, do_parse!(
2176 lo: pat_lit_expr >>
2177 limits: syn!(RangeLimits) >>
2178 hi: pat_lit_expr >>
2179 (PatRange {
2180 lo: Box::new(lo),
2181 hi: Box::new(hi),
2182 limits: limits,
2183 })
2184 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002185 }
David Tolnaye1310902016-10-29 23:40:00 -07002186
Michael Layzell734adb42017-06-07 16:58:31 -04002187 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002188 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002189 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002190 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002191 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002192 |
Alex Crichton954046c2017-05-30 21:49:42 -07002193 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002194 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002195 (if let Some(neg) = neg {
Alex Crichton62a0a592017-05-22 13:58:53 -07002196 ExprKind::Unary(ExprUnary {
David Tolnayc29b9892017-12-27 22:58:14 -05002197 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002198 expr: Box::new(v.into())
2199 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002200 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002201 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002202 })
2203 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002204
Michael Layzell734adb42017-06-07 16:58:31 -04002205 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002206 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002207 named!(parse -> Self, map!(
2208 brackets!(do_parse!(
2209 before: call!(Delimited::parse_terminated) >>
2210 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002211 dots: punct!(..) >>
2212 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002213 (dots, trailing)
2214 )) >>
2215 after: cond!(
2216 match middle {
2217 Some((_, ref trailing)) => trailing.is_some(),
2218 _ => false,
2219 },
2220 call!(Delimited::parse_terminated)
2221 ) >>
2222 (before, middle, after)
2223 )),
2224 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002225 let mut before: Delimited<Pat, Token![,]> = before;
2226 let after: Option<Delimited<Pat, Token![,]>> = after;
2227 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002228 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002229 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002230 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002231 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002232 }),
2233 bracket_token: brackets,
2234 middle: middle.and_then(|_| {
2235 if !before.is_empty() && !before.trailing_delim() {
2236 Some(Box::new(before.pop().unwrap().into_item()))
2237 } else {
2238 None
2239 }
2240 }),
2241 front: before,
2242 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002243 }
Alex Crichton954046c2017-05-30 21:49:42 -07002244 }
Michael Layzell92639a52017-06-01 00:07:44 -04002245 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002246 }
David Tolnay435a9a82016-10-29 13:47:20 -07002247
Michael Layzell734adb42017-06-07 16:58:31 -04002248 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002249 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002250 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002251 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002252 |
2253 epsilon!() => { |_| CaptureBy::Ref }
2254 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002255 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002256}
2257
David Tolnayf4bbbd92016-09-23 14:41:55 -07002258#[cfg(feature = "printing")]
2259mod printing {
2260 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002261 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002262 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002263 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002264 #[cfg(feature = "full")]
2265 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002266
David Tolnaybcf26022017-12-25 22:10:52 -05002267 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2268 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002269 #[cfg(feature = "full")]
2270 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2271 if let ExprKind::Struct(_) = e.node {
David Tolnay32954ef2017-12-26 22:43:16 -05002272 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002273 e.to_tokens(tokens);
2274 });
2275 } else {
2276 e.to_tokens(tokens);
2277 }
2278 }
2279
David Tolnayf4bbbd92016-09-23 14:41:55 -07002280 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002281 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002282 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002283 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002284 self.node.to_tokens(tokens)
2285 }
Michael Layzell734adb42017-06-07 16:58:31 -04002286
2287 #[cfg(not(feature = "full"))]
2288 fn to_tokens(&self, tokens: &mut Tokens) {
2289 self.node.to_tokens(tokens)
2290 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002291 }
2292
Michael Layzell734adb42017-06-07 16:58:31 -04002293 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002294 impl ToTokens for ExprBox {
2295 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002296 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002297 self.expr.to_tokens(tokens);
2298 }
2299 }
2300
Michael Layzell734adb42017-06-07 16:58:31 -04002301 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002302 impl ToTokens for ExprInPlace {
2303 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002304 match self.kind {
2305 InPlaceKind::Arrow(ref arrow) => {
2306 self.place.to_tokens(tokens);
2307 arrow.to_tokens(tokens);
2308 self.value.to_tokens(tokens);
2309 }
2310 InPlaceKind::In(ref _in) => {
2311 _in.to_tokens(tokens);
2312 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002313 // NOTE: The second operand must be in a block, add one if
2314 // it is not present.
2315 if let ExprKind::Block(_) = self.value.node {
2316 self.value.to_tokens(tokens);
2317 } else {
David Tolnay32954ef2017-12-26 22:43:16 -05002318 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002319 self.value.to_tokens(tokens);
2320 })
2321 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002322 }
2323 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002324 }
2325 }
2326
Michael Layzell734adb42017-06-07 16:58:31 -04002327 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002328 impl ToTokens for ExprArray {
2329 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002330 self.bracket_token.surround(tokens, |tokens| {
2331 self.exprs.to_tokens(tokens);
2332 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002333 }
2334 }
2335
2336 impl ToTokens for ExprCall {
2337 fn to_tokens(&self, tokens: &mut Tokens) {
2338 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002339 self.paren_token.surround(tokens, |tokens| {
2340 self.args.to_tokens(tokens);
2341 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002342 }
2343 }
2344
Michael Layzell734adb42017-06-07 16:58:31 -04002345 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002346 impl ToTokens for ExprMethodCall {
2347 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002348 self.expr.to_tokens(tokens);
2349 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002350 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002351 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002352 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2353 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002354 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002355 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002356 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002357 self.paren_token.surround(tokens, |tokens| {
2358 self.args.to_tokens(tokens);
2359 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002360 }
2361 }
2362
Michael Layzell734adb42017-06-07 16:58:31 -04002363 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002364 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002365 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002366 self.paren_token.surround(tokens, |tokens| {
2367 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002368 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002369 // distinguish ExprTuple from ExprParen.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002370 if self.args.len() == 1 && !self.args.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002371 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002372 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002373 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002374 }
2375 }
2376
2377 impl ToTokens for ExprBinary {
2378 fn to_tokens(&self, tokens: &mut Tokens) {
2379 self.left.to_tokens(tokens);
2380 self.op.to_tokens(tokens);
2381 self.right.to_tokens(tokens);
2382 }
2383 }
2384
2385 impl ToTokens for ExprUnary {
2386 fn to_tokens(&self, tokens: &mut Tokens) {
2387 self.op.to_tokens(tokens);
2388 self.expr.to_tokens(tokens);
2389 }
2390 }
2391
2392 impl ToTokens for ExprCast {
2393 fn to_tokens(&self, tokens: &mut Tokens) {
2394 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002395 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002396 self.ty.to_tokens(tokens);
2397 }
2398 }
2399
2400 impl ToTokens for ExprType {
2401 fn to_tokens(&self, tokens: &mut Tokens) {
2402 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002403 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002404 self.ty.to_tokens(tokens);
2405 }
2406 }
2407
Michael Layzell734adb42017-06-07 16:58:31 -04002408 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002409 fn maybe_wrap_else(
2410 tokens: &mut Tokens,
2411 else_token: &Option<Token![else]>,
2412 if_false: &Option<Box<Expr>>,
2413 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002414 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002415 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002416
2417 // If we are not one of the valid expressions to exist in an else
2418 // clause, wrap ourselves in a block.
2419 match if_false.node {
David Tolnay51382052017-12-27 13:46:21 -05002420 ExprKind::If(_) | ExprKind::IfLet(_) | ExprKind::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002421 if_false.to_tokens(tokens);
2422 }
2423 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002424 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002425 if_false.to_tokens(tokens);
2426 });
2427 }
2428 }
2429 }
2430 }
2431
2432 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002433 impl ToTokens for ExprIf {
2434 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002435 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002436 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002437 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002438 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002439 }
2440 }
2441
Michael Layzell734adb42017-06-07 16:58:31 -04002442 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002443 impl ToTokens for ExprIfLet {
2444 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002445 self.if_token.to_tokens(tokens);
2446 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002447 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002448 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002449 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002450 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002451 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002452 }
2453 }
2454
Michael Layzell734adb42017-06-07 16:58:31 -04002455 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002456 impl ToTokens for ExprWhile {
2457 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002458 if self.label.is_some() {
2459 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002460 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002461 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002462 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002463 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002464 self.body.to_tokens(tokens);
2465 }
2466 }
2467
Michael Layzell734adb42017-06-07 16:58:31 -04002468 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 impl ToTokens for ExprWhileLet {
2470 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002471 if self.label.is_some() {
2472 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002473 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002474 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002475 self.while_token.to_tokens(tokens);
2476 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002477 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002478 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002479 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002480 self.body.to_tokens(tokens);
2481 }
2482 }
2483
Michael Layzell734adb42017-06-07 16:58:31 -04002484 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002485 impl ToTokens for ExprForLoop {
2486 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002487 if self.label.is_some() {
2488 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002489 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002490 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002491 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002492 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002493 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002494 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002495 self.body.to_tokens(tokens);
2496 }
2497 }
2498
Michael Layzell734adb42017-06-07 16:58:31 -04002499 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002500 impl ToTokens for ExprLoop {
2501 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002502 if self.label.is_some() {
2503 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002504 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002505 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002506 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002507 self.body.to_tokens(tokens);
2508 }
2509 }
2510
Michael Layzell734adb42017-06-07 16:58:31 -04002511 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002512 impl ToTokens for ExprMatch {
2513 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002514 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002515 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002516 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002517 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002518 arm.to_tokens(tokens);
2519 // Ensure that we have a comma after a non-block arm, except
2520 // for the last one.
2521 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002522 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002523 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002524 }
2525 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002526 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002527 }
2528 }
2529
Michael Layzell734adb42017-06-07 16:58:31 -04002530 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002531 impl ToTokens for ExprCatch {
2532 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002533 self.do_token.to_tokens(tokens);
2534 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002535 self.block.to_tokens(tokens);
2536 }
2537 }
2538
Michael Layzell734adb42017-06-07 16:58:31 -04002539 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002540 impl ToTokens for ExprYield {
2541 fn to_tokens(&self, tokens: &mut Tokens) {
2542 self.yield_token.to_tokens(tokens);
2543 self.expr.to_tokens(tokens);
2544 }
2545 }
2546
2547 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002548 impl ToTokens for ExprClosure {
2549 fn to_tokens(&self, tokens: &mut Tokens) {
2550 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002551 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002552 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002553 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002554 FnArg::Captured(ArgCaptured {
2555 ref pat,
2556 ty: Type::Infer(_),
2557 ..
2558 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002559 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002560 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002561 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002562 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002563 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002564 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002565 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002566 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002567 self.body.to_tokens(tokens);
2568 }
2569 }
2570
Michael Layzell734adb42017-06-07 16:58:31 -04002571 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002572 impl ToTokens for ExprUnsafe {
2573 fn to_tokens(&self, tokens: &mut Tokens) {
2574 self.unsafe_token.to_tokens(tokens);
2575 self.block.to_tokens(tokens);
2576 }
2577 }
2578
2579 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002580 impl ToTokens for ExprBlock {
2581 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002582 self.block.to_tokens(tokens);
2583 }
2584 }
2585
Michael Layzell734adb42017-06-07 16:58:31 -04002586 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002587 impl ToTokens for ExprAssign {
2588 fn to_tokens(&self, tokens: &mut Tokens) {
2589 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002590 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002591 self.right.to_tokens(tokens);
2592 }
2593 }
2594
Michael Layzell734adb42017-06-07 16:58:31 -04002595 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002596 impl ToTokens for ExprAssignOp {
2597 fn to_tokens(&self, tokens: &mut Tokens) {
2598 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002599 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002600 self.right.to_tokens(tokens);
2601 }
2602 }
2603
Michael Layzell734adb42017-06-07 16:58:31 -04002604 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002605 impl ToTokens for ExprField {
2606 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002607 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002608 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002609 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002610 }
2611 }
2612
Michael Layzell734adb42017-06-07 16:58:31 -04002613 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002614 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002616 match *self {
2617 Member::Named(ident) => ident.to_tokens(tokens),
2618 Member::Unnamed(ref index) => index.to_tokens(tokens),
2619 }
2620 }
2621 }
2622
2623 #[cfg(feature = "full")]
2624 impl ToTokens for Index {
2625 fn to_tokens(&self, tokens: &mut Tokens) {
2626 tokens.append(TokenTree {
2627 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002628 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002629 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002630 }
2631 }
2632
2633 impl ToTokens for ExprIndex {
2634 fn to_tokens(&self, tokens: &mut Tokens) {
2635 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002636 self.bracket_token.surround(tokens, |tokens| {
2637 self.index.to_tokens(tokens);
2638 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002639 }
2640 }
2641
Michael Layzell734adb42017-06-07 16:58:31 -04002642 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002643 impl ToTokens for ExprRange {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
2645 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002646 match self.limits {
2647 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2648 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2649 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002650 self.to.to_tokens(tokens);
2651 }
2652 }
2653
2654 impl ToTokens for ExprPath {
2655 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002656 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002657 }
2658 }
2659
Michael Layzell734adb42017-06-07 16:58:31 -04002660 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002661 impl ToTokens for ExprAddrOf {
2662 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002663 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002664 self.mutbl.to_tokens(tokens);
2665 self.expr.to_tokens(tokens);
2666 }
2667 }
2668
Michael Layzell734adb42017-06-07 16:58:31 -04002669 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002670 impl ToTokens for ExprBreak {
2671 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002672 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002673 self.label.to_tokens(tokens);
2674 self.expr.to_tokens(tokens);
2675 }
2676 }
2677
Michael Layzell734adb42017-06-07 16:58:31 -04002678 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002679 impl ToTokens for ExprContinue {
2680 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002681 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002682 self.label.to_tokens(tokens);
2683 }
2684 }
2685
Michael Layzell734adb42017-06-07 16:58:31 -04002686 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002687 impl ToTokens for ExprRet {
2688 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002689 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002690 self.expr.to_tokens(tokens);
2691 }
2692 }
2693
Michael Layzell734adb42017-06-07 16:58:31 -04002694 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002695 impl ToTokens for ExprStruct {
2696 fn to_tokens(&self, tokens: &mut Tokens) {
2697 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002698 self.brace_token.surround(tokens, |tokens| {
2699 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002700 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002701 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002702 self.rest.to_tokens(tokens);
2703 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002704 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002705 }
2706 }
2707
Michael Layzell734adb42017-06-07 16:58:31 -04002708 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002709 impl ToTokens for ExprRepeat {
2710 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002711 self.bracket_token.surround(tokens, |tokens| {
2712 self.expr.to_tokens(tokens);
2713 self.semi_token.to_tokens(tokens);
2714 self.amt.to_tokens(tokens);
2715 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002716 }
2717 }
2718
Michael Layzell93c36282017-06-04 20:43:14 -04002719 impl ToTokens for ExprGroup {
2720 fn to_tokens(&self, tokens: &mut Tokens) {
2721 self.group_token.surround(tokens, |tokens| {
2722 self.expr.to_tokens(tokens);
2723 });
2724 }
2725 }
2726
Alex Crichton62a0a592017-05-22 13:58:53 -07002727 impl ToTokens for ExprParen {
2728 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002729 self.paren_token.surround(tokens, |tokens| {
2730 self.expr.to_tokens(tokens);
2731 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002732 }
2733 }
2734
Michael Layzell734adb42017-06-07 16:58:31 -04002735 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002736 impl ToTokens for ExprTry {
2737 fn to_tokens(&self, tokens: &mut Tokens) {
2738 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002739 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002740 }
2741 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002742
Michael Layzell734adb42017-06-07 16:58:31 -04002743 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002744 impl ToTokens for FieldValue {
2745 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002746 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002747 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2748 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002749 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002750 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002751 self.expr.to_tokens(tokens);
2752 }
David Tolnay055a7042016-10-02 19:23:54 -07002753 }
2754 }
2755
Michael Layzell734adb42017-06-07 16:58:31 -04002756 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002757 impl ToTokens for Arm {
2758 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002759 tokens.append_all(&self.attrs);
2760 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002761 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002762 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002763 self.guard.to_tokens(tokens);
2764 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002765 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002766 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002767 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002768 }
2769 }
2770
Michael Layzell734adb42017-06-07 16:58:31 -04002771 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002772 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002773 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002774 self.underscore_token.to_tokens(tokens);
2775 }
2776 }
2777
Michael Layzell734adb42017-06-07 16:58:31 -04002778 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002779 impl ToTokens for PatIdent {
2780 fn to_tokens(&self, tokens: &mut Tokens) {
2781 self.mode.to_tokens(tokens);
2782 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002783 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002784 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002785 self.subpat.to_tokens(tokens);
2786 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002787 }
2788 }
2789
Michael Layzell734adb42017-06-07 16:58:31 -04002790 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002791 impl ToTokens for PatStruct {
2792 fn to_tokens(&self, tokens: &mut Tokens) {
2793 self.path.to_tokens(tokens);
2794 self.brace_token.surround(tokens, |tokens| {
2795 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002796 // NOTE: We need a comma before the dot2 token if it is present.
2797 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002798 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002799 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002800 self.dot2_token.to_tokens(tokens);
2801 });
2802 }
2803 }
2804
Michael Layzell734adb42017-06-07 16:58:31 -04002805 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002806 impl ToTokens for PatTupleStruct {
2807 fn to_tokens(&self, tokens: &mut Tokens) {
2808 self.path.to_tokens(tokens);
2809 self.pat.to_tokens(tokens);
2810 }
2811 }
2812
Michael Layzell734adb42017-06-07 16:58:31 -04002813 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002814 impl ToTokens for PatPath {
2815 fn to_tokens(&self, tokens: &mut Tokens) {
2816 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2817 }
2818 }
2819
Michael Layzell734adb42017-06-07 16:58:31 -04002820 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002821 impl ToTokens for PatTuple {
2822 fn to_tokens(&self, tokens: &mut Tokens) {
2823 self.paren_token.surround(tokens, |tokens| {
2824 for (i, token) in self.pats.iter().enumerate() {
2825 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002826 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2827 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002828 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002829 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002830 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002831
2832 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002833 // Ensure there is a comma before the .. token.
2834 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002835 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002836 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002837 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002838 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002839 });
2840 }
2841 }
2842
Michael Layzell734adb42017-06-07 16:58:31 -04002843 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002844 impl ToTokens for PatBox {
2845 fn to_tokens(&self, tokens: &mut Tokens) {
2846 self.box_token.to_tokens(tokens);
2847 self.pat.to_tokens(tokens);
2848 }
2849 }
2850
Michael Layzell734adb42017-06-07 16:58:31 -04002851 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002852 impl ToTokens for PatRef {
2853 fn to_tokens(&self, tokens: &mut Tokens) {
2854 self.and_token.to_tokens(tokens);
2855 self.mutbl.to_tokens(tokens);
2856 self.pat.to_tokens(tokens);
2857 }
2858 }
2859
Michael Layzell734adb42017-06-07 16:58:31 -04002860 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002861 impl ToTokens for PatLit {
2862 fn to_tokens(&self, tokens: &mut Tokens) {
2863 self.expr.to_tokens(tokens);
2864 }
2865 }
2866
Michael Layzell734adb42017-06-07 16:58:31 -04002867 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002868 impl ToTokens for PatRange {
2869 fn to_tokens(&self, tokens: &mut Tokens) {
2870 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002871 match self.limits {
2872 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2873 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
2874 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002875 self.hi.to_tokens(tokens);
2876 }
2877 }
2878
Michael Layzell734adb42017-06-07 16:58:31 -04002879 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002880 impl ToTokens for PatSlice {
2881 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002882 // XXX: This is a mess, and it will be so easy to screw it up. How
2883 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002884 self.bracket_token.surround(tokens, |tokens| {
2885 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002886
2887 // If we need a comma before the middle or standalone .. token,
2888 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05002889 if !self.front.empty_or_trailing()
2890 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04002891 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002892 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002893 }
2894
2895 // If we have an identifier, we always need a .. token.
2896 if self.middle.is_some() {
2897 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002898 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002899 } else if self.dot2_token.is_some() {
2900 self.dot2_token.to_tokens(tokens);
2901 }
2902
2903 // Make sure we have a comma before the back half.
2904 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002905 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002906 self.back.to_tokens(tokens);
2907 } else {
2908 self.comma_token.to_tokens(tokens);
2909 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002910 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002911 }
2912 }
2913
Michael Layzell734adb42017-06-07 16:58:31 -04002914 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002915 impl ToTokens for FieldPat {
2916 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002917 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002918 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05002919 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002920 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002921 }
2922 self.pat.to_tokens(tokens);
2923 }
2924 }
2925
Michael Layzell734adb42017-06-07 16:58:31 -04002926 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002927 impl ToTokens for BindingMode {
2928 fn to_tokens(&self, tokens: &mut Tokens) {
2929 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002930 BindingMode::ByRef(ref t, ref m) => {
2931 t.to_tokens(tokens);
2932 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002933 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002934 BindingMode::ByValue(ref m) => {
2935 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002936 }
2937 }
2938 }
2939 }
David Tolnay42602292016-10-01 22:25:45 -07002940
Michael Layzell734adb42017-06-07 16:58:31 -04002941 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002942 impl ToTokens for CaptureBy {
2943 fn to_tokens(&self, tokens: &mut Tokens) {
2944 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002945 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002946 CaptureBy::Ref => {
2947 // nothing
2948 }
David Tolnay89e05672016-10-02 14:39:42 -07002949 }
2950 }
2951 }
2952
Michael Layzell734adb42017-06-07 16:58:31 -04002953 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002954 impl ToTokens for Block {
2955 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002956 self.brace_token.surround(tokens, |tokens| {
2957 tokens.append_all(&self.stmts);
2958 });
David Tolnay42602292016-10-01 22:25:45 -07002959 }
2960 }
2961
Michael Layzell734adb42017-06-07 16:58:31 -04002962 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002963 impl ToTokens for Stmt {
2964 fn to_tokens(&self, tokens: &mut Tokens) {
2965 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002966 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002967 Stmt::Item(ref item) => item.to_tokens(tokens),
2968 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002969 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002970 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002971 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002972 }
David Tolnay42602292016-10-01 22:25:45 -07002973 }
2974 }
2975 }
David Tolnay191e0582016-10-02 18:31:09 -07002976
Michael Layzell734adb42017-06-07 16:58:31 -04002977 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002978 impl ToTokens for Local {
2979 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002980 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002981 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002982 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002983 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002984 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002985 self.ty.to_tokens(tokens);
2986 }
2987 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002988 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002989 self.init.to_tokens(tokens);
2990 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002991 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002992 }
2993 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002994}