blob: fb71ef7a902d21da23b9fc0d46bb6c5b0fc82eb3 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
Alex Crichton954046c2017-05-30 21:49:42 -070029 pub box_token: tokens::Box_,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub exprs: Delimited<Expr, tokens::Comma>,
42 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 pub args: Delimited<Expr, tokens::Comma>,
49 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
55 /// The vector of `Ty`s are the ascripted type parameters for the method
56 /// (within the angle brackets).
57 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
59 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070063 pub typarams: Delimited<Ty, tokens::Comma>,
64 pub args: Delimited<Expr, tokens::Comma>,
65 pub paren_token: tokens::Paren,
66 pub dot_token: tokens::Dot,
67 pub lt_token: Option<tokens::Lt>,
68 pub colon2_token: Option<tokens::Colon2>,
69 pub gt_token: Option<tokens::Gt>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
Michael Layzell734adb42017-06-07 16:58:31 -040073 pub Tup(ExprTup #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070074 pub args: Delimited<Expr, tokens::Comma>,
75 pub paren_token: tokens::Paren,
76 pub lone_comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070098 pub as_token: tokens::As,
Alex Crichton62a0a592017-05-22 13:58:53 -070099 pub ty: Box<Ty>,
100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// A type ascription, e.g. `foo: f64`.
103 pub Type(ExprType {
104 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 pub ty: Box<Ty>,
107 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500108
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 /// An `if` block, with an optional else block
110 ///
111 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 pub if_token: tokens::If,
117 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700130 pub if_token: tokens::If,
131 pub let_token: tokens::Let,
132 pub eq_token: tokens::Eq,
133 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 pub colon_token: Option<tokens::Colon>,
144 pub while_token: tokens::While,
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700157 pub colon_token: Option<tokens::Colon>,
158 pub while_token: tokens::While,
159 pub let_token: tokens::Let,
160 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700173 pub for_token: tokens::For,
174 pub colon_token: Option<tokens::Colon>,
175 pub in_token: tokens::In,
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700184 pub loop_token: tokens::Loop,
185 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 pub match_token: tokens::Match,
191 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201 pub or1_token: tokens::Or,
202 pub or2_token: tokens::Or,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// A block (`{ ... }` or `unsafe { ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400206 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 pub unsafety: Unsafety,
208 pub block: Block,
209 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700210
Alex Crichton62a0a592017-05-22 13:58:53 -0700211 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700215 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500217
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 /// An assignment with an operator
219 ///
220 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub op: BinOp,
223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// Access of a named struct field (`obj.foo`)
Michael Layzell734adb42017-06-07 16:58:31 -0400228 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 pub expr: Box<Expr>,
230 pub field: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500233
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 /// Access of an unnamed field of a struct or tuple-struct
235 ///
236 /// For example, `foo.0`.
Michael Layzell734adb42017-06-07 16:58:31 -0400237 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700239 pub field: Lit,
240 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500242
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 /// An indexing operation (`foo[2]`)
244 pub Index(ExprIndex {
245 pub expr: Box<Expr>,
246 pub index: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500249
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400251 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 pub from: Option<Box<Expr>>,
253 pub to: Option<Box<Expr>>,
254 pub limits: RangeLimits,
255 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700256
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 /// Variable reference, possibly containing `::` and/or type
258 /// parameters, e.g. foo::bar::<baz>.
259 ///
260 /// Optionally "qualified",
261 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
262 pub Path(ExprPath {
263 pub qself: Option<QSelf>,
264 pub path: Path,
265 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700266
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400268 pub AddrOf(ExprAddrOf #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 pub and_token: tokens::And,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub mutbl: Mutability,
271 pub expr: Box<Expr>,
272 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500273
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400275 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700276 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700278 pub break_token: tokens::Break,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500280
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400282 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700283 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 pub continue_token: tokens::Continue,
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500286
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400288 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 pub return_token: tokens::Return,
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700292
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 /// A macro invocation; pre-expansion
294 pub Mac(Mac),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700295
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 /// A struct literal expression.
297 ///
298 /// For example, `Foo {x: 1, y: 2}`, or
299 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400300 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 pub path: Path,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 pub fields: Delimited<FieldValue, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub rest: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700304 pub dot2_token: Option<tokens::Dot2>,
305 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700307
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 /// An array literal constructed from one repeated element.
309 ///
310 /// For example, `[1; 5]`. The first expression is the element
311 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400312 pub Repeat(ExprRepeat #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 pub bracket_token: tokens::Bracket,
314 pub semi_token: tokens::Semi,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub expr: Box<Expr>,
316 pub amt: Box<Expr>,
317 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700318
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 /// No-op: used solely so we can pretty-print faithfully
320 pub Paren(ExprParen {
321 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700322 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700324
Michael Layzell93c36282017-06-04 20:43:14 -0400325 /// No-op: used solely so we can pretty-print faithfully
326 ///
327 /// A `group` represents a `None`-delimited span in the input
328 /// `TokenStream` which affects the precidence of the resulting
329 /// expression. They are used for macro hygiene.
330 pub Group(ExprGroup {
331 pub expr: Box<Expr>,
332 pub group_token: tokens::Group,
333 }),
334
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400336 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700338 pub question_token: tokens::Question,
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700340
Alex Crichton62a0a592017-05-22 13:58:53 -0700341 /// A catch expression.
342 ///
343 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400344 pub Catch(ExprCatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700345 pub do_token: tokens::Do,
346 pub catch_token: tokens::Catch,
Alex Crichton62a0a592017-05-22 13:58:53 -0700347 pub block: Block,
348 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700349
350 /// A yield expression.
351 ///
352 /// E.g. `yield expr`
353 pub Yield(ExprYield #full {
354 pub yield_token: tokens::Yield,
355 pub expr: Option<Box<Expr>>,
356 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700358}
359
Michael Layzell734adb42017-06-07 16:58:31 -0400360#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700361ast_struct! {
362 /// A field-value pair in a struct literal.
363 pub struct FieldValue {
364 /// Name of the field.
365 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500366
Alex Crichton62a0a592017-05-22 13:58:53 -0700367 /// Value of the field.
368 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500369
Alex Crichton62a0a592017-05-22 13:58:53 -0700370 /// Whether this is a shorthand field, e.g. `Struct { x }`
371 /// instead of `Struct { x: x }`.
372 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500373
Alex Crichton62a0a592017-05-22 13:58:53 -0700374 /// Attributes tagged on the field.
375 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700376
377 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700378 }
David Tolnay055a7042016-10-02 19:23:54 -0700379}
380
Michael Layzell734adb42017-06-07 16:58:31 -0400381#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700382ast_struct! {
383 /// A Block (`{ .. }`).
384 ///
385 /// E.g. `{ .. }` as in `fn foo() { .. }`
386 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700387 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700388 /// Statements in a block
389 pub stmts: Vec<Stmt>,
390 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391}
392
Michael Layzell734adb42017-06-07 16:58:31 -0400393#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700394ast_enum! {
395 /// A statement, usually ending in a semicolon.
396 pub enum Stmt {
397 /// A local (let) binding.
398 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700399
Alex Crichton62a0a592017-05-22 13:58:53 -0700400 /// An item definition.
401 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700402
Alex Crichton62a0a592017-05-22 13:58:53 -0700403 /// Expr without trailing semicolon.
404 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700405
Alex Crichton62a0a592017-05-22 13:58:53 -0700406 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700407 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700408
Alex Crichton62a0a592017-05-22 13:58:53 -0700409 /// Macro invocation.
410 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
411 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700412}
413
Michael Layzell734adb42017-06-07 16:58:31 -0400414#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700415ast_enum! {
416 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700417 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 pub enum MacStmtStyle {
419 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
420 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700421 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500422
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 /// The macro statement had braces; e.g. foo! { ... }
424 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500425
Alex Crichton62a0a592017-05-22 13:58:53 -0700426 /// The macro statement had parentheses or brackets and no semicolon; e.g.
427 /// `foo!(...)`. All of these will end up being converted into macro
428 /// expressions.
429 NoBraces,
430 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700431}
432
Michael Layzell734adb42017-06-07 16:58:31 -0400433#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700434ast_struct! {
435 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
436 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700437 pub let_token: tokens::Let,
438 pub colon_token: Option<tokens::Colon>,
439 pub eq_token: Option<tokens::Eq>,
440 pub semi_token: tokens::Semi,
441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 pub pat: Box<Pat>,
443 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Initializer expression to set the value, if any
446 pub init: Option<Box<Expr>>,
447 pub attrs: Vec<Attribute>,
448 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700449}
450
Michael Layzell734adb42017-06-07 16:58:31 -0400451#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700452ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700453 // Clippy false positive
454 // https://github.com/Manishearth/rust-clippy/issues/1241
455 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
456 pub enum Pat {
457 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458 pub Wild(PatWild {
459 pub underscore_token: tokens::Underscore,
460 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
463 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
464 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
465 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700466 pub Ident(PatIdent {
467 pub mode: BindingMode,
468 pub ident: Ident,
469 pub subpat: Option<Box<Pat>>,
470 pub at_token: Option<tokens::At>,
471 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700472
Alex Crichton62a0a592017-05-22 13:58:53 -0700473 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
474 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 pub Struct(PatStruct {
476 pub path: Path,
477 pub fields: Delimited<FieldPat, tokens::Comma>,
478 pub brace_token: tokens::Brace,
479 pub dot2_token: Option<tokens::Dot2>,
480 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
483 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
484 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 pub TupleStruct(PatTupleStruct {
486 pub path: Path,
487 pub pat: PatTuple,
488 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A possibly qualified path pattern.
491 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
492 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
493 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 pub Path(PatPath {
495 pub qself: Option<QSelf>,
496 pub path: Path,
497 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700498
Alex Crichton62a0a592017-05-22 13:58:53 -0700499 /// A tuple pattern `(a, b)`.
500 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
501 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub Tuple(PatTuple {
503 pub pats: Delimited<Pat, tokens::Comma>,
504 pub dots_pos: Option<usize>,
505 pub paren_token: tokens::Paren,
506 pub dot2_token: Option<tokens::Dot2>,
507 pub comma_token: Option<tokens::Comma>,
508 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700509 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700510 pub Box(PatBox {
511 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700512 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Ref(PatRef {
516 pub pat: Box<Pat>,
517 pub mutbl: Mutability,
518 pub and_token: tokens::And,
519 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700520 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 pub Lit(PatLit {
522 pub expr: Box<Expr>,
523 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700524 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub Range(PatRange {
526 pub lo: Box<Expr>,
527 pub hi: Box<Expr>,
528 pub limits: RangeLimits,
529 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400530 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 pub Slice(PatSlice {
532 pub front: Delimited<Pat, tokens::Comma>,
533 pub middle: Option<Box<Pat>>,
534 pub back: Delimited<Pat, tokens::Comma>,
535 pub dot2_token: Option<tokens::Dot2>,
536 pub comma_token: Option<tokens::Comma>,
537 pub bracket_token: tokens::Bracket,
538 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700540 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700541 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700542}
543
Michael Layzell734adb42017-06-07 16:58:31 -0400544#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700545ast_struct! {
546 /// An arm of a 'match'.
547 ///
548 /// E.g. `0...10 => { println!("match!") }` as in
549 ///
550 /// ```rust,ignore
551 /// match n {
552 /// 0...10 => { println!("match!") },
553 /// // ..
554 /// }
555 /// ```
556 pub struct Arm {
557 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 pub pats: Delimited<Pat, tokens::Or>,
559 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700561 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700563 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700565}
566
Michael Layzell734adb42017-06-07 16:58:31 -0400567#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700568ast_enum! {
569 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700570 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 Ref,
574 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700575}
576
Michael Layzell734adb42017-06-07 16:58:31 -0400577#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700578ast_enum! {
579 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700580 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub enum RangeLimits {
582 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700583 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700585 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587}
588
Michael Layzell734adb42017-06-07 16:58:31 -0400589#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700590ast_struct! {
591 /// A single field in a struct pattern
592 ///
593 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
594 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
595 /// except `is_shorthand` is true
596 pub struct FieldPat {
597 /// The identifier for the field
598 pub ident: Ident,
599 /// The pattern the field is destructured to
600 pub pat: Box<Pat>,
601 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700602 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 pub attrs: Vec<Attribute>,
604 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700605}
606
Michael Layzell734adb42017-06-07 16:58:31 -0400607#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700608ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700609 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700611 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700612 ByValue(Mutability),
613 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700614}
615
Michael Layzell734adb42017-06-07 16:58:31 -0400616#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400617ast_enum! {
618 #[cfg_attr(feature = "clone-impls", derive(Copy))]
619 pub enum InPlaceKind {
620 Arrow(tokens::LArrow),
621 In(tokens::In),
622 }
623}
624
Michael Layzell3936ceb2017-07-08 00:28:36 -0400625#[cfg(any(feature = "parsing", feature = "printing"))]
626#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700627fn arm_expr_requires_comma(expr: &Expr) -> bool {
628 // see https://github.com/rust-lang/rust/blob/eb8f2586e
629 // /src/libsyntax/parse/classify.rs#L17-L37
630 match expr.node {
631 ExprKind::Block(..) |
632 ExprKind::If(..) |
633 ExprKind::IfLet(..) |
634 ExprKind::Match(..) |
635 ExprKind::While(..) |
636 ExprKind::WhileLet(..) |
637 ExprKind::Loop(..) |
638 ExprKind::ForLoop(..) |
639 ExprKind::Catch(..) => false,
640 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400641 }
642}
643
David Tolnayb9c8e322016-09-23 20:48:37 -0700644#[cfg(feature = "parsing")]
645pub mod parsing {
646 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700647 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700648
Michael Layzell734adb42017-06-07 16:58:31 -0400649 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700650 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400651 use synom::{PResult, Cursor, Synom};
652 #[cfg(feature = "full")]
653 use synom::parse_error;
Alex Crichton954046c2017-05-30 21:49:42 -0700654 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700655
Michael Layzellb78f3b52017-06-04 19:03:03 -0400656 /// When we're parsing expressions which occur before blocks, like in
657 /// an if statement's condition, we cannot parse a struct literal.
658 ///
659 /// Struct literals are ambiguous in certain positions
660 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700661 macro_rules! ambiguous_expr {
662 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700663 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700664 };
665 }
666
Michael Layzellb78f3b52017-06-04 19:03:03 -0400667 /// When we are parsing an optional suffix expression, we cannot allow
668 /// blocks if structs are not allowed.
669 ///
670 /// Example:
671 /// ```ignore
672 /// if break { } { }
673 /// // is ambiguous between:
674 /// if (break { }) { }
675 /// // - or -
676 /// if (break) { } { }
677 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400678 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400679 macro_rules! opt_ambiguous_expr {
680 ($i:expr, $allow_struct:ident) => {
681 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
682 };
683 }
684
Alex Crichton954046c2017-05-30 21:49:42 -0700685 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400686 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700687
688 fn description() -> Option<&'static str> {
689 Some("expression")
690 }
691 }
692
Michael Layzell734adb42017-06-07 16:58:31 -0400693 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700694 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
695
Michael Layzellb78f3b52017-06-04 19:03:03 -0400696 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400697 #[cfg(feature = "full")]
698 fn ambiguous_expr(i: Cursor,
699 allow_struct: bool,
700 allow_block: bool)
701 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400702 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700703 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400704 call!(assign_expr, allow_struct, allow_block),
705 ExprKind::into
706 )
707 }
708
Michael Layzell734adb42017-06-07 16:58:31 -0400709 #[cfg(not(feature = "full"))]
710 fn ambiguous_expr(i: Cursor,
711 allow_struct: bool,
712 allow_block: bool)
713 -> PResult<Expr> {
714 map!(
715 i,
716 // NOTE: We intentionally skip assign_expr, placement_expr, and
717 // range_expr, as they are not parsed in non-full mode.
718 call!(or_expr, allow_struct, allow_block),
719 ExprKind::into
720 )
721 }
722
Michael Layzellb78f3b52017-06-04 19:03:03 -0400723 /// Parse a left-associative binary operator.
724 macro_rules! binop {
725 (
726 $name: ident,
727 $next: ident,
728 $submac: ident!( $($args:tt)* )
729 ) => {
730 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
731 mut e: call!($next, allow_struct, allow_block) >>
732 many0!(do_parse!(
733 op: $submac!($($args)*) >>
734 rhs: call!($next, allow_struct, true) >>
735 ({
736 e = ExprBinary {
737 left: Box::new(e.into()),
738 op: op,
739 right: Box::new(rhs.into()),
740 }.into();
741 })
742 )) >>
743 (e)
744 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700745 }
David Tolnay54e854d2016-10-24 12:03:30 -0700746 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700747
Michael Layzellb78f3b52017-06-04 19:03:03 -0400748 /// ```ignore
749 /// <placement> = <placement> ..
750 /// <placement> += <placement> ..
751 /// <placement> -= <placement> ..
752 /// <placement> *= <placement> ..
753 /// <placement> /= <placement> ..
754 /// <placement> %= <placement> ..
755 /// <placement> ^= <placement> ..
756 /// <placement> &= <placement> ..
757 /// <placement> |= <placement> ..
758 /// <placement> <<= <placement> ..
759 /// <placement> >>= <placement> ..
760 /// ```
761 ///
762 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400763 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400764 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
765 mut e: call!(placement_expr, allow_struct, allow_block) >>
766 alt!(
767 do_parse!(
768 eq: syn!(Eq) >>
769 // Recurse into self to parse right-associative operator.
770 rhs: call!(assign_expr, allow_struct, true) >>
771 ({
772 e = ExprAssign {
773 left: Box::new(e.into()),
774 eq_token: eq,
775 right: Box::new(rhs.into()),
776 }.into();
777 })
778 )
779 |
780 do_parse!(
781 op: call!(BinOp::parse_assign_op) >>
782 // Recurse into self to parse right-associative operator.
783 rhs: call!(assign_expr, allow_struct, true) >>
784 ({
785 e = ExprAssignOp {
786 left: Box::new(e.into()),
787 op: op,
788 right: Box::new(rhs.into()),
789 }.into();
790 })
791 )
792 |
793 epsilon!()
794 ) >>
795 (e)
796 ));
797
798 /// ```ignore
799 /// <range> <- <range> ..
800 /// ```
801 ///
802 /// NOTE: The `in place { expr }` version of this syntax is parsed in
803 /// `atom_expr`, not here.
804 ///
805 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400806 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400807 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
808 mut e: call!(range_expr, allow_struct, allow_block) >>
809 alt!(
810 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400811 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400812 // Recurse into self to parse right-associative operator.
813 rhs: call!(placement_expr, allow_struct, true) >>
814 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400815 e = ExprInPlace {
816 // op: BinOp::Place(larrow),
817 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400818 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400819 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400820 }.into();
821 })
822 )
823 |
824 epsilon!()
825 ) >>
826 (e)
827 ));
828
829 /// ```ignore
830 /// <or> ... <or> ..
831 /// <or> .. <or> ..
832 /// <or> ..
833 /// ```
834 ///
835 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
836 /// rules are for parsing these expressions are, but this is not correct.
837 /// For example, `a .. b .. c` is not a legal expression. It should not
838 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
839 ///
840 /// NOTE: The form of ranges which don't include a preceding expression are
841 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400842 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400843 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
844 mut e: call!(or_expr, allow_struct, allow_block) >>
845 many0!(do_parse!(
846 limits: syn!(RangeLimits) >>
847 // We don't want to allow blocks here if we don't allow structs. See
848 // the reasoning for `opt_ambiguous_expr!` above.
849 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
850 ({
851 e = ExprRange {
852 from: Some(Box::new(e.into())),
853 limits: limits,
854 to: hi.map(|e| Box::new(e.into())),
855 }.into();
856 })
857 )) >>
858 (e)
859 ));
860
861 /// ```ignore
862 /// <and> || <and> ...
863 /// ```
864 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
865
866 /// ```ignore
867 /// <compare> && <compare> ...
868 /// ```
869 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
870
871 /// ```ignore
872 /// <bitor> == <bitor> ...
873 /// <bitor> != <bitor> ...
874 /// <bitor> >= <bitor> ...
875 /// <bitor> <= <bitor> ...
876 /// <bitor> > <bitor> ...
877 /// <bitor> < <bitor> ...
878 /// ```
879 ///
880 /// NOTE: This operator appears to be parsed as left-associative, but errors
881 /// if it is used in a non-associative manner.
882 binop!(compare_expr, bitor_expr, alt!(
883 syn!(EqEq) => { BinOp::Eq }
884 |
885 syn!(Ne) => { BinOp::Ne }
886 |
887 // must be above Lt
888 syn!(Le) => { BinOp::Le }
889 |
890 // must be above Gt
891 syn!(Ge) => { BinOp::Ge }
892 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400893 do_parse!(
894 // Make sure that we don't eat the < part of a <- operator
895 not!(syn!(LArrow)) >>
896 t: syn!(Lt) >>
897 (BinOp::Lt(t))
898 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400899 |
900 syn!(Gt) => { BinOp::Gt }
901 ));
902
903 /// ```ignore
904 /// <bitxor> | <bitxor> ...
905 /// ```
906 binop!(bitor_expr, bitxor_expr, do_parse!(
907 not!(syn!(OrOr)) >>
908 not!(syn!(OrEq)) >>
909 t: syn!(Or) >>
910 (BinOp::BitOr(t))
911 ));
912
913 /// ```ignore
914 /// <bitand> ^ <bitand> ...
915 /// ```
916 binop!(bitxor_expr, bitand_expr, do_parse!(
917 // NOTE: Make sure we aren't looking at ^=.
918 not!(syn!(CaretEq)) >>
919 t: syn!(Caret) >>
920 (BinOp::BitXor(t))
921 ));
922
923 /// ```ignore
924 /// <shift> & <shift> ...
925 /// ```
926 binop!(bitand_expr, shift_expr, do_parse!(
927 // NOTE: Make sure we aren't looking at && or &=.
928 not!(syn!(AndAnd)) >>
929 not!(syn!(AndEq)) >>
930 t: syn!(And) >>
931 (BinOp::BitAnd(t))
932 ));
933
934 /// ```ignore
935 /// <arith> << <arith> ...
936 /// <arith> >> <arith> ...
937 /// ```
938 binop!(shift_expr, arith_expr, alt!(
939 syn!(Shl) => { BinOp::Shl }
940 |
941 syn!(Shr) => { BinOp::Shr }
942 ));
943
944 /// ```ignore
945 /// <term> + <term> ...
946 /// <term> - <term> ...
947 /// ```
948 binop!(arith_expr, term_expr, alt!(
949 syn!(Add) => { BinOp::Add }
950 |
951 syn!(Sub) => { BinOp::Sub }
952 ));
953
954 /// ```ignore
955 /// <cast> * <cast> ...
956 /// <cast> / <cast> ...
957 /// <cast> % <cast> ...
958 /// ```
959 binop!(term_expr, cast_expr, alt!(
960 syn!(Star) => { BinOp::Mul }
961 |
962 syn!(Div) => { BinOp::Div }
963 |
964 syn!(Rem) => { BinOp::Rem }
965 ));
966
967 /// ```ignore
968 /// <unary> as <ty>
969 /// <unary> : <ty>
970 /// ```
971 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
972 mut e: call!(unary_expr, allow_struct, allow_block) >>
973 many0!(alt!(
974 do_parse!(
975 as_: syn!(As) >>
976 // We can't accept `A + B` in cast expressions, as it's
977 // ambiguous with the + expression.
978 ty: call!(Ty::without_plus) >>
979 ({
980 e = ExprCast {
981 expr: Box::new(e.into()),
982 as_token: as_,
983 ty: Box::new(ty),
984 }.into();
985 })
986 )
987 |
988 do_parse!(
989 colon: syn!(Colon) >>
990 // We can't accept `A + B` in cast expressions, as it's
991 // ambiguous with the + expression.
992 ty: call!(Ty::without_plus) >>
993 ({
994 e = ExprType {
995 expr: Box::new(e.into()),
996 colon_token: colon,
997 ty: Box::new(ty),
998 }.into();
999 })
1000 )
1001 )) >>
1002 (e)
1003 ));
1004
1005 /// ```
1006 /// <UnOp> <trailer>
1007 /// & <trailer>
1008 /// &mut <trailer>
1009 /// box <trailer>
1010 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001011 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001012 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1013 do_parse!(
1014 op: syn!(UnOp) >>
1015 expr: call!(unary_expr, allow_struct, true) >>
1016 (ExprUnary {
1017 op: op,
1018 expr: Box::new(expr.into()),
1019 }.into())
1020 )
1021 |
1022 do_parse!(
1023 and: syn!(And) >>
1024 mutability: syn!(Mutability) >>
1025 expr: call!(unary_expr, allow_struct, true) >>
1026 (ExprAddrOf {
1027 and_token: and,
1028 mutbl: mutability,
1029 expr: Box::new(expr.into()),
1030 }.into())
1031 )
1032 |
1033 do_parse!(
1034 box_: syn!(Box_) >>
1035 expr: call!(unary_expr, allow_struct, true) >>
1036 (ExprBox {
1037 box_token: box_,
1038 expr: Box::new(expr.into()),
1039 }.into())
1040 )
1041 |
1042 call!(trailer_expr, allow_struct, allow_block)
1043 ));
1044
Michael Layzell734adb42017-06-07 16:58:31 -04001045 // XXX: This duplication is ugly
1046 #[cfg(not(feature = "full"))]
1047 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1048 do_parse!(
1049 op: syn!(UnOp) >>
1050 expr: call!(unary_expr, allow_struct, true) >>
1051 (ExprUnary {
1052 op: op,
1053 expr: Box::new(expr.into()),
1054 }.into())
1055 )
1056 |
1057 call!(trailer_expr, allow_struct, allow_block)
1058 ));
1059
Michael Layzellb78f3b52017-06-04 19:03:03 -04001060 /// ```ignore
1061 /// <atom> (..<args>) ...
1062 /// <atom> . <ident> (..<args>) ...
1063 /// <atom> . <ident> ...
1064 /// <atom> . <lit> ...
1065 /// <atom> [ <expr> ] ...
1066 /// <atom> ? ...
1067 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001068 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001069 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1070 mut e: call!(atom_expr, allow_struct, allow_block) >>
1071 many0!(alt!(
1072 tap!(args: and_call => {
1073 let (args, paren) = args;
1074 e = ExprCall {
1075 func: Box::new(e.into()),
1076 args: args,
1077 paren_token: paren,
1078 }.into();
1079 })
1080 |
1081 tap!(more: and_method_call => {
1082 let mut call = more;
1083 call.expr = Box::new(e.into());
1084 e = call.into();
1085 })
1086 |
1087 tap!(field: and_field => {
1088 let (field, token) = field;
1089 e = ExprField {
1090 expr: Box::new(e.into()),
1091 field: field,
1092 dot_token: token,
1093 }.into();
1094 })
1095 |
1096 tap!(field: and_tup_field => {
1097 let (field, token) = field;
1098 e = ExprTupField {
1099 expr: Box::new(e.into()),
1100 field: field,
1101 dot_token: token,
1102 }.into();
1103 })
1104 |
1105 tap!(i: and_index => {
1106 let (i, token) = i;
1107 e = ExprIndex {
1108 expr: Box::new(e.into()),
1109 bracket_token: token,
1110 index: Box::new(i),
1111 }.into();
1112 })
1113 |
1114 tap!(question: syn!(Question) => {
1115 e = ExprTry {
1116 expr: Box::new(e.into()),
1117 question_token: question,
1118 }.into();
1119 })
1120 )) >>
1121 (e)
1122 ));
1123
Michael Layzell734adb42017-06-07 16:58:31 -04001124 // XXX: Duplication == ugly
1125 #[cfg(not(feature = "full"))]
1126 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1127 mut e: call!(atom_expr, allow_struct, allow_block) >>
1128 many0!(alt!(
1129 tap!(args: and_call => {
1130 let (args, paren) = args;
1131 e = ExprCall {
1132 func: Box::new(e.into()),
1133 args: args,
1134 paren_token: paren,
1135 }.into();
1136 })
1137 |
1138 tap!(i: and_index => {
1139 let (i, token) = i;
1140 e = ExprIndex {
1141 expr: Box::new(e.into()),
1142 bracket_token: token,
1143 index: Box::new(i),
1144 }.into();
1145 })
1146 )) >>
1147 (e)
1148 ));
1149
Michael Layzellb78f3b52017-06-04 19:03:03 -04001150 /// Parse all atomic expressions which don't have to worry about precidence
1151 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001152 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001153 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001154 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1155 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001156 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1157 |
1158 // must be before expr_path
1159 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1160 |
1161 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1162 |
1163 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1164 |
1165 call!(expr_break, allow_struct) // must be before expr_path
1166 |
1167 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1168 |
1169 call!(expr_ret, allow_struct) // must be before expr_path
1170 |
1171 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1172 syn!(ExprInPlace) => { ExprKind::InPlace }
1173 |
1174 syn!(ExprArray) => { ExprKind::Array }
1175 |
1176 syn!(ExprTup) => { ExprKind::Tup }
1177 |
1178 syn!(ExprIf) => { ExprKind::If }
1179 |
1180 syn!(ExprIfLet) => { ExprKind::IfLet }
1181 |
1182 syn!(ExprWhile) => { ExprKind::While }
1183 |
1184 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1185 |
1186 syn!(ExprForLoop) => { ExprKind::ForLoop }
1187 |
1188 syn!(ExprLoop) => { ExprKind::Loop }
1189 |
1190 syn!(ExprMatch) => { ExprKind::Match }
1191 |
1192 syn!(ExprCatch) => { ExprKind::Catch }
1193 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001194 syn!(ExprYield) => { ExprKind::Yield }
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 |
1216 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1217 |
1218 syn!(ExprPath) => { ExprKind::Path }
1219 ));
1220
1221
1222 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001223 named!(expr_nosemi -> Expr, map!(alt!(
1224 syn!(ExprIf) => { ExprKind::If }
1225 |
1226 syn!(ExprIfLet) => { ExprKind::IfLet }
1227 |
1228 syn!(ExprWhile) => { ExprKind::While }
1229 |
1230 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1231 |
1232 syn!(ExprForLoop) => { ExprKind::ForLoop }
1233 |
1234 syn!(ExprLoop) => { ExprKind::Loop }
1235 |
1236 syn!(ExprMatch) => { ExprKind::Match }
1237 |
1238 syn!(ExprCatch) => { ExprKind::Catch }
1239 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001240 syn!(ExprYield) => { ExprKind::Yield }
1241 |
Michael Layzell35418782017-06-07 09:20:25 -04001242 syn!(ExprBlock) => { ExprKind::Block }
1243 ), Expr::from));
1244
Michael Layzell93c36282017-06-04 20:43:14 -04001245 impl Synom for ExprGroup {
1246 named!(parse -> Self, do_parse!(
1247 e: grouped!(syn!(Expr)) >>
1248 (ExprGroup {
1249 expr: Box::new(e.0),
1250 group_token: e.1,
1251 }.into())
1252 ));
1253 }
1254
Alex Crichton954046c2017-05-30 21:49:42 -07001255 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001256 named!(parse -> Self, do_parse!(
1257 e: parens!(syn!(Expr)) >>
1258 (ExprParen {
1259 expr: Box::new(e.0),
1260 paren_token: e.1,
1261 }.into())
1262 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001263 }
David Tolnay89e05672016-10-02 14:39:42 -07001264
Michael Layzell734adb42017-06-07 16:58:31 -04001265 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001266 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001267 named!(parse -> Self, do_parse!(
1268 in_: syn!(In) >>
1269 place: expr_no_struct >>
1270 value: braces!(call!(Block::parse_within)) >>
1271 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001272 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001273 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001274 value: Box::new(Expr {
1275 node: ExprBlock {
1276 unsafety: Unsafety::Normal,
1277 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
Alex Crichton954046c2017-05-30 21:49:42 -07001299 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1300 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!(
Alex Crichton954046c2017-05-30 21:49:42 -07001304 dot: syn!(Dot) >>
1305 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001306 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001307 colon2: syn!(Colon2) >>
1308 lt: syn!(Lt) >>
1309 tys: call!(Delimited::parse_terminated) >>
1310 gt: syn!(Gt) >>
1311 (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")]
Alex Crichton954046c2017-05-30 21:49:42 -07001339 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001340 named!(parse -> Self, do_parse!(
1341 elems: parens!(call!(Delimited::parse_terminated)) >>
1342 (ExprTup {
1343 args: elems.0,
1344 paren_token: elems.1,
1345 lone_comma: None, // TODO: parse this
1346 })
1347 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001348 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001349
Michael Layzell734adb42017-06-07 16:58:31 -04001350 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001351 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001352 named!(parse -> Self, do_parse!(
1353 if_: syn!(If) >>
1354 let_: syn!(Let) >>
1355 pat: syn!(Pat) >>
1356 eq: syn!(Eq) >>
1357 cond: expr_no_struct >>
1358 then_block: braces!(call!(Block::parse_within)) >>
1359 else_block: option!(else_block) >>
1360 (ExprIfLet {
1361 pat: Box::new(pat),
1362 let_token: let_,
1363 eq_token: eq,
1364 expr: Box::new(cond),
1365 if_true: Block {
1366 stmts: then_block.0,
1367 brace_token: then_block.1,
1368 },
1369 if_token: if_,
1370 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1371 if_false: else_block.map(|p| Box::new(p.1.into())),
1372 })
1373 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001374 }
1375
Michael Layzell734adb42017-06-07 16:58:31 -04001376 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001377 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001378 named!(parse -> Self, do_parse!(
1379 if_: syn!(If) >>
1380 cond: expr_no_struct >>
1381 then_block: braces!(call!(Block::parse_within)) >>
1382 else_block: option!(else_block) >>
1383 (ExprIf {
1384 cond: Box::new(cond),
1385 if_true: Block {
1386 stmts: then_block.0,
1387 brace_token: then_block.1,
1388 },
1389 if_token: if_,
1390 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1391 if_false: else_block.map(|p| Box::new(p.1.into())),
1392 })
1393 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001394 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001395
Michael Layzell734adb42017-06-07 16:58:31 -04001396 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001397 named!(else_block -> (Else, ExprKind), do_parse!(
1398 else_: syn!(Else) >>
1399 expr: alt!(
1400 syn!(ExprIf) => { ExprKind::If }
1401 |
1402 syn!(ExprIfLet) => { ExprKind::IfLet }
1403 |
1404 do_parse!(
1405 else_block: braces!(call!(Block::parse_within)) >>
1406 (ExprKind::Block(ExprBlock {
1407 unsafety: Unsafety::Normal,
1408 block: Block {
1409 stmts: else_block.0,
1410 brace_token: else_block.1,
1411 },
1412 }))
David Tolnay939766a2016-09-23 23:48:12 -07001413 )
Alex Crichton954046c2017-05-30 21:49:42 -07001414 ) >>
1415 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001416 ));
1417
David Tolnaybb6feae2016-10-02 21:25:20 -07001418
Michael Layzell734adb42017-06-07 16:58:31 -04001419 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001420 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001421 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001422 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001423 for_: syn!(For) >>
1424 pat: syn!(Pat) >>
1425 in_: syn!(In) >>
1426 expr: expr_no_struct >>
1427 loop_block: syn!(Block) >>
1428 (ExprForLoop {
1429 for_token: for_,
1430 in_token: in_,
1431 pat: Box::new(pat),
1432 expr: Box::new(expr),
1433 body: loop_block,
1434 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1435 label: lbl.map(|p| p.0),
1436 })
1437 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001438 }
Gregory Katze5f35682016-09-27 14:20:55 -04001439
Michael Layzell734adb42017-06-07 16:58:31 -04001440 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001441 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001442 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001443 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001444 loop_: syn!(Loop) >>
1445 loop_block: syn!(Block) >>
1446 (ExprLoop {
1447 loop_token: loop_,
1448 body: loop_block,
1449 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1450 label: lbl.map(|p| p.0),
1451 })
1452 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001453 }
1454
Michael Layzell734adb42017-06-07 16:58:31 -04001455 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001456 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001457 named!(parse -> Self, do_parse!(
1458 match_: syn!(Match) >>
1459 obj: expr_no_struct >>
Alex Crichton03b30272017-08-28 09:35:24 -07001460 res: braces!(many0!(syn!(Arm))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001461 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001462 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001463 ExprMatch {
1464 expr: Box::new(obj),
1465 match_token: match_,
1466 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001467 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001468 }
1469 })
1470 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001471 }
David Tolnay1978c672016-10-27 22:05:52 -07001472
Michael Layzell734adb42017-06-07 16:58:31 -04001473 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001474 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001475 named!(parse -> Self, do_parse!(
1476 do_: syn!(Do) >>
1477 catch_: syn!(Catch) >>
1478 catch_block: syn!(Block) >>
1479 (ExprCatch {
1480 block: catch_block,
1481 do_token: do_,
1482 catch_token: catch_,
1483 }.into())
1484 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001485 }
Arnavion02ef13f2017-04-25 00:54:31 -07001486
Michael Layzell734adb42017-06-07 16:58:31 -04001487 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001488 impl Synom for ExprYield {
1489 named!(parse -> Self, do_parse!(
1490 yield_: syn!(Yield) >>
1491 expr: option!(syn!(Expr)) >>
1492 (ExprYield {
1493 yield_token: yield_,
1494 expr: expr.map(Box::new),
1495 })
1496 ));
1497 }
1498
1499 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001500 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001501 named!(parse -> Self, do_parse!(
1502 attrs: many0!(call!(Attribute::parse_outer)) >>
1503 pats: call!(Delimited::parse_separated_nonempty) >>
1504 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1505 rocket: syn!(Rocket) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001506 body: do_parse!(
1507 expr: alt!(expr_nosemi | syn!(Expr)) >>
1508 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1509 map!(input_end!(), |_| None)
1510 |
1511 map!(syn!(Comma), Some)
1512 )) >>
1513 comma2: cond!(!arm_expr_requires_comma(&expr), option!(syn!(Comma))) >>
1514 (expr, comma1.and_then(|x| x).or(comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001515 ) >>
1516 (Arm {
1517 rocket_token: rocket,
1518 if_token: guard.as_ref().map(|p| If((p.0).0)),
1519 attrs: attrs,
1520 pats: pats,
1521 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001522 body: Box::new(body.0),
1523 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001524 })
1525 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001526 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001527
Michael Layzell734adb42017-06-07 16:58:31 -04001528 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001529 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001530 capture: syn!(CaptureBy) >>
1531 or1: syn!(Or) >>
1532 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1533 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001534 ret_and_body: alt!(
1535 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001536 arrow: syn!(RArrow) >>
1537 ty: syn!(Ty) >>
1538 body: syn!(Block) >>
1539 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001540 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001541 unsafety: Unsafety::Normal,
1542 block: body,
1543 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001544 )
1545 |
David Tolnay58af3552016-12-22 16:58:07 -05001546 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001547 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001548 (ExprClosure {
1549 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001550 or1_token: or1,
1551 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001552 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001553 inputs: inputs,
1554 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001555 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001556 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001557 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001558 generics: Generics::default(),
1559 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001560 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001561 body: Box::new(ret_and_body.1),
1562 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001563 ));
1564
Michael Layzell734adb42017-06-07 16:58:31 -04001565 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001566 named!(fn_arg -> FnArg, do_parse!(
1567 pat: syn!(Pat) >>
1568 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1569 ({
1570 let (colon, ty) = ty.unwrap_or_else(|| {
1571 (Colon::default(), TyInfer {
1572 underscore_token: Underscore::default(),
1573 }.into())
1574 });
1575 ArgCaptured {
1576 pat: pat,
1577 colon_token: colon,
1578 ty: ty,
1579 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001580 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001581 ));
1582
Michael Layzell734adb42017-06-07 16:58:31 -04001583 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001584 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001585 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001586 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001587 while_: syn!(While) >>
1588 cond: expr_no_struct >>
1589 while_block: syn!(Block) >>
1590 (ExprWhile {
1591 while_token: while_,
1592 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1593 cond: Box::new(cond),
1594 body: while_block,
1595 label: lbl.map(|p| p.0),
1596 })
1597 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001598 }
1599
Michael Layzell734adb42017-06-07 16:58:31 -04001600 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001601 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001602 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001603 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001604 while_: syn!(While) >>
1605 let_: syn!(Let) >>
1606 pat: syn!(Pat) >>
1607 eq: syn!(Eq) >>
1608 value: expr_no_struct >>
1609 while_block: syn!(Block) >>
1610 (ExprWhileLet {
1611 eq_token: eq,
1612 let_token: let_,
1613 while_token: while_,
1614 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1615 pat: Box::new(pat),
1616 expr: Box::new(value),
1617 body: while_block,
1618 label: lbl.map(|p| p.0),
1619 })
1620 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001621 }
1622
Michael Layzell734adb42017-06-07 16:58:31 -04001623 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001624 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001625 named!(parse -> Self, do_parse!(
1626 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001627 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001628 (ExprContinue {
1629 continue_token: cont,
1630 label: lbl,
1631 })
1632 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001633 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001634
Michael Layzell734adb42017-06-07 16:58:31 -04001635 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001636 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001637 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001638 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001639 // We can't allow blocks after a `break` expression when we wouldn't
1640 // allow structs, as this expression is ambiguous.
1641 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001642 (ExprBreak {
1643 label: lbl,
1644 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001645 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001646 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001647 ));
1648
Michael Layzell734adb42017-06-07 16:58:31 -04001649 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001650 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001651 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001652 // NOTE: return is greedy and eats blocks after it even when in a
1653 // position where structs are not allowed, such as in if statement
1654 // conditions. For example:
1655 //
1656 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001657 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001658 (ExprRet {
1659 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001660 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001661 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001662 ));
1663
Michael Layzell734adb42017-06-07 16:58:31 -04001664 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001665 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001666 named!(parse -> Self, do_parse!(
1667 path: syn!(Path) >>
1668 data: braces!(do_parse!(
1669 fields: call!(Delimited::parse_terminated) >>
1670 base: option!(
1671 cond!(fields.is_empty() || fields.trailing_delim(),
1672 do_parse!(
1673 dots: syn!(Dot2) >>
1674 base: syn!(Expr) >>
1675 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001676 )
Michael Layzell92639a52017-06-01 00:07:44 -04001677 )
1678 ) >>
1679 (fields, base)
1680 )) >>
1681 ({
1682 let ((fields, base), brace) = data;
1683 let (dots, rest) = match base.and_then(|b| b) {
1684 Some((dots, base)) => (Some(dots), Some(base)),
1685 None => (None, None),
1686 };
1687 ExprStruct {
1688 brace_token: brace,
1689 path: path,
1690 fields: fields,
1691 dot2_token: dots,
1692 rest: rest.map(Box::new),
1693 }
1694 })
1695 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001696 }
1697
Michael Layzell734adb42017-06-07 16:58:31 -04001698 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001699 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001700 named!(parse -> Self, alt!(
1701 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001702 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001703 colon: syn!(Colon) >>
1704 value: syn!(Expr) >>
1705 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001706 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001707 expr: value,
1708 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001709 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001710 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001711 })
Michael Layzell92639a52017-06-01 00:07:44 -04001712 )
1713 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001714 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001715 ident: name.clone(),
1716 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1717 is_shorthand: true,
1718 attrs: Vec::new(),
1719 colon_token: None,
1720 })
1721 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001722 }
David Tolnay055a7042016-10-02 19:23:54 -07001723
Michael Layzell734adb42017-06-07 16:58:31 -04001724 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001725 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001726 named!(parse -> Self, do_parse!(
1727 data: brackets!(do_parse!(
1728 value: syn!(Expr) >>
1729 semi: syn!(Semi) >>
1730 times: syn!(Expr) >>
1731 (value, semi, times)
1732 )) >>
1733 (ExprRepeat {
1734 expr: Box::new((data.0).0),
1735 amt: Box::new((data.0).2),
1736 bracket_token: data.1,
1737 semi_token: (data.0).1,
1738 })
1739 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001740 }
David Tolnay055a7042016-10-02 19:23:54 -07001741
Michael Layzell734adb42017-06-07 16:58:31 -04001742 #[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!(
1745 rules: syn!(Unsafety) >>
1746 b: syn!(Block) >>
1747 (ExprBlock {
1748 unsafety: rules,
1749 block: b,
1750 })
1751 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001752 }
David Tolnay89e05672016-10-02 14:39:42 -07001753
Michael Layzell734adb42017-06-07 16:58:31 -04001754 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001755 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001756 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001757 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001758 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001759 ));
1760
Michael Layzell734adb42017-06-07 16:58:31 -04001761 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001762 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001763 named!(parse -> Self, alt!(
1764 // Must come before Dot2
1765 syn!(Dot3) => { RangeLimits::Closed }
1766 |
1767 syn!(Dot2) => { RangeLimits::HalfOpen }
1768 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001769 }
David Tolnay438c9052016-10-07 23:24:48 -07001770
Alex Crichton954046c2017-05-30 21:49:42 -07001771 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001772 named!(parse -> Self, do_parse!(
1773 pair: qpath >>
1774 (ExprPath {
1775 qself: pair.0,
1776 path: pair.1,
1777 })
1778 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001779 }
David Tolnay42602292016-10-01 22:25:45 -07001780
Michael Layzell734adb42017-06-07 16:58:31 -04001781 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001782 named!(and_field -> (Ident, Dot),
1783 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001784
Michael Layzell734adb42017-06-07 16:58:31 -04001785 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001786 named!(and_tup_field -> (Lit, Dot),
1787 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001788
Alex Crichton954046c2017-05-30 21:49:42 -07001789 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001790
Michael Layzell734adb42017-06-07 16:58:31 -04001791 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001792 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001793 named!(parse -> Self, do_parse!(
1794 stmts: braces!(call!(Block::parse_within)) >>
1795 (Block {
1796 stmts: stmts.0,
1797 brace_token: stmts.1,
1798 })
1799 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001800 }
David Tolnay939766a2016-09-23 23:48:12 -07001801
Michael Layzell734adb42017-06-07 16:58:31 -04001802 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001803 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001804 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1805 many0!(syn!(Semi)) >>
1806 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001807 last: option!(do_parse!(
1808 attrs: many0!(call!(Attribute::parse_outer)) >>
1809 mut e: syn!(Expr) >>
1810 ({
1811 e.attrs = attrs;
1812 Stmt::Expr(Box::new(e))
1813 })
1814 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001815 (match last {
1816 None => standalone,
1817 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001818 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001819 standalone
1820 }
1821 })
1822 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001823 }
1824
Michael Layzell734adb42017-06-07 16:58:31 -04001825 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001826 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001827 named!(parse -> Self, alt!(
1828 stmt_mac
1829 |
1830 stmt_local
1831 |
1832 stmt_item
1833 |
Michael Layzell35418782017-06-07 09:20:25 -04001834 stmt_blockexpr
1835 |
Michael Layzell92639a52017-06-01 00:07:44 -04001836 stmt_expr
1837 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001838 }
David Tolnay939766a2016-09-23 23:48:12 -07001839
Michael Layzell734adb42017-06-07 16:58:31 -04001840 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001841 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001842 attrs: many0!(call!(Attribute::parse_outer)) >>
1843 what: syn!(Path) >>
1844 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001845 // Only parse braces here; paren and bracket will get parsed as
1846 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001847 data: braces!(syn!(TokenStream)) >>
1848 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001849 (Stmt::Mac(Box::new((
1850 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001851 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001852 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001853 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001854 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001855 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001856 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001857 })],
1858 },
Alex Crichton954046c2017-05-30 21:49:42 -07001859 match semi {
1860 Some(semi) => MacStmtStyle::Semicolon(semi),
1861 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001862 },
David Tolnayeea28d62016-10-25 20:44:08 -07001863 attrs,
1864 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001865 ));
1866
Michael Layzell734adb42017-06-07 16:58:31 -04001867 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001868 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001869 attrs: many0!(call!(Attribute::parse_outer)) >>
1870 let_: syn!(Let) >>
1871 pat: syn!(Pat) >>
1872 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1873 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1874 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001875 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001876 let_token: let_,
1877 semi_token: semi,
1878 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1879 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001880 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001881 ty: ty.map(|p| Box::new(p.1)),
1882 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001883 attrs: attrs,
1884 })))
1885 ));
1886
Michael Layzell734adb42017-06-07 16:58:31 -04001887 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001888 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001889
Michael Layzell734adb42017-06-07 16:58:31 -04001890 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001891 named!(stmt_blockexpr -> Stmt, do_parse!(
1892 attrs: many0!(call!(Attribute::parse_outer)) >>
1893 mut e: expr_nosemi >>
1894 // If the next token is a `.` or a `?` it is special-cased to parse as
1895 // an expression instead of a blockexpression.
1896 not!(syn!(Dot)) >>
1897 not!(syn!(Question)) >>
1898 semi: option!(syn!(Semi)) >>
1899 ({
1900 e.attrs = attrs;
1901 if let Some(semi) = semi {
1902 Stmt::Semi(Box::new(e), semi)
1903 } else {
1904 Stmt::Expr(Box::new(e))
1905 }
1906 })
1907 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001908
Michael Layzell734adb42017-06-07 16:58:31 -04001909 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001910 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001911 attrs: many0!(call!(Attribute::parse_outer)) >>
1912 mut e: syn!(Expr) >>
Michael Layzell35418782017-06-07 09:20:25 -04001913 semi: syn!(Semi) >>
David Tolnay7184b132016-10-30 10:06:37 -07001914 ({
1915 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001916 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001917 })
David Tolnay939766a2016-09-23 23:48:12 -07001918 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001919
Michael Layzell734adb42017-06-07 16:58:31 -04001920 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001921 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001922 named!(parse -> Self, alt!(
1923 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1924 |
1925 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1926 |
1927 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1928 |
1929 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1930 |
1931 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1932 |
1933 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1934 |
1935 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1936 |
1937 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1938 |
1939 syn!(PatPath) => { Pat::Path }
1940 |
1941 syn!(PatTuple) => { Pat::Tuple }
1942 |
1943 syn!(PatRef) => { Pat::Ref }
1944 |
1945 syn!(PatSlice) => { Pat::Slice }
1946 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001947 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001948
Michael Layzell734adb42017-06-07 16:58:31 -04001949 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001950 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001951 named!(parse -> Self, map!(
1952 syn!(Underscore),
1953 |u| PatWild { underscore_token: u }
1954 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001955 }
David Tolnay84aa0752016-10-02 23:01:13 -07001956
Michael Layzell734adb42017-06-07 16:58:31 -04001957 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001958 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001959 named!(parse -> Self, do_parse!(
1960 boxed: syn!(Box_) >>
1961 pat: syn!(Pat) >>
1962 (PatBox {
1963 pat: Box::new(pat),
1964 box_token: boxed,
1965 })
1966 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001967 }
1968
Michael Layzell734adb42017-06-07 16:58:31 -04001969 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001970 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001971 named!(parse -> Self, do_parse!(
1972 mode: option!(syn!(Ref)) >>
1973 mutability: syn!(Mutability) >>
1974 name: alt!(
1975 syn!(Ident)
1976 |
1977 syn!(Self_) => { Into::into }
1978 ) >>
1979 not!(syn!(Lt)) >>
1980 not!(syn!(Colon2)) >>
1981 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1982 (PatIdent {
1983 mode: match mode {
1984 Some(mode) => BindingMode::ByRef(mode, mutability),
1985 None => BindingMode::ByValue(mutability),
1986 },
1987 ident: name,
1988 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1989 subpat: subpat.map(|p| Box::new(p.1)),
1990 })
1991 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001992 }
1993
Michael Layzell734adb42017-06-07 16:58:31 -04001994 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001995 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001996 named!(parse -> Self, do_parse!(
1997 path: syn!(Path) >>
1998 tuple: syn!(PatTuple) >>
1999 (PatTupleStruct {
2000 path: path,
2001 pat: tuple,
2002 })
2003 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002004 }
2005
Michael Layzell734adb42017-06-07 16:58:31 -04002006 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002007 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002008 named!(parse -> Self, do_parse!(
2009 path: syn!(Path) >>
2010 data: braces!(do_parse!(
2011 fields: call!(Delimited::parse_terminated) >>
2012 base: option!(
2013 cond!(fields.is_empty() || fields.trailing_delim(),
2014 syn!(Dot2))
2015 ) >>
2016 (fields, base)
2017 )) >>
2018 (PatStruct {
2019 path: path,
2020 fields: (data.0).0,
2021 brace_token: data.1,
2022 dot2_token: (data.0).1.and_then(|m| m),
2023 })
2024 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002025 }
2026
Michael Layzell734adb42017-06-07 16:58:31 -04002027 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002028 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002029 named!(parse -> Self, alt!(
2030 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002031 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04002032 colon: syn!(Colon) >>
2033 pat: syn!(Pat) >>
2034 (FieldPat {
2035 ident: ident,
2036 pat: Box::new(pat),
2037 is_shorthand: false,
2038 attrs: Vec::new(),
2039 colon_token: Some(colon),
2040 })
2041 )
2042 |
2043 do_parse!(
2044 boxed: option!(syn!(Box_)) >>
2045 mode: option!(syn!(Ref)) >>
2046 mutability: syn!(Mutability) >>
2047 ident: syn!(Ident) >>
2048 ({
2049 let mut pat: Pat = PatIdent {
2050 mode: if let Some(mode) = mode {
2051 BindingMode::ByRef(mode, mutability)
2052 } else {
2053 BindingMode::ByValue(mutability)
2054 },
2055 ident: ident.clone(),
2056 subpat: None,
2057 at_token: None,
2058 }.into();
2059 if let Some(boxed) = boxed {
2060 pat = PatBox {
2061 pat: Box::new(pat),
2062 box_token: boxed,
2063 }.into();
2064 }
2065 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002066 ident: ident,
2067 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002068 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002069 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002070 colon_token: None,
2071 }
2072 })
2073 )
2074 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002075 }
2076
Michael Layzell734adb42017-06-07 16:58:31 -04002077 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002078 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002079 syn!(Ident)
2080 |
2081 do_parse!(
2082 lit: syn!(Lit) >>
2083 ({
David Tolnay570695e2017-06-03 16:15:13 -07002084 let s = lit.to_string();
2085 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002086 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002087 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002088 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002089 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002090 })
2091 )
2092 ));
2093
Michael Layzell734adb42017-06-07 16:58:31 -04002094 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002095 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002096 named!(parse -> Self, map!(
2097 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002098 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002099 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002100 }
David Tolnay9636c052016-10-02 17:11:17 -07002101
Michael Layzell734adb42017-06-07 16:58:31 -04002102 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002103 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002104 named!(parse -> Self, do_parse!(
2105 data: parens!(do_parse!(
2106 elems: call!(Delimited::parse_terminated) >>
2107 dotdot: map!(cond!(
2108 elems.is_empty() || elems.trailing_delim(),
2109 option!(do_parse!(
2110 dots: syn!(Dot2) >>
2111 trailing: option!(syn!(Comma)) >>
2112 (dots, trailing)
2113 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002114 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002115 rest: cond!(match dotdot {
2116 Some((_, Some(_))) => true,
2117 _ => false,
2118 },
2119 call!(Delimited::parse_terminated)) >>
2120 (elems, dotdot, rest)
2121 )) >>
2122 ({
2123 let ((mut elems, dotdot, rest), parens) = data;
2124 let (dotdot, trailing) = match dotdot {
2125 Some((a, b)) => (Some(a), Some(b)),
2126 None => (None, None),
2127 };
2128 PatTuple {
2129 paren_token: parens,
2130 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2131 dot2_token: dotdot,
2132 comma_token: trailing.and_then(|b| b),
2133 pats: {
2134 if let Some(rest) = rest {
2135 for elem in rest {
2136 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002137 }
Michael Layzell92639a52017-06-01 00:07:44 -04002138 }
2139 elems
2140 },
2141 }
2142 })
2143 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002144 }
David Tolnayfbb73232016-10-03 01:00:06 -07002145
Michael Layzell734adb42017-06-07 16:58:31 -04002146 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002147 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002148 named!(parse -> Self, do_parse!(
2149 and: syn!(And) >>
2150 mutability: syn!(Mutability) >>
2151 pat: syn!(Pat) >>
2152 (PatRef {
2153 pat: Box::new(pat),
2154 mutbl: mutability,
2155 and_token: and,
2156 })
2157 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002158 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002159
Michael Layzell734adb42017-06-07 16:58:31 -04002160 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002161 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002162 named!(parse -> Self, do_parse!(
2163 lit: pat_lit_expr >>
2164 (if let ExprKind::Path(_) = lit.node {
2165 return parse_error(); // these need to be parsed by pat_path
2166 } else {
2167 PatLit {
2168 expr: Box::new(lit),
2169 }
2170 })
2171 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002172 }
David Tolnaye1310902016-10-29 23:40:00 -07002173
Michael Layzell734adb42017-06-07 16:58:31 -04002174 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002175 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002176 named!(parse -> Self, do_parse!(
2177 lo: pat_lit_expr >>
2178 limits: syn!(RangeLimits) >>
2179 hi: pat_lit_expr >>
2180 (PatRange {
2181 lo: Box::new(lo),
2182 hi: Box::new(hi),
2183 limits: limits,
2184 })
2185 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002186 }
David Tolnaye1310902016-10-29 23:40:00 -07002187
Michael Layzell734adb42017-06-07 16:58:31 -04002188 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002189 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002190 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002191 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002192 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002193 |
Alex Crichton954046c2017-05-30 21:49:42 -07002194 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002195 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002196 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002197 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002198 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002199 expr: Box::new(v.into())
2200 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002201 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002202 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002203 })
2204 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002205
Michael Layzell734adb42017-06-07 16:58:31 -04002206 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002207 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002208 named!(parse -> Self, map!(
2209 brackets!(do_parse!(
2210 before: call!(Delimited::parse_terminated) >>
2211 middle: option!(do_parse!(
2212 dots: syn!(Dot2) >>
2213 trailing: option!(syn!(Comma)) >>
2214 (dots, trailing)
2215 )) >>
2216 after: cond!(
2217 match middle {
2218 Some((_, ref trailing)) => trailing.is_some(),
2219 _ => false,
2220 },
2221 call!(Delimited::parse_terminated)
2222 ) >>
2223 (before, middle, after)
2224 )),
2225 |((before, middle, after), brackets)| {
2226 let mut before: Delimited<Pat, tokens::Comma> = before;
2227 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2228 let middle: Option<(Dot2, Option<Comma>)> = middle;
2229 PatSlice {
2230 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2231 comma_token: middle.as_ref().and_then(|m| {
2232 m.1.as_ref().map(|m| Comma(m.0))
2233 }),
2234 bracket_token: brackets,
2235 middle: middle.and_then(|_| {
2236 if !before.is_empty() && !before.trailing_delim() {
2237 Some(Box::new(before.pop().unwrap().into_item()))
2238 } else {
2239 None
2240 }
2241 }),
2242 front: before,
2243 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002244 }
Alex Crichton954046c2017-05-30 21:49:42 -07002245 }
Michael Layzell92639a52017-06-01 00:07:44 -04002246 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002247 }
David Tolnay435a9a82016-10-29 13:47:20 -07002248
Michael Layzell734adb42017-06-07 16:58:31 -04002249 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002250 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002251 named!(parse -> Self, alt!(
2252 syn!(Move) => { CaptureBy::Value }
2253 |
2254 epsilon!() => { |_| CaptureBy::Ref }
2255 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002256 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002257}
2258
David Tolnayf4bbbd92016-09-23 14:41:55 -07002259#[cfg(feature = "printing")]
2260mod printing {
2261 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002262 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002263 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002264 use quote::{Tokens, ToTokens};
2265
Michael Layzell3936ceb2017-07-08 00:28:36 -04002266 /// If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2267 /// before appending it to `Tokens`.
2268 #[cfg(feature = "full")]
2269 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2270 if let ExprKind::Struct(_) = e.node {
2271 tokens::Paren::default().surround(tokens, |tokens| {
2272 e.to_tokens(tokens);
2273 });
2274 } else {
2275 e.to_tokens(tokens);
2276 }
2277 }
2278
David Tolnayf4bbbd92016-09-23 14:41:55 -07002279 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002280 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002281 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002282 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002283 self.node.to_tokens(tokens)
2284 }
Michael Layzell734adb42017-06-07 16:58:31 -04002285
2286 #[cfg(not(feature = "full"))]
2287 fn to_tokens(&self, tokens: &mut Tokens) {
2288 self.node.to_tokens(tokens)
2289 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002290 }
2291
Michael Layzell734adb42017-06-07 16:58:31 -04002292 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002293 impl ToTokens for ExprBox {
2294 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002295 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002296 self.expr.to_tokens(tokens);
2297 }
2298 }
2299
Michael Layzell734adb42017-06-07 16:58:31 -04002300 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002301 impl ToTokens for ExprInPlace {
2302 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002303 match self.kind {
2304 InPlaceKind::Arrow(ref arrow) => {
2305 self.place.to_tokens(tokens);
2306 arrow.to_tokens(tokens);
2307 self.value.to_tokens(tokens);
2308 }
2309 InPlaceKind::In(ref _in) => {
2310 _in.to_tokens(tokens);
2311 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002312 // NOTE: The second operand must be in a block, add one if
2313 // it is not present.
2314 if let ExprKind::Block(_) = self.value.node {
2315 self.value.to_tokens(tokens);
2316 } else {
2317 tokens::Brace::default().surround(tokens, |tokens| {
2318 self.value.to_tokens(tokens);
2319 })
2320 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002321 }
2322 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002323 }
2324 }
2325
Michael Layzell734adb42017-06-07 16:58:31 -04002326 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002327 impl ToTokens for ExprArray {
2328 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002329 self.bracket_token.surround(tokens, |tokens| {
2330 self.exprs.to_tokens(tokens);
2331 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002332 }
2333 }
2334
2335 impl ToTokens for ExprCall {
2336 fn to_tokens(&self, tokens: &mut Tokens) {
2337 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002338 self.paren_token.surround(tokens, |tokens| {
2339 self.args.to_tokens(tokens);
2340 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002341 }
2342 }
2343
Michael Layzell734adb42017-06-07 16:58:31 -04002344 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002345 impl ToTokens for ExprMethodCall {
2346 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002347 self.expr.to_tokens(tokens);
2348 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002349 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002350 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002351 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2352 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002353 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002354 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002355 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002356 self.paren_token.surround(tokens, |tokens| {
2357 self.args.to_tokens(tokens);
2358 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002359 }
2360 }
2361
Michael Layzell734adb42017-06-07 16:58:31 -04002362 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002363 impl ToTokens for ExprTup {
2364 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002365 self.paren_token.surround(tokens, |tokens| {
2366 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002367 // If we only have one argument, we need a trailing comma to
2368 // distinguish ExprTup from ExprParen.
2369 if self.args.len() == 1 && !self.args.trailing_delim() {
2370 tokens::Comma::default().to_tokens(tokens);
2371 }
2372 // XXX: Not sure how to handle this, but we never parse it yet.
2373 // Is this for an expression like (0,)? Can't we use the
2374 // trailing delimiter on Delimited for that? (,) isn't a valid
2375 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002376 self.lone_comma.to_tokens(tokens);
2377 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002378 }
2379 }
2380
2381 impl ToTokens for ExprBinary {
2382 fn to_tokens(&self, tokens: &mut Tokens) {
2383 self.left.to_tokens(tokens);
2384 self.op.to_tokens(tokens);
2385 self.right.to_tokens(tokens);
2386 }
2387 }
2388
2389 impl ToTokens for ExprUnary {
2390 fn to_tokens(&self, tokens: &mut Tokens) {
2391 self.op.to_tokens(tokens);
2392 self.expr.to_tokens(tokens);
2393 }
2394 }
2395
2396 impl ToTokens for ExprCast {
2397 fn to_tokens(&self, tokens: &mut Tokens) {
2398 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002399 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002400 self.ty.to_tokens(tokens);
2401 }
2402 }
2403
2404 impl ToTokens for ExprType {
2405 fn to_tokens(&self, tokens: &mut Tokens) {
2406 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002407 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002408 self.ty.to_tokens(tokens);
2409 }
2410 }
2411
Michael Layzell734adb42017-06-07 16:58:31 -04002412 #[cfg(feature = "full")]
Michael Layzell3936ceb2017-07-08 00:28:36 -04002413 fn maybe_wrap_else(tokens: &mut Tokens,
2414 else_token: &Option<tokens::Else>,
2415 if_false: &Option<Box<Expr>>)
2416 {
2417 if let Some(ref if_false) = *if_false {
Alex Crichton259ee532017-07-14 06:51:02 -07002418 TokensOrDefault(&else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002419
2420 // If we are not one of the valid expressions to exist in an else
2421 // clause, wrap ourselves in a block.
2422 match if_false.node {
2423 ExprKind::If(_) |
2424 ExprKind::IfLet(_) |
2425 ExprKind::Block(_) => {
2426 if_false.to_tokens(tokens);
2427 }
2428 _ => {
2429 tokens::Brace::default().surround(tokens, |tokens| {
2430 if_false.to_tokens(tokens);
2431 });
2432 }
2433 }
2434 }
2435 }
2436
2437 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002438 impl ToTokens for ExprIf {
2439 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002440 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002441 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002442 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002443 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002444 }
2445 }
2446
Michael Layzell734adb42017-06-07 16:58:31 -04002447 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002448 impl ToTokens for ExprIfLet {
2449 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002450 self.if_token.to_tokens(tokens);
2451 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002452 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002453 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002454 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002455 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002456 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002457 }
2458 }
2459
Michael Layzell734adb42017-06-07 16:58:31 -04002460 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002461 impl ToTokens for ExprWhile {
2462 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002463 if self.label.is_some() {
2464 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002465 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002466 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002467 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002468 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 self.body.to_tokens(tokens);
2470 }
2471 }
2472
Michael Layzell734adb42017-06-07 16:58:31 -04002473 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002474 impl ToTokens for ExprWhileLet {
2475 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002476 if self.label.is_some() {
2477 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002478 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002479 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002480 self.while_token.to_tokens(tokens);
2481 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002482 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002483 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002484 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002485 self.body.to_tokens(tokens);
2486 }
2487 }
2488
Michael Layzell734adb42017-06-07 16:58:31 -04002489 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002490 impl ToTokens for ExprForLoop {
2491 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002492 if self.label.is_some() {
2493 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002494 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002495 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002496 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002497 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002498 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002499 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002500 self.body.to_tokens(tokens);
2501 }
2502 }
2503
Michael Layzell734adb42017-06-07 16:58:31 -04002504 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002505 impl ToTokens for ExprLoop {
2506 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002507 if self.label.is_some() {
2508 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002509 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002510 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002511 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002512 self.body.to_tokens(tokens);
2513 }
2514 }
2515
Michael Layzell734adb42017-06-07 16:58:31 -04002516 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002517 impl ToTokens for ExprMatch {
2518 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002519 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002520 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002521 self.brace_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002522 for (i, arm) in self.arms.iter().enumerate() {
2523 arm.to_tokens(tokens);
2524 // Ensure that we have a comma after a non-block arm, except
2525 // for the last one.
2526 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002527 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002528 tokens::Comma::default().to_tokens(tokens);
2529 }
2530 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002531 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002532 }
2533 }
2534
Michael Layzell734adb42017-06-07 16:58:31 -04002535 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002536 impl ToTokens for ExprCatch {
2537 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002538 self.do_token.to_tokens(tokens);
2539 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002540 self.block.to_tokens(tokens);
2541 }
2542 }
2543
Michael Layzell734adb42017-06-07 16:58:31 -04002544 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002545 impl ToTokens for ExprYield {
2546 fn to_tokens(&self, tokens: &mut Tokens) {
2547 self.yield_token.to_tokens(tokens);
2548 self.expr.to_tokens(tokens);
2549 }
2550 }
2551
2552 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002553 impl ToTokens for ExprClosure {
2554 fn to_tokens(&self, tokens: &mut Tokens) {
2555 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002556 self.or1_token.to_tokens(tokens);
2557 for item in self.decl.inputs.iter() {
2558 match **item.item() {
2559 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002560 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002561 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002562 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002563 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002564 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002565 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002566 self.or2_token.to_tokens(tokens);
2567 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002568 self.body.to_tokens(tokens);
2569 }
2570 }
2571
Michael Layzell734adb42017-06-07 16:58:31 -04002572 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002573 impl ToTokens for ExprBlock {
2574 fn to_tokens(&self, tokens: &mut Tokens) {
2575 self.unsafety.to_tokens(tokens);
2576 self.block.to_tokens(tokens);
2577 }
2578 }
2579
Michael Layzell734adb42017-06-07 16:58:31 -04002580 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002581 impl ToTokens for ExprAssign {
2582 fn to_tokens(&self, tokens: &mut Tokens) {
2583 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002584 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002585 self.right.to_tokens(tokens);
2586 }
2587 }
2588
Michael Layzell734adb42017-06-07 16:58:31 -04002589 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002590 impl ToTokens for ExprAssignOp {
2591 fn to_tokens(&self, tokens: &mut Tokens) {
2592 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002593 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002594 self.right.to_tokens(tokens);
2595 }
2596 }
2597
Michael Layzell734adb42017-06-07 16:58:31 -04002598 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002599 impl ToTokens for ExprField {
2600 fn to_tokens(&self, tokens: &mut Tokens) {
2601 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002602 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002603 // XXX: I don't think we can do anything if someone shoves a
2604 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002605 self.field.to_tokens(tokens);
2606 }
2607 }
2608
Michael Layzell734adb42017-06-07 16:58:31 -04002609 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002610 impl ToTokens for ExprTupField {
2611 fn to_tokens(&self, tokens: &mut Tokens) {
2612 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002613 self.dot_token.to_tokens(tokens);
2614 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 }
2616 }
2617
2618 impl ToTokens for ExprIndex {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
2620 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002621 self.bracket_token.surround(tokens, |tokens| {
2622 self.index.to_tokens(tokens);
2623 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002624 }
2625 }
2626
Michael Layzell734adb42017-06-07 16:58:31 -04002627 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002628 impl ToTokens for ExprRange {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
2630 self.from.to_tokens(tokens);
2631 self.limits.to_tokens(tokens);
2632 self.to.to_tokens(tokens);
2633 }
2634 }
2635
2636 impl ToTokens for ExprPath {
2637 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002638 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
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 ExprAddrOf {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002645 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002646 self.mutbl.to_tokens(tokens);
2647 self.expr.to_tokens(tokens);
2648 }
2649 }
2650
Michael Layzell734adb42017-06-07 16:58:31 -04002651 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002652 impl ToTokens for ExprBreak {
2653 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002654 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002655 self.label.to_tokens(tokens);
2656 self.expr.to_tokens(tokens);
2657 }
2658 }
2659
Michael Layzell734adb42017-06-07 16:58:31 -04002660 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002661 impl ToTokens for ExprContinue {
2662 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002663 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002664 self.label.to_tokens(tokens);
2665 }
2666 }
2667
Michael Layzell734adb42017-06-07 16:58:31 -04002668 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002669 impl ToTokens for ExprRet {
2670 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002671 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002672 self.expr.to_tokens(tokens);
2673 }
2674 }
2675
Michael Layzell734adb42017-06-07 16:58:31 -04002676 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002677 impl ToTokens for ExprStruct {
2678 fn to_tokens(&self, tokens: &mut Tokens) {
2679 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002680 self.brace_token.surround(tokens, |tokens| {
2681 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002682 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002683 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002684 self.rest.to_tokens(tokens);
2685 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002686 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002687 }
2688 }
2689
Michael Layzell734adb42017-06-07 16:58:31 -04002690 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002691 impl ToTokens for ExprRepeat {
2692 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002693 self.bracket_token.surround(tokens, |tokens| {
2694 self.expr.to_tokens(tokens);
2695 self.semi_token.to_tokens(tokens);
2696 self.amt.to_tokens(tokens);
2697 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002698 }
2699 }
2700
Michael Layzell93c36282017-06-04 20:43:14 -04002701 impl ToTokens for ExprGroup {
2702 fn to_tokens(&self, tokens: &mut Tokens) {
2703 self.group_token.surround(tokens, |tokens| {
2704 self.expr.to_tokens(tokens);
2705 });
2706 }
2707 }
2708
Alex Crichton62a0a592017-05-22 13:58:53 -07002709 impl ToTokens for ExprParen {
2710 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002711 self.paren_token.surround(tokens, |tokens| {
2712 self.expr.to_tokens(tokens);
2713 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002714 }
2715 }
2716
Michael Layzell734adb42017-06-07 16:58:31 -04002717 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002718 impl ToTokens for ExprTry {
2719 fn to_tokens(&self, tokens: &mut Tokens) {
2720 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002721 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002722 }
2723 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002724
Michael Layzell734adb42017-06-07 16:58:31 -04002725 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002726 impl ToTokens for FieldValue {
2727 fn to_tokens(&self, tokens: &mut Tokens) {
2728 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002729 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2730 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002731 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002732 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002733 self.expr.to_tokens(tokens);
2734 }
David Tolnay055a7042016-10-02 19:23:54 -07002735 }
2736 }
2737
Michael Layzell734adb42017-06-07 16:58:31 -04002738 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002739 impl ToTokens for Arm {
2740 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002741 tokens.append_all(&self.attrs);
2742 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002743 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002744 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002745 self.guard.to_tokens(tokens);
2746 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002747 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002748 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002749 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002750 }
2751 }
2752
Michael Layzell734adb42017-06-07 16:58:31 -04002753 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002754 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002755 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002756 self.underscore_token.to_tokens(tokens);
2757 }
2758 }
2759
Michael Layzell734adb42017-06-07 16:58:31 -04002760 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002761 impl ToTokens for PatIdent {
2762 fn to_tokens(&self, tokens: &mut Tokens) {
2763 self.mode.to_tokens(tokens);
2764 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002765 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002766 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002767 self.subpat.to_tokens(tokens);
2768 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002769 }
2770 }
2771
Michael Layzell734adb42017-06-07 16:58:31 -04002772 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002773 impl ToTokens for PatStruct {
2774 fn to_tokens(&self, tokens: &mut Tokens) {
2775 self.path.to_tokens(tokens);
2776 self.brace_token.surround(tokens, |tokens| {
2777 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002778 // NOTE: We need a comma before the dot2 token if it is present.
2779 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
2780 tokens::Comma::default().to_tokens(tokens);
2781 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002782 self.dot2_token.to_tokens(tokens);
2783 });
2784 }
2785 }
2786
Michael Layzell734adb42017-06-07 16:58:31 -04002787 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002788 impl ToTokens for PatTupleStruct {
2789 fn to_tokens(&self, tokens: &mut Tokens) {
2790 self.path.to_tokens(tokens);
2791 self.pat.to_tokens(tokens);
2792 }
2793 }
2794
Michael Layzell734adb42017-06-07 16:58:31 -04002795 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002796 impl ToTokens for PatPath {
2797 fn to_tokens(&self, tokens: &mut Tokens) {
2798 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2799 }
2800 }
2801
Michael Layzell734adb42017-06-07 16:58:31 -04002802 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002803 impl ToTokens for PatTuple {
2804 fn to_tokens(&self, tokens: &mut Tokens) {
2805 self.paren_token.surround(tokens, |tokens| {
2806 for (i, token) in self.pats.iter().enumerate() {
2807 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002808 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2809 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002810 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002811 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002812 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002813
2814 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002815 // Ensure there is a comma before the .. token.
2816 if !self.pats.empty_or_trailing() {
2817 tokens::Comma::default().to_tokens(tokens);
2818 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002819 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002820 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002821 });
2822 }
2823 }
2824
Michael Layzell734adb42017-06-07 16:58:31 -04002825 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002826 impl ToTokens for PatBox {
2827 fn to_tokens(&self, tokens: &mut Tokens) {
2828 self.box_token.to_tokens(tokens);
2829 self.pat.to_tokens(tokens);
2830 }
2831 }
2832
Michael Layzell734adb42017-06-07 16:58:31 -04002833 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002834 impl ToTokens for PatRef {
2835 fn to_tokens(&self, tokens: &mut Tokens) {
2836 self.and_token.to_tokens(tokens);
2837 self.mutbl.to_tokens(tokens);
2838 self.pat.to_tokens(tokens);
2839 }
2840 }
2841
Michael Layzell734adb42017-06-07 16:58:31 -04002842 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002843 impl ToTokens for PatLit {
2844 fn to_tokens(&self, tokens: &mut Tokens) {
2845 self.expr.to_tokens(tokens);
2846 }
2847 }
2848
Michael Layzell734adb42017-06-07 16:58:31 -04002849 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002850 impl ToTokens for PatRange {
2851 fn to_tokens(&self, tokens: &mut Tokens) {
2852 self.lo.to_tokens(tokens);
2853 self.limits.to_tokens(tokens);
2854 self.hi.to_tokens(tokens);
2855 }
2856 }
2857
Michael Layzell734adb42017-06-07 16:58:31 -04002858 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002859 impl ToTokens for PatSlice {
2860 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002861 // XXX: This is a mess, and it will be so easy to screw it up. How
2862 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002863 self.bracket_token.surround(tokens, |tokens| {
2864 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002865
2866 // If we need a comma before the middle or standalone .. token,
2867 // then make sure it's present.
2868 if !self.front.empty_or_trailing() &&
2869 (self.middle.is_some() || self.dot2_token.is_some())
2870 {
2871 tokens::Comma::default().to_tokens(tokens);
2872 }
2873
2874 // If we have an identifier, we always need a .. token.
2875 if self.middle.is_some() {
2876 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002877 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002878 } else if self.dot2_token.is_some() {
2879 self.dot2_token.to_tokens(tokens);
2880 }
2881
2882 // Make sure we have a comma before the back half.
2883 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002884 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002885 self.back.to_tokens(tokens);
2886 } else {
2887 self.comma_token.to_tokens(tokens);
2888 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002889 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002890 }
2891 }
2892
Michael Layzell734adb42017-06-07 16:58:31 -04002893 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002894 impl ToTokens for RangeLimits {
2895 fn to_tokens(&self, tokens: &mut Tokens) {
2896 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002897 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2898 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002899 }
2900 }
2901 }
2902
Michael Layzell734adb42017-06-07 16:58:31 -04002903 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002904 impl ToTokens for FieldPat {
2905 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002906 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002907 if !self.is_shorthand {
2908 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002909 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002910 }
2911 self.pat.to_tokens(tokens);
2912 }
2913 }
2914
Michael Layzell734adb42017-06-07 16:58:31 -04002915 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002916 impl ToTokens for BindingMode {
2917 fn to_tokens(&self, tokens: &mut Tokens) {
2918 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002919 BindingMode::ByRef(ref t, ref m) => {
2920 t.to_tokens(tokens);
2921 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002922 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002923 BindingMode::ByValue(ref m) => {
2924 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002925 }
2926 }
2927 }
2928 }
David Tolnay42602292016-10-01 22:25:45 -07002929
Michael Layzell734adb42017-06-07 16:58:31 -04002930 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002931 impl ToTokens for CaptureBy {
2932 fn to_tokens(&self, tokens: &mut Tokens) {
2933 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002934 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002935 CaptureBy::Ref => {
2936 // nothing
2937 }
David Tolnay89e05672016-10-02 14:39:42 -07002938 }
2939 }
2940 }
2941
Michael Layzell734adb42017-06-07 16:58:31 -04002942 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002943 impl ToTokens for Block {
2944 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002945 self.brace_token.surround(tokens, |tokens| {
2946 tokens.append_all(&self.stmts);
2947 });
David Tolnay42602292016-10-01 22:25:45 -07002948 }
2949 }
2950
Michael Layzell734adb42017-06-07 16:58:31 -04002951 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002952 impl ToTokens for Stmt {
2953 fn to_tokens(&self, tokens: &mut Tokens) {
2954 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002955 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002956 Stmt::Item(ref item) => item.to_tokens(tokens),
2957 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002958 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002959 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002960 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002961 }
David Tolnay13b3d352016-10-03 00:31:15 -07002962 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002963 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002964 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002965 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002966 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002967 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002968 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2969 // no semicolon
2970 }
David Tolnay13b3d352016-10-03 00:31:15 -07002971 }
2972 }
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}