blob: 6783b7dcb991f8e69c26c735998fcc2be5c77854 [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 }),
349 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700350}
351
Michael Layzell734adb42017-06-07 16:58:31 -0400352#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700353ast_struct! {
354 /// A field-value pair in a struct literal.
355 pub struct FieldValue {
356 /// Name of the field.
357 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500358
Alex Crichton62a0a592017-05-22 13:58:53 -0700359 /// Value of the field.
360 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500361
Alex Crichton62a0a592017-05-22 13:58:53 -0700362 /// Whether this is a shorthand field, e.g. `Struct { x }`
363 /// instead of `Struct { x: x }`.
364 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500365
Alex Crichton62a0a592017-05-22 13:58:53 -0700366 /// Attributes tagged on the field.
367 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700368
369 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700370 }
David Tolnay055a7042016-10-02 19:23:54 -0700371}
372
Michael Layzell734adb42017-06-07 16:58:31 -0400373#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700374ast_struct! {
375 /// A Block (`{ .. }`).
376 ///
377 /// E.g. `{ .. }` as in `fn foo() { .. }`
378 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700379 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700380 /// Statements in a block
381 pub stmts: Vec<Stmt>,
382 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700383}
384
Michael Layzell734adb42017-06-07 16:58:31 -0400385#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700386ast_enum! {
387 /// A statement, usually ending in a semicolon.
388 pub enum Stmt {
389 /// A local (let) binding.
390 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391
Alex Crichton62a0a592017-05-22 13:58:53 -0700392 /// An item definition.
393 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700394
Alex Crichton62a0a592017-05-22 13:58:53 -0700395 /// Expr without trailing semicolon.
396 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700397
Alex Crichton62a0a592017-05-22 13:58:53 -0700398 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700399 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700400
Alex Crichton62a0a592017-05-22 13:58:53 -0700401 /// Macro invocation.
402 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
403 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700404}
405
Michael Layzell734adb42017-06-07 16:58:31 -0400406#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700407ast_enum! {
408 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700409 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700410 pub enum MacStmtStyle {
411 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
412 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700413 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500414
Alex Crichton62a0a592017-05-22 13:58:53 -0700415 /// The macro statement had braces; e.g. foo! { ... }
416 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500417
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 /// The macro statement had parentheses or brackets and no semicolon; e.g.
419 /// `foo!(...)`. All of these will end up being converted into macro
420 /// expressions.
421 NoBraces,
422 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700423}
424
Michael Layzell734adb42017-06-07 16:58:31 -0400425#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700426ast_struct! {
427 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
428 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700429 pub let_token: tokens::Let,
430 pub colon_token: Option<tokens::Colon>,
431 pub eq_token: Option<tokens::Eq>,
432 pub semi_token: tokens::Semi,
433
Alex Crichton62a0a592017-05-22 13:58:53 -0700434 pub pat: Box<Pat>,
435 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500436
Alex Crichton62a0a592017-05-22 13:58:53 -0700437 /// Initializer expression to set the value, if any
438 pub init: Option<Box<Expr>>,
439 pub attrs: Vec<Attribute>,
440 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700441}
442
Michael Layzell734adb42017-06-07 16:58:31 -0400443#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700444ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 // Clippy false positive
446 // https://github.com/Manishearth/rust-clippy/issues/1241
447 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
448 pub enum Pat {
449 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700450 pub Wild(PatWild {
451 pub underscore_token: tokens::Underscore,
452 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700453
Alex Crichton62a0a592017-05-22 13:58:53 -0700454 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
455 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
456 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
457 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458 pub Ident(PatIdent {
459 pub mode: BindingMode,
460 pub ident: Ident,
461 pub subpat: Option<Box<Pat>>,
462 pub at_token: Option<tokens::At>,
463 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700464
Alex Crichton62a0a592017-05-22 13:58:53 -0700465 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
466 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700467 pub Struct(PatStruct {
468 pub path: Path,
469 pub fields: Delimited<FieldPat, tokens::Comma>,
470 pub brace_token: tokens::Brace,
471 pub dot2_token: Option<tokens::Dot2>,
472 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700473
Alex Crichton62a0a592017-05-22 13:58:53 -0700474 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
475 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
476 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700477 pub TupleStruct(PatTupleStruct {
478 pub path: Path,
479 pub pat: PatTuple,
480 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 /// A possibly qualified path pattern.
483 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
484 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
485 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700486 pub Path(PatPath {
487 pub qself: Option<QSelf>,
488 pub path: Path,
489 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700490
Alex Crichton62a0a592017-05-22 13:58:53 -0700491 /// A tuple pattern `(a, b)`.
492 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
493 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 pub Tuple(PatTuple {
495 pub pats: Delimited<Pat, tokens::Comma>,
496 pub dots_pos: Option<usize>,
497 pub paren_token: tokens::Paren,
498 pub dot2_token: Option<tokens::Dot2>,
499 pub comma_token: Option<tokens::Comma>,
500 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700501 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub Box(PatBox {
503 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700504 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700505 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700506 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700507 pub Ref(PatRef {
508 pub pat: Box<Pat>,
509 pub mutbl: Mutability,
510 pub and_token: tokens::And,
511 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700512 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 pub Lit(PatLit {
514 pub expr: Box<Expr>,
515 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700516 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700517 pub Range(PatRange {
518 pub lo: Box<Expr>,
519 pub hi: Box<Expr>,
520 pub limits: RangeLimits,
521 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700522 /// `[a, b, ..i, y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700523 pub Slice(PatSlice {
524 pub front: Delimited<Pat, tokens::Comma>,
525 pub middle: Option<Box<Pat>>,
526 pub back: Delimited<Pat, tokens::Comma>,
527 pub dot2_token: Option<tokens::Dot2>,
528 pub comma_token: Option<tokens::Comma>,
529 pub bracket_token: tokens::Bracket,
530 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700531 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700532 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700533 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700534}
535
Michael Layzell734adb42017-06-07 16:58:31 -0400536#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700537ast_struct! {
538 /// An arm of a 'match'.
539 ///
540 /// E.g. `0...10 => { println!("match!") }` as in
541 ///
542 /// ```rust,ignore
543 /// match n {
544 /// 0...10 => { println!("match!") },
545 /// // ..
546 /// }
547 /// ```
548 pub struct Arm {
549 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700550 pub pats: Delimited<Pat, tokens::Or>,
551 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700552 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700553 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700555 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700556 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700557}
558
Michael Layzell734adb42017-06-07 16:58:31 -0400559#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700560ast_enum! {
561 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700562 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700563 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700564 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700565 Ref,
566 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700567}
568
Michael Layzell734adb42017-06-07 16:58:31 -0400569#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700570ast_enum! {
571 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700572 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 pub enum RangeLimits {
574 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700576 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700577 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700578 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700579}
580
Michael Layzell734adb42017-06-07 16:58:31 -0400581#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700582ast_struct! {
583 /// A single field in a struct pattern
584 ///
585 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
586 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
587 /// except `is_shorthand` is true
588 pub struct FieldPat {
589 /// The identifier for the field
590 pub ident: Ident,
591 /// The pattern the field is destructured to
592 pub pat: Box<Pat>,
593 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700594 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700595 pub attrs: Vec<Attribute>,
596 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700597}
598
Michael Layzell734adb42017-06-07 16:58:31 -0400599#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700600ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700601 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700602 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700603 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700604 ByValue(Mutability),
605 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700606}
607
Michael Layzell734adb42017-06-07 16:58:31 -0400608#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400609ast_enum! {
610 #[cfg_attr(feature = "clone-impls", derive(Copy))]
611 pub enum InPlaceKind {
612 Arrow(tokens::LArrow),
613 In(tokens::In),
614 }
615}
616
David Tolnayb9c8e322016-09-23 20:48:37 -0700617#[cfg(feature = "parsing")]
618pub mod parsing {
619 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700620 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700621
Michael Layzell734adb42017-06-07 16:58:31 -0400622 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700623 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400624 use synom::{PResult, Cursor, Synom};
625 #[cfg(feature = "full")]
626 use synom::parse_error;
Alex Crichton954046c2017-05-30 21:49:42 -0700627 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700628
Michael Layzellb78f3b52017-06-04 19:03:03 -0400629 /// When we're parsing expressions which occur before blocks, like in
630 /// an if statement's condition, we cannot parse a struct literal.
631 ///
632 /// Struct literals are ambiguous in certain positions
633 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700634 macro_rules! ambiguous_expr {
635 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700636 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700637 };
638 }
639
Michael Layzellb78f3b52017-06-04 19:03:03 -0400640 /// When we are parsing an optional suffix expression, we cannot allow
641 /// blocks if structs are not allowed.
642 ///
643 /// Example:
644 /// ```ignore
645 /// if break { } { }
646 /// // is ambiguous between:
647 /// if (break { }) { }
648 /// // - or -
649 /// if (break) { } { }
650 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400651 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400652 macro_rules! opt_ambiguous_expr {
653 ($i:expr, $allow_struct:ident) => {
654 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
655 };
656 }
657
Alex Crichton954046c2017-05-30 21:49:42 -0700658 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400659 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700660
661 fn description() -> Option<&'static str> {
662 Some("expression")
663 }
664 }
665
Michael Layzell734adb42017-06-07 16:58:31 -0400666 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700667 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
668
Michael Layzellb78f3b52017-06-04 19:03:03 -0400669 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400670 #[cfg(feature = "full")]
671 fn ambiguous_expr(i: Cursor,
672 allow_struct: bool,
673 allow_block: bool)
674 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400675 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700676 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400677 call!(assign_expr, allow_struct, allow_block),
678 ExprKind::into
679 )
680 }
681
Michael Layzell734adb42017-06-07 16:58:31 -0400682 #[cfg(not(feature = "full"))]
683 fn ambiguous_expr(i: Cursor,
684 allow_struct: bool,
685 allow_block: bool)
686 -> PResult<Expr> {
687 map!(
688 i,
689 // NOTE: We intentionally skip assign_expr, placement_expr, and
690 // range_expr, as they are not parsed in non-full mode.
691 call!(or_expr, allow_struct, allow_block),
692 ExprKind::into
693 )
694 }
695
Michael Layzellb78f3b52017-06-04 19:03:03 -0400696 /// Parse a left-associative binary operator.
697 macro_rules! binop {
698 (
699 $name: ident,
700 $next: ident,
701 $submac: ident!( $($args:tt)* )
702 ) => {
703 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
704 mut e: call!($next, allow_struct, allow_block) >>
705 many0!(do_parse!(
706 op: $submac!($($args)*) >>
707 rhs: call!($next, allow_struct, true) >>
708 ({
709 e = ExprBinary {
710 left: Box::new(e.into()),
711 op: op,
712 right: Box::new(rhs.into()),
713 }.into();
714 })
715 )) >>
716 (e)
717 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700718 }
David Tolnay54e854d2016-10-24 12:03:30 -0700719 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700720
Michael Layzellb78f3b52017-06-04 19:03:03 -0400721 /// ```ignore
722 /// <placement> = <placement> ..
723 /// <placement> += <placement> ..
724 /// <placement> -= <placement> ..
725 /// <placement> *= <placement> ..
726 /// <placement> /= <placement> ..
727 /// <placement> %= <placement> ..
728 /// <placement> ^= <placement> ..
729 /// <placement> &= <placement> ..
730 /// <placement> |= <placement> ..
731 /// <placement> <<= <placement> ..
732 /// <placement> >>= <placement> ..
733 /// ```
734 ///
735 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400736 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400737 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
738 mut e: call!(placement_expr, allow_struct, allow_block) >>
739 alt!(
740 do_parse!(
741 eq: syn!(Eq) >>
742 // Recurse into self to parse right-associative operator.
743 rhs: call!(assign_expr, allow_struct, true) >>
744 ({
745 e = ExprAssign {
746 left: Box::new(e.into()),
747 eq_token: eq,
748 right: Box::new(rhs.into()),
749 }.into();
750 })
751 )
752 |
753 do_parse!(
754 op: call!(BinOp::parse_assign_op) >>
755 // Recurse into self to parse right-associative operator.
756 rhs: call!(assign_expr, allow_struct, true) >>
757 ({
758 e = ExprAssignOp {
759 left: Box::new(e.into()),
760 op: op,
761 right: Box::new(rhs.into()),
762 }.into();
763 })
764 )
765 |
766 epsilon!()
767 ) >>
768 (e)
769 ));
770
771 /// ```ignore
772 /// <range> <- <range> ..
773 /// ```
774 ///
775 /// NOTE: The `in place { expr }` version of this syntax is parsed in
776 /// `atom_expr`, not here.
777 ///
778 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400779 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400780 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
781 mut e: call!(range_expr, allow_struct, allow_block) >>
782 alt!(
783 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400784 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400785 // Recurse into self to parse right-associative operator.
786 rhs: call!(placement_expr, allow_struct, true) >>
787 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400788 e = ExprInPlace {
789 // op: BinOp::Place(larrow),
790 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400791 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400792 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400793 }.into();
794 })
795 )
796 |
797 epsilon!()
798 ) >>
799 (e)
800 ));
801
802 /// ```ignore
803 /// <or> ... <or> ..
804 /// <or> .. <or> ..
805 /// <or> ..
806 /// ```
807 ///
808 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
809 /// rules are for parsing these expressions are, but this is not correct.
810 /// For example, `a .. b .. c` is not a legal expression. It should not
811 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
812 ///
813 /// NOTE: The form of ranges which don't include a preceding expression are
814 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400815 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400816 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
817 mut e: call!(or_expr, allow_struct, allow_block) >>
818 many0!(do_parse!(
819 limits: syn!(RangeLimits) >>
820 // We don't want to allow blocks here if we don't allow structs. See
821 // the reasoning for `opt_ambiguous_expr!` above.
822 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
823 ({
824 e = ExprRange {
825 from: Some(Box::new(e.into())),
826 limits: limits,
827 to: hi.map(|e| Box::new(e.into())),
828 }.into();
829 })
830 )) >>
831 (e)
832 ));
833
834 /// ```ignore
835 /// <and> || <and> ...
836 /// ```
837 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
838
839 /// ```ignore
840 /// <compare> && <compare> ...
841 /// ```
842 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
843
844 /// ```ignore
845 /// <bitor> == <bitor> ...
846 /// <bitor> != <bitor> ...
847 /// <bitor> >= <bitor> ...
848 /// <bitor> <= <bitor> ...
849 /// <bitor> > <bitor> ...
850 /// <bitor> < <bitor> ...
851 /// ```
852 ///
853 /// NOTE: This operator appears to be parsed as left-associative, but errors
854 /// if it is used in a non-associative manner.
855 binop!(compare_expr, bitor_expr, alt!(
856 syn!(EqEq) => { BinOp::Eq }
857 |
858 syn!(Ne) => { BinOp::Ne }
859 |
860 // must be above Lt
861 syn!(Le) => { BinOp::Le }
862 |
863 // must be above Gt
864 syn!(Ge) => { BinOp::Ge }
865 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400866 do_parse!(
867 // Make sure that we don't eat the < part of a <- operator
868 not!(syn!(LArrow)) >>
869 t: syn!(Lt) >>
870 (BinOp::Lt(t))
871 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400872 |
873 syn!(Gt) => { BinOp::Gt }
874 ));
875
876 /// ```ignore
877 /// <bitxor> | <bitxor> ...
878 /// ```
879 binop!(bitor_expr, bitxor_expr, do_parse!(
880 not!(syn!(OrOr)) >>
881 not!(syn!(OrEq)) >>
882 t: syn!(Or) >>
883 (BinOp::BitOr(t))
884 ));
885
886 /// ```ignore
887 /// <bitand> ^ <bitand> ...
888 /// ```
889 binop!(bitxor_expr, bitand_expr, do_parse!(
890 // NOTE: Make sure we aren't looking at ^=.
891 not!(syn!(CaretEq)) >>
892 t: syn!(Caret) >>
893 (BinOp::BitXor(t))
894 ));
895
896 /// ```ignore
897 /// <shift> & <shift> ...
898 /// ```
899 binop!(bitand_expr, shift_expr, do_parse!(
900 // NOTE: Make sure we aren't looking at && or &=.
901 not!(syn!(AndAnd)) >>
902 not!(syn!(AndEq)) >>
903 t: syn!(And) >>
904 (BinOp::BitAnd(t))
905 ));
906
907 /// ```ignore
908 /// <arith> << <arith> ...
909 /// <arith> >> <arith> ...
910 /// ```
911 binop!(shift_expr, arith_expr, alt!(
912 syn!(Shl) => { BinOp::Shl }
913 |
914 syn!(Shr) => { BinOp::Shr }
915 ));
916
917 /// ```ignore
918 /// <term> + <term> ...
919 /// <term> - <term> ...
920 /// ```
921 binop!(arith_expr, term_expr, alt!(
922 syn!(Add) => { BinOp::Add }
923 |
924 syn!(Sub) => { BinOp::Sub }
925 ));
926
927 /// ```ignore
928 /// <cast> * <cast> ...
929 /// <cast> / <cast> ...
930 /// <cast> % <cast> ...
931 /// ```
932 binop!(term_expr, cast_expr, alt!(
933 syn!(Star) => { BinOp::Mul }
934 |
935 syn!(Div) => { BinOp::Div }
936 |
937 syn!(Rem) => { BinOp::Rem }
938 ));
939
940 /// ```ignore
941 /// <unary> as <ty>
942 /// <unary> : <ty>
943 /// ```
944 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
945 mut e: call!(unary_expr, allow_struct, allow_block) >>
946 many0!(alt!(
947 do_parse!(
948 as_: syn!(As) >>
949 // We can't accept `A + B` in cast expressions, as it's
950 // ambiguous with the + expression.
951 ty: call!(Ty::without_plus) >>
952 ({
953 e = ExprCast {
954 expr: Box::new(e.into()),
955 as_token: as_,
956 ty: Box::new(ty),
957 }.into();
958 })
959 )
960 |
961 do_parse!(
962 colon: syn!(Colon) >>
963 // We can't accept `A + B` in cast expressions, as it's
964 // ambiguous with the + expression.
965 ty: call!(Ty::without_plus) >>
966 ({
967 e = ExprType {
968 expr: Box::new(e.into()),
969 colon_token: colon,
970 ty: Box::new(ty),
971 }.into();
972 })
973 )
974 )) >>
975 (e)
976 ));
977
978 /// ```
979 /// <UnOp> <trailer>
980 /// & <trailer>
981 /// &mut <trailer>
982 /// box <trailer>
983 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400984 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400985 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
986 do_parse!(
987 op: syn!(UnOp) >>
988 expr: call!(unary_expr, allow_struct, true) >>
989 (ExprUnary {
990 op: op,
991 expr: Box::new(expr.into()),
992 }.into())
993 )
994 |
995 do_parse!(
996 and: syn!(And) >>
997 mutability: syn!(Mutability) >>
998 expr: call!(unary_expr, allow_struct, true) >>
999 (ExprAddrOf {
1000 and_token: and,
1001 mutbl: mutability,
1002 expr: Box::new(expr.into()),
1003 }.into())
1004 )
1005 |
1006 do_parse!(
1007 box_: syn!(Box_) >>
1008 expr: call!(unary_expr, allow_struct, true) >>
1009 (ExprBox {
1010 box_token: box_,
1011 expr: Box::new(expr.into()),
1012 }.into())
1013 )
1014 |
1015 call!(trailer_expr, allow_struct, allow_block)
1016 ));
1017
Michael Layzell734adb42017-06-07 16:58:31 -04001018 // XXX: This duplication is ugly
1019 #[cfg(not(feature = "full"))]
1020 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1021 do_parse!(
1022 op: syn!(UnOp) >>
1023 expr: call!(unary_expr, allow_struct, true) >>
1024 (ExprUnary {
1025 op: op,
1026 expr: Box::new(expr.into()),
1027 }.into())
1028 )
1029 |
1030 call!(trailer_expr, allow_struct, allow_block)
1031 ));
1032
Michael Layzellb78f3b52017-06-04 19:03:03 -04001033 /// ```ignore
1034 /// <atom> (..<args>) ...
1035 /// <atom> . <ident> (..<args>) ...
1036 /// <atom> . <ident> ...
1037 /// <atom> . <lit> ...
1038 /// <atom> [ <expr> ] ...
1039 /// <atom> ? ...
1040 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001041 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001042 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1043 mut e: call!(atom_expr, allow_struct, allow_block) >>
1044 many0!(alt!(
1045 tap!(args: and_call => {
1046 let (args, paren) = args;
1047 e = ExprCall {
1048 func: Box::new(e.into()),
1049 args: args,
1050 paren_token: paren,
1051 }.into();
1052 })
1053 |
1054 tap!(more: and_method_call => {
1055 let mut call = more;
1056 call.expr = Box::new(e.into());
1057 e = call.into();
1058 })
1059 |
1060 tap!(field: and_field => {
1061 let (field, token) = field;
1062 e = ExprField {
1063 expr: Box::new(e.into()),
1064 field: field,
1065 dot_token: token,
1066 }.into();
1067 })
1068 |
1069 tap!(field: and_tup_field => {
1070 let (field, token) = field;
1071 e = ExprTupField {
1072 expr: Box::new(e.into()),
1073 field: field,
1074 dot_token: token,
1075 }.into();
1076 })
1077 |
1078 tap!(i: and_index => {
1079 let (i, token) = i;
1080 e = ExprIndex {
1081 expr: Box::new(e.into()),
1082 bracket_token: token,
1083 index: Box::new(i),
1084 }.into();
1085 })
1086 |
1087 tap!(question: syn!(Question) => {
1088 e = ExprTry {
1089 expr: Box::new(e.into()),
1090 question_token: question,
1091 }.into();
1092 })
1093 )) >>
1094 (e)
1095 ));
1096
Michael Layzell734adb42017-06-07 16:58:31 -04001097 // XXX: Duplication == ugly
1098 #[cfg(not(feature = "full"))]
1099 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1100 mut e: call!(atom_expr, allow_struct, allow_block) >>
1101 many0!(alt!(
1102 tap!(args: and_call => {
1103 let (args, paren) = args;
1104 e = ExprCall {
1105 func: Box::new(e.into()),
1106 args: args,
1107 paren_token: paren,
1108 }.into();
1109 })
1110 |
1111 tap!(i: and_index => {
1112 let (i, token) = i;
1113 e = ExprIndex {
1114 expr: Box::new(e.into()),
1115 bracket_token: token,
1116 index: Box::new(i),
1117 }.into();
1118 })
1119 )) >>
1120 (e)
1121 ));
1122
Michael Layzellb78f3b52017-06-04 19:03:03 -04001123 /// Parse all atomic expressions which don't have to worry about precidence
1124 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001125 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001126 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001127 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1128 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001129 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1130 |
1131 // must be before expr_path
1132 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1133 |
1134 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1135 |
1136 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1137 |
1138 call!(expr_break, allow_struct) // must be before expr_path
1139 |
1140 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1141 |
1142 call!(expr_ret, allow_struct) // must be before expr_path
1143 |
1144 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1145 syn!(ExprInPlace) => { ExprKind::InPlace }
1146 |
1147 syn!(ExprArray) => { ExprKind::Array }
1148 |
1149 syn!(ExprTup) => { ExprKind::Tup }
1150 |
1151 syn!(ExprIf) => { ExprKind::If }
1152 |
1153 syn!(ExprIfLet) => { ExprKind::IfLet }
1154 |
1155 syn!(ExprWhile) => { ExprKind::While }
1156 |
1157 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1158 |
1159 syn!(ExprForLoop) => { ExprKind::ForLoop }
1160 |
1161 syn!(ExprLoop) => { ExprKind::Loop }
1162 |
1163 syn!(ExprMatch) => { ExprKind::Match }
1164 |
1165 syn!(ExprCatch) => { ExprKind::Catch }
1166 |
1167 call!(expr_closure, allow_struct)
1168 |
1169 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1170 |
1171 // NOTE: This is the prefix-form of range
1172 call!(expr_range, allow_struct)
1173 |
1174 syn!(ExprPath) => { ExprKind::Path }
1175 |
1176 syn!(ExprRepeat) => { ExprKind::Repeat }
1177 ));
1178
Michael Layzell734adb42017-06-07 16:58:31 -04001179 #[cfg(not(feature = "full"))]
1180 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1181 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1182 |
1183 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1184 |
1185 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1186 |
1187 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1188 |
1189 syn!(ExprPath) => { ExprKind::Path }
1190 ));
1191
1192
1193 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001194 named!(expr_nosemi -> Expr, map!(alt!(
1195 syn!(ExprIf) => { ExprKind::If }
1196 |
1197 syn!(ExprIfLet) => { ExprKind::IfLet }
1198 |
1199 syn!(ExprWhile) => { ExprKind::While }
1200 |
1201 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1202 |
1203 syn!(ExprForLoop) => { ExprKind::ForLoop }
1204 |
1205 syn!(ExprLoop) => { ExprKind::Loop }
1206 |
1207 syn!(ExprMatch) => { ExprKind::Match }
1208 |
1209 syn!(ExprCatch) => { ExprKind::Catch }
1210 |
1211 syn!(ExprBlock) => { ExprKind::Block }
1212 ), Expr::from));
1213
Michael Layzell93c36282017-06-04 20:43:14 -04001214 impl Synom for ExprGroup {
1215 named!(parse -> Self, do_parse!(
1216 e: grouped!(syn!(Expr)) >>
1217 (ExprGroup {
1218 expr: Box::new(e.0),
1219 group_token: e.1,
1220 }.into())
1221 ));
1222 }
1223
Alex Crichton954046c2017-05-30 21:49:42 -07001224 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001225 named!(parse -> Self, do_parse!(
1226 e: parens!(syn!(Expr)) >>
1227 (ExprParen {
1228 expr: Box::new(e.0),
1229 paren_token: e.1,
1230 }.into())
1231 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001232 }
David Tolnay89e05672016-10-02 14:39:42 -07001233
Michael Layzell734adb42017-06-07 16:58:31 -04001234 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001235 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001236 named!(parse -> Self, do_parse!(
1237 in_: syn!(In) >>
1238 place: expr_no_struct >>
1239 value: braces!(call!(Block::parse_within)) >>
1240 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001241 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001242 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001243 value: Box::new(Expr {
1244 node: ExprBlock {
1245 unsafety: Unsafety::Normal,
1246 block: Block {
1247 stmts: value.0,
1248 brace_token: value.1,
1249 },
1250 }.into(),
1251 attrs: Vec::new(),
1252 }),
1253 })
1254 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001255 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001256
Michael Layzell734adb42017-06-07 16:58:31 -04001257 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001258 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001259 named!(parse -> Self, do_parse!(
1260 elems: brackets!(call!(Delimited::parse_terminated)) >>
1261 (ExprArray {
1262 exprs: elems.0,
1263 bracket_token: elems.1,
1264 })
1265 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001266 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001267
Alex Crichton954046c2017-05-30 21:49:42 -07001268 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1269 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001270
Michael Layzell734adb42017-06-07 16:58:31 -04001271 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001272 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001273 dot: syn!(Dot) >>
1274 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001275 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001276 colon2: syn!(Colon2) >>
1277 lt: syn!(Lt) >>
1278 tys: call!(Delimited::parse_terminated) >>
1279 gt: syn!(Gt) >>
1280 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001281 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001282 args: parens!(call!(Delimited::parse_terminated)) >>
1283 ({
1284 let (colon2, lt, tys, gt) = match typarams {
1285 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1286 None => (None, None, None, None),
1287 };
1288 ExprMethodCall {
1289 // this expr will get overwritten after being returned
1290 expr: Box::new(ExprKind::Lit(Lit {
1291 span: Span::default(),
1292 value: LitKind::Bool(false),
1293 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001294
Alex Crichton954046c2017-05-30 21:49:42 -07001295 method: method,
1296 args: args.0,
1297 paren_token: args.1,
1298 dot_token: dot,
1299 lt_token: lt,
1300 gt_token: gt,
1301 colon2_token: colon2,
1302 typarams: tys.unwrap_or_default(),
1303 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001304 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001305 ));
1306
Michael Layzell734adb42017-06-07 16:58:31 -04001307 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001308 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001309 named!(parse -> Self, do_parse!(
1310 elems: parens!(call!(Delimited::parse_terminated)) >>
1311 (ExprTup {
1312 args: elems.0,
1313 paren_token: elems.1,
1314 lone_comma: None, // TODO: parse this
1315 })
1316 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001317 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001318
Michael Layzell734adb42017-06-07 16:58:31 -04001319 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001320 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001321 named!(parse -> Self, do_parse!(
1322 if_: syn!(If) >>
1323 let_: syn!(Let) >>
1324 pat: syn!(Pat) >>
1325 eq: syn!(Eq) >>
1326 cond: expr_no_struct >>
1327 then_block: braces!(call!(Block::parse_within)) >>
1328 else_block: option!(else_block) >>
1329 (ExprIfLet {
1330 pat: Box::new(pat),
1331 let_token: let_,
1332 eq_token: eq,
1333 expr: Box::new(cond),
1334 if_true: Block {
1335 stmts: then_block.0,
1336 brace_token: then_block.1,
1337 },
1338 if_token: if_,
1339 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1340 if_false: else_block.map(|p| Box::new(p.1.into())),
1341 })
1342 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001343 }
1344
Michael Layzell734adb42017-06-07 16:58:31 -04001345 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001346 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001347 named!(parse -> Self, do_parse!(
1348 if_: syn!(If) >>
1349 cond: expr_no_struct >>
1350 then_block: braces!(call!(Block::parse_within)) >>
1351 else_block: option!(else_block) >>
1352 (ExprIf {
1353 cond: Box::new(cond),
1354 if_true: Block {
1355 stmts: then_block.0,
1356 brace_token: then_block.1,
1357 },
1358 if_token: if_,
1359 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1360 if_false: else_block.map(|p| Box::new(p.1.into())),
1361 })
1362 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001363 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001364
Michael Layzell734adb42017-06-07 16:58:31 -04001365 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001366 named!(else_block -> (Else, ExprKind), do_parse!(
1367 else_: syn!(Else) >>
1368 expr: alt!(
1369 syn!(ExprIf) => { ExprKind::If }
1370 |
1371 syn!(ExprIfLet) => { ExprKind::IfLet }
1372 |
1373 do_parse!(
1374 else_block: braces!(call!(Block::parse_within)) >>
1375 (ExprKind::Block(ExprBlock {
1376 unsafety: Unsafety::Normal,
1377 block: Block {
1378 stmts: else_block.0,
1379 brace_token: else_block.1,
1380 },
1381 }))
David Tolnay939766a2016-09-23 23:48:12 -07001382 )
Alex Crichton954046c2017-05-30 21:49:42 -07001383 ) >>
1384 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001385 ));
1386
David Tolnaybb6feae2016-10-02 21:25:20 -07001387
Michael Layzell734adb42017-06-07 16:58:31 -04001388 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001389 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001390 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001391 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001392 for_: syn!(For) >>
1393 pat: syn!(Pat) >>
1394 in_: syn!(In) >>
1395 expr: expr_no_struct >>
1396 loop_block: syn!(Block) >>
1397 (ExprForLoop {
1398 for_token: for_,
1399 in_token: in_,
1400 pat: Box::new(pat),
1401 expr: Box::new(expr),
1402 body: loop_block,
1403 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1404 label: lbl.map(|p| p.0),
1405 })
1406 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001407 }
Gregory Katze5f35682016-09-27 14:20:55 -04001408
Michael Layzell734adb42017-06-07 16:58:31 -04001409 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001410 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001411 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001412 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001413 loop_: syn!(Loop) >>
1414 loop_block: syn!(Block) >>
1415 (ExprLoop {
1416 loop_token: loop_,
1417 body: loop_block,
1418 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1419 label: lbl.map(|p| p.0),
1420 })
1421 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001422 }
1423
Michael Layzell734adb42017-06-07 16:58:31 -04001424 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001425 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001426 named!(parse -> Self, do_parse!(
1427 match_: syn!(Match) >>
1428 obj: expr_no_struct >>
1429 res: braces!(do_parse!(
1430 mut arms: many0!(do_parse!(
1431 arm: syn!(Arm) >>
1432 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1433 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1434 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001435 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001436 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001437 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001438 arms.extend(last_arm);
1439 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001440 })
Michael Layzell92639a52017-06-01 00:07:44 -04001441 )) >>
1442 ({
1443 let (mut arms, brace) = res;
1444 ExprMatch {
1445 expr: Box::new(obj),
1446 match_token: match_,
1447 brace_token: brace,
1448 arms: {
1449 for arm in &mut arms {
1450 if arm_requires_comma(arm) {
1451 arm.comma = Some(tokens::Comma::default());
1452 }
1453 }
1454 arms
1455 },
1456 }
1457 })
1458 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001459 }
David Tolnay1978c672016-10-27 22:05:52 -07001460
Michael Layzell734adb42017-06-07 16:58:31 -04001461 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001462 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001463 named!(parse -> Self, do_parse!(
1464 do_: syn!(Do) >>
1465 catch_: syn!(Catch) >>
1466 catch_block: syn!(Block) >>
1467 (ExprCatch {
1468 block: catch_block,
1469 do_token: do_,
1470 catch_token: catch_,
1471 }.into())
1472 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001473 }
Arnavion02ef13f2017-04-25 00:54:31 -07001474
Michael Layzell734adb42017-06-07 16:58:31 -04001475 #[cfg(feature = "full")]
David Tolnay1978c672016-10-27 22:05:52 -07001476 fn arm_requires_comma(arm: &Arm) -> bool {
Alex Crichton62a0a592017-05-22 13:58:53 -07001477 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
David Tolnay1978c672016-10-27 22:05:52 -07001478 false
1479 } else {
1480 true
1481 }
1482 }
1483
Michael Layzell734adb42017-06-07 16:58:31 -04001484 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001485 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001486 named!(parse -> Self, do_parse!(
1487 attrs: many0!(call!(Attribute::parse_outer)) >>
1488 pats: call!(Delimited::parse_separated_nonempty) >>
1489 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1490 rocket: syn!(Rocket) >>
1491 body: alt!(
1492 map!(syn!(Block), |blk| {
1493 ExprKind::Block(ExprBlock {
1494 unsafety: Unsafety::Normal,
1495 block: blk,
1496 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001497 })
Michael Layzell92639a52017-06-01 00:07:44 -04001498 |
1499 syn!(Expr)
1500 ) >>
1501 (Arm {
1502 rocket_token: rocket,
1503 if_token: guard.as_ref().map(|p| If((p.0).0)),
1504 attrs: attrs,
1505 pats: pats,
1506 guard: guard.map(|p| Box::new(p.1)),
1507 body: Box::new(body),
1508 comma: None,
1509 })
1510 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001511 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001512
Michael Layzell734adb42017-06-07 16:58:31 -04001513 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001514 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001515 capture: syn!(CaptureBy) >>
1516 or1: syn!(Or) >>
1517 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1518 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001519 ret_and_body: alt!(
1520 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001521 arrow: syn!(RArrow) >>
1522 ty: syn!(Ty) >>
1523 body: syn!(Block) >>
1524 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001525 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001526 unsafety: Unsafety::Normal,
1527 block: body,
1528 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001529 )
1530 |
David Tolnay58af3552016-12-22 16:58:07 -05001531 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001532 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001533 (ExprClosure {
1534 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001535 or1_token: or1,
1536 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001537 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001538 inputs: inputs,
1539 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001540 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001541 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001542 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001543 generics: Generics::default(),
1544 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001545 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001546 body: Box::new(ret_and_body.1),
1547 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001548 ));
1549
Michael Layzell734adb42017-06-07 16:58:31 -04001550 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001551 named!(fn_arg -> FnArg, do_parse!(
1552 pat: syn!(Pat) >>
1553 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1554 ({
1555 let (colon, ty) = ty.unwrap_or_else(|| {
1556 (Colon::default(), TyInfer {
1557 underscore_token: Underscore::default(),
1558 }.into())
1559 });
1560 ArgCaptured {
1561 pat: pat,
1562 colon_token: colon,
1563 ty: ty,
1564 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001565 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001566 ));
1567
Michael Layzell734adb42017-06-07 16:58:31 -04001568 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001569 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001570 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001571 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001572 while_: syn!(While) >>
1573 cond: expr_no_struct >>
1574 while_block: syn!(Block) >>
1575 (ExprWhile {
1576 while_token: while_,
1577 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1578 cond: Box::new(cond),
1579 body: while_block,
1580 label: lbl.map(|p| p.0),
1581 })
1582 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001583 }
1584
Michael Layzell734adb42017-06-07 16:58:31 -04001585 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001586 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001587 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001588 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001589 while_: syn!(While) >>
1590 let_: syn!(Let) >>
1591 pat: syn!(Pat) >>
1592 eq: syn!(Eq) >>
1593 value: expr_no_struct >>
1594 while_block: syn!(Block) >>
1595 (ExprWhileLet {
1596 eq_token: eq,
1597 let_token: let_,
1598 while_token: while_,
1599 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1600 pat: Box::new(pat),
1601 expr: Box::new(value),
1602 body: while_block,
1603 label: lbl.map(|p| p.0),
1604 })
1605 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001606 }
1607
Michael Layzell734adb42017-06-07 16:58:31 -04001608 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001609 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001610 named!(parse -> Self, do_parse!(
1611 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001612 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001613 (ExprContinue {
1614 continue_token: cont,
1615 label: lbl,
1616 })
1617 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001618 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001619
Michael Layzell734adb42017-06-07 16:58:31 -04001620 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001621 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001622 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001623 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001624 // We can't allow blocks after a `break` expression when we wouldn't
1625 // allow structs, as this expression is ambiguous.
1626 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001627 (ExprBreak {
1628 label: lbl,
1629 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001630 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001631 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001632 ));
1633
Michael Layzell734adb42017-06-07 16:58:31 -04001634 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001635 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001636 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001637 // NOTE: return is greedy and eats blocks after it even when in a
1638 // position where structs are not allowed, such as in if statement
1639 // conditions. For example:
1640 //
1641 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001642 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001643 (ExprRet {
1644 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001645 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001646 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001647 ));
1648
Michael Layzell734adb42017-06-07 16:58:31 -04001649 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001650 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001651 named!(parse -> Self, do_parse!(
1652 path: syn!(Path) >>
1653 data: braces!(do_parse!(
1654 fields: call!(Delimited::parse_terminated) >>
1655 base: option!(
1656 cond!(fields.is_empty() || fields.trailing_delim(),
1657 do_parse!(
1658 dots: syn!(Dot2) >>
1659 base: syn!(Expr) >>
1660 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001661 )
Michael Layzell92639a52017-06-01 00:07:44 -04001662 )
1663 ) >>
1664 (fields, base)
1665 )) >>
1666 ({
1667 let ((fields, base), brace) = data;
1668 let (dots, rest) = match base.and_then(|b| b) {
1669 Some((dots, base)) => (Some(dots), Some(base)),
1670 None => (None, None),
1671 };
1672 ExprStruct {
1673 brace_token: brace,
1674 path: path,
1675 fields: fields,
1676 dot2_token: dots,
1677 rest: rest.map(Box::new),
1678 }
1679 })
1680 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001681 }
1682
Michael Layzell734adb42017-06-07 16:58:31 -04001683 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001684 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001685 named!(parse -> Self, alt!(
1686 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001687 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001688 colon: syn!(Colon) >>
1689 value: syn!(Expr) >>
1690 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001691 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001692 expr: value,
1693 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001694 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001695 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001696 })
Michael Layzell92639a52017-06-01 00:07:44 -04001697 )
1698 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001699 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001700 ident: name.clone(),
1701 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1702 is_shorthand: true,
1703 attrs: Vec::new(),
1704 colon_token: None,
1705 })
1706 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001707 }
David Tolnay055a7042016-10-02 19:23:54 -07001708
Michael Layzell734adb42017-06-07 16:58:31 -04001709 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001710 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001711 named!(parse -> Self, do_parse!(
1712 data: brackets!(do_parse!(
1713 value: syn!(Expr) >>
1714 semi: syn!(Semi) >>
1715 times: syn!(Expr) >>
1716 (value, semi, times)
1717 )) >>
1718 (ExprRepeat {
1719 expr: Box::new((data.0).0),
1720 amt: Box::new((data.0).2),
1721 bracket_token: data.1,
1722 semi_token: (data.0).1,
1723 })
1724 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001725 }
David Tolnay055a7042016-10-02 19:23:54 -07001726
Michael Layzell734adb42017-06-07 16:58:31 -04001727 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001728 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001729 named!(parse -> Self, do_parse!(
1730 rules: syn!(Unsafety) >>
1731 b: syn!(Block) >>
1732 (ExprBlock {
1733 unsafety: rules,
1734 block: b,
1735 })
1736 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001737 }
David Tolnay89e05672016-10-02 14:39:42 -07001738
Michael Layzell734adb42017-06-07 16:58:31 -04001739 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001740 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001741 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001742 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001743 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001744 ));
1745
Michael Layzell734adb42017-06-07 16:58:31 -04001746 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001747 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001748 named!(parse -> Self, alt!(
1749 // Must come before Dot2
1750 syn!(Dot3) => { RangeLimits::Closed }
1751 |
1752 syn!(Dot2) => { RangeLimits::HalfOpen }
1753 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001754 }
David Tolnay438c9052016-10-07 23:24:48 -07001755
Alex Crichton954046c2017-05-30 21:49:42 -07001756 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001757 named!(parse -> Self, do_parse!(
1758 pair: qpath >>
1759 (ExprPath {
1760 qself: pair.0,
1761 path: pair.1,
1762 })
1763 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001764 }
David Tolnay42602292016-10-01 22:25:45 -07001765
Michael Layzell734adb42017-06-07 16:58:31 -04001766 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001767 named!(and_field -> (Ident, Dot),
1768 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001769
Michael Layzell734adb42017-06-07 16:58:31 -04001770 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001771 named!(and_tup_field -> (Lit, Dot),
1772 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001773
Alex Crichton954046c2017-05-30 21:49:42 -07001774 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001775
Michael Layzell734adb42017-06-07 16:58:31 -04001776 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001777 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001778 named!(parse -> Self, do_parse!(
1779 stmts: braces!(call!(Block::parse_within)) >>
1780 (Block {
1781 stmts: stmts.0,
1782 brace_token: stmts.1,
1783 })
1784 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001785 }
David Tolnay939766a2016-09-23 23:48:12 -07001786
Michael Layzell734adb42017-06-07 16:58:31 -04001787 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001788 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001789 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1790 many0!(syn!(Semi)) >>
1791 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1792 last: option!(syn!(Expr)) >>
1793 (match last {
1794 None => standalone,
1795 Some(last) => {
1796 standalone.push(Stmt::Expr(Box::new(last)));
1797 standalone
1798 }
1799 })
1800 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001801 }
1802
Michael Layzell734adb42017-06-07 16:58:31 -04001803 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001804 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001805 named!(parse -> Self, alt!(
1806 stmt_mac
1807 |
1808 stmt_local
1809 |
1810 stmt_item
1811 |
Michael Layzell35418782017-06-07 09:20:25 -04001812 stmt_blockexpr
1813 |
Michael Layzell92639a52017-06-01 00:07:44 -04001814 stmt_expr
1815 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001816 }
David Tolnay939766a2016-09-23 23:48:12 -07001817
Michael Layzell734adb42017-06-07 16:58:31 -04001818 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001819 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001820 attrs: many0!(call!(Attribute::parse_outer)) >>
1821 what: syn!(Path) >>
1822 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001823 // Only parse braces here; paren and bracket will get parsed as
1824 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001825 data: braces!(syn!(TokenStream)) >>
1826 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001827 (Stmt::Mac(Box::new((
1828 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001829 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001830 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001831 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001832 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001833 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001834 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001835 })],
1836 },
Alex Crichton954046c2017-05-30 21:49:42 -07001837 match semi {
1838 Some(semi) => MacStmtStyle::Semicolon(semi),
1839 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001840 },
David Tolnayeea28d62016-10-25 20:44:08 -07001841 attrs,
1842 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001843 ));
1844
Michael Layzell734adb42017-06-07 16:58:31 -04001845 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001846 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001847 attrs: many0!(call!(Attribute::parse_outer)) >>
1848 let_: syn!(Let) >>
1849 pat: syn!(Pat) >>
1850 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1851 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1852 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001853 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001854 let_token: let_,
1855 semi_token: semi,
1856 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1857 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001858 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001859 ty: ty.map(|p| Box::new(p.1)),
1860 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001861 attrs: attrs,
1862 })))
1863 ));
1864
Michael Layzell734adb42017-06-07 16:58:31 -04001865 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001866 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001867
Michael Layzell734adb42017-06-07 16:58:31 -04001868 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001869 named!(stmt_blockexpr -> Stmt, do_parse!(
1870 attrs: many0!(call!(Attribute::parse_outer)) >>
1871 mut e: expr_nosemi >>
1872 // If the next token is a `.` or a `?` it is special-cased to parse as
1873 // an expression instead of a blockexpression.
1874 not!(syn!(Dot)) >>
1875 not!(syn!(Question)) >>
1876 semi: option!(syn!(Semi)) >>
1877 ({
1878 e.attrs = attrs;
1879 if let Some(semi) = semi {
1880 Stmt::Semi(Box::new(e), semi)
1881 } else {
1882 Stmt::Expr(Box::new(e))
1883 }
1884 })
1885 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001886
Michael Layzell734adb42017-06-07 16:58:31 -04001887 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001888 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001889 attrs: many0!(call!(Attribute::parse_outer)) >>
1890 mut e: syn!(Expr) >>
Michael Layzell35418782017-06-07 09:20:25 -04001891 semi: syn!(Semi) >>
David Tolnay7184b132016-10-30 10:06:37 -07001892 ({
1893 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001894 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001895 })
David Tolnay939766a2016-09-23 23:48:12 -07001896 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001897
Michael Layzell734adb42017-06-07 16:58:31 -04001898 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001899 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001900 named!(parse -> Self, alt!(
1901 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1902 |
1903 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1904 |
1905 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1906 |
1907 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1908 |
1909 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1910 |
1911 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1912 |
1913 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1914 |
1915 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1916 |
1917 syn!(PatPath) => { Pat::Path }
1918 |
1919 syn!(PatTuple) => { Pat::Tuple }
1920 |
1921 syn!(PatRef) => { Pat::Ref }
1922 |
1923 syn!(PatSlice) => { Pat::Slice }
1924 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001925 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001926
Michael Layzell734adb42017-06-07 16:58:31 -04001927 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001928 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001929 named!(parse -> Self, map!(
1930 syn!(Underscore),
1931 |u| PatWild { underscore_token: u }
1932 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001933 }
David Tolnay84aa0752016-10-02 23:01:13 -07001934
Michael Layzell734adb42017-06-07 16:58:31 -04001935 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001936 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001937 named!(parse -> Self, do_parse!(
1938 boxed: syn!(Box_) >>
1939 pat: syn!(Pat) >>
1940 (PatBox {
1941 pat: Box::new(pat),
1942 box_token: boxed,
1943 })
1944 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001945 }
1946
Michael Layzell734adb42017-06-07 16:58:31 -04001947 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001948 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001949 named!(parse -> Self, do_parse!(
1950 mode: option!(syn!(Ref)) >>
1951 mutability: syn!(Mutability) >>
1952 name: alt!(
1953 syn!(Ident)
1954 |
1955 syn!(Self_) => { Into::into }
1956 ) >>
1957 not!(syn!(Lt)) >>
1958 not!(syn!(Colon2)) >>
1959 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1960 (PatIdent {
1961 mode: match mode {
1962 Some(mode) => BindingMode::ByRef(mode, mutability),
1963 None => BindingMode::ByValue(mutability),
1964 },
1965 ident: name,
1966 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1967 subpat: subpat.map(|p| Box::new(p.1)),
1968 })
1969 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001970 }
1971
Michael Layzell734adb42017-06-07 16:58:31 -04001972 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001973 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001974 named!(parse -> Self, do_parse!(
1975 path: syn!(Path) >>
1976 tuple: syn!(PatTuple) >>
1977 (PatTupleStruct {
1978 path: path,
1979 pat: tuple,
1980 })
1981 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001982 }
1983
Michael Layzell734adb42017-06-07 16:58:31 -04001984 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001985 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001986 named!(parse -> Self, do_parse!(
1987 path: syn!(Path) >>
1988 data: braces!(do_parse!(
1989 fields: call!(Delimited::parse_terminated) >>
1990 base: option!(
1991 cond!(fields.is_empty() || fields.trailing_delim(),
1992 syn!(Dot2))
1993 ) >>
1994 (fields, base)
1995 )) >>
1996 (PatStruct {
1997 path: path,
1998 fields: (data.0).0,
1999 brace_token: data.1,
2000 dot2_token: (data.0).1.and_then(|m| m),
2001 })
2002 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002003 }
2004
Michael Layzell734adb42017-06-07 16:58:31 -04002005 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002006 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002007 named!(parse -> Self, alt!(
2008 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002009 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04002010 colon: syn!(Colon) >>
2011 pat: syn!(Pat) >>
2012 (FieldPat {
2013 ident: ident,
2014 pat: Box::new(pat),
2015 is_shorthand: false,
2016 attrs: Vec::new(),
2017 colon_token: Some(colon),
2018 })
2019 )
2020 |
2021 do_parse!(
2022 boxed: option!(syn!(Box_)) >>
2023 mode: option!(syn!(Ref)) >>
2024 mutability: syn!(Mutability) >>
2025 ident: syn!(Ident) >>
2026 ({
2027 let mut pat: Pat = PatIdent {
2028 mode: if let Some(mode) = mode {
2029 BindingMode::ByRef(mode, mutability)
2030 } else {
2031 BindingMode::ByValue(mutability)
2032 },
2033 ident: ident.clone(),
2034 subpat: None,
2035 at_token: None,
2036 }.into();
2037 if let Some(boxed) = boxed {
2038 pat = PatBox {
2039 pat: Box::new(pat),
2040 box_token: boxed,
2041 }.into();
2042 }
2043 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002044 ident: ident,
2045 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002046 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002047 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002048 colon_token: None,
2049 }
2050 })
2051 )
2052 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002053 }
2054
Michael Layzell734adb42017-06-07 16:58:31 -04002055 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002056 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002057 syn!(Ident)
2058 |
2059 do_parse!(
2060 lit: syn!(Lit) >>
2061 ({
David Tolnay570695e2017-06-03 16:15:13 -07002062 let s = lit.to_string();
2063 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002064 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002065 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002066 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002067 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002068 })
2069 )
2070 ));
2071
Michael Layzell734adb42017-06-07 16:58:31 -04002072 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002073 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002074 named!(parse -> Self, map!(
2075 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002076 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002077 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002078 }
David Tolnay9636c052016-10-02 17:11:17 -07002079
Michael Layzell734adb42017-06-07 16:58:31 -04002080 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002081 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002082 named!(parse -> Self, do_parse!(
2083 data: parens!(do_parse!(
2084 elems: call!(Delimited::parse_terminated) >>
2085 dotdot: map!(cond!(
2086 elems.is_empty() || elems.trailing_delim(),
2087 option!(do_parse!(
2088 dots: syn!(Dot2) >>
2089 trailing: option!(syn!(Comma)) >>
2090 (dots, trailing)
2091 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002092 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002093 rest: cond!(match dotdot {
2094 Some((_, Some(_))) => true,
2095 _ => false,
2096 },
2097 call!(Delimited::parse_terminated)) >>
2098 (elems, dotdot, rest)
2099 )) >>
2100 ({
2101 let ((mut elems, dotdot, rest), parens) = data;
2102 let (dotdot, trailing) = match dotdot {
2103 Some((a, b)) => (Some(a), Some(b)),
2104 None => (None, None),
2105 };
2106 PatTuple {
2107 paren_token: parens,
2108 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2109 dot2_token: dotdot,
2110 comma_token: trailing.and_then(|b| b),
2111 pats: {
2112 if let Some(rest) = rest {
2113 for elem in rest {
2114 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002115 }
Michael Layzell92639a52017-06-01 00:07:44 -04002116 }
2117 elems
2118 },
2119 }
2120 })
2121 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002122 }
David Tolnayfbb73232016-10-03 01:00:06 -07002123
Michael Layzell734adb42017-06-07 16:58:31 -04002124 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002125 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002126 named!(parse -> Self, do_parse!(
2127 and: syn!(And) >>
2128 mutability: syn!(Mutability) >>
2129 pat: syn!(Pat) >>
2130 (PatRef {
2131 pat: Box::new(pat),
2132 mutbl: mutability,
2133 and_token: and,
2134 })
2135 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002136 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002137
Michael Layzell734adb42017-06-07 16:58:31 -04002138 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002139 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002140 named!(parse -> Self, do_parse!(
2141 lit: pat_lit_expr >>
2142 (if let ExprKind::Path(_) = lit.node {
2143 return parse_error(); // these need to be parsed by pat_path
2144 } else {
2145 PatLit {
2146 expr: Box::new(lit),
2147 }
2148 })
2149 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002150 }
David Tolnaye1310902016-10-29 23:40:00 -07002151
Michael Layzell734adb42017-06-07 16:58:31 -04002152 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002153 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002154 named!(parse -> Self, do_parse!(
2155 lo: pat_lit_expr >>
2156 limits: syn!(RangeLimits) >>
2157 hi: pat_lit_expr >>
2158 (PatRange {
2159 lo: Box::new(lo),
2160 hi: Box::new(hi),
2161 limits: limits,
2162 })
2163 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002164 }
David Tolnaye1310902016-10-29 23:40:00 -07002165
Michael Layzell734adb42017-06-07 16:58:31 -04002166 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002167 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002168 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002169 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002170 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002171 |
Alex Crichton954046c2017-05-30 21:49:42 -07002172 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002173 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002174 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002175 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002176 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002177 expr: Box::new(v.into())
2178 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002179 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002180 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002181 })
2182 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002183
Michael Layzell734adb42017-06-07 16:58:31 -04002184 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002185 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002186 named!(parse -> Self, map!(
2187 brackets!(do_parse!(
2188 before: call!(Delimited::parse_terminated) >>
2189 middle: option!(do_parse!(
2190 dots: syn!(Dot2) >>
2191 trailing: option!(syn!(Comma)) >>
2192 (dots, trailing)
2193 )) >>
2194 after: cond!(
2195 match middle {
2196 Some((_, ref trailing)) => trailing.is_some(),
2197 _ => false,
2198 },
2199 call!(Delimited::parse_terminated)
2200 ) >>
2201 (before, middle, after)
2202 )),
2203 |((before, middle, after), brackets)| {
2204 let mut before: Delimited<Pat, tokens::Comma> = before;
2205 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2206 let middle: Option<(Dot2, Option<Comma>)> = middle;
2207 PatSlice {
2208 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2209 comma_token: middle.as_ref().and_then(|m| {
2210 m.1.as_ref().map(|m| Comma(m.0))
2211 }),
2212 bracket_token: brackets,
2213 middle: middle.and_then(|_| {
2214 if !before.is_empty() && !before.trailing_delim() {
2215 Some(Box::new(before.pop().unwrap().into_item()))
2216 } else {
2217 None
2218 }
2219 }),
2220 front: before,
2221 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002222 }
Alex Crichton954046c2017-05-30 21:49:42 -07002223 }
Michael Layzell92639a52017-06-01 00:07:44 -04002224 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002225 }
David Tolnay435a9a82016-10-29 13:47:20 -07002226
Michael Layzell734adb42017-06-07 16:58:31 -04002227 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002228 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002229 named!(parse -> Self, alt!(
2230 syn!(Move) => { CaptureBy::Value }
2231 |
2232 epsilon!() => { |_| CaptureBy::Ref }
2233 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002234 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002235}
2236
David Tolnayf4bbbd92016-09-23 14:41:55 -07002237#[cfg(feature = "printing")]
2238mod printing {
2239 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002240 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002241 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002242 use quote::{Tokens, ToTokens};
2243
2244 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002245 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002246 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002247 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002248 self.node.to_tokens(tokens)
2249 }
Michael Layzell734adb42017-06-07 16:58:31 -04002250
2251 #[cfg(not(feature = "full"))]
2252 fn to_tokens(&self, tokens: &mut Tokens) {
2253 self.node.to_tokens(tokens)
2254 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002255 }
2256
Michael Layzell734adb42017-06-07 16:58:31 -04002257 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002258 impl ToTokens for ExprBox {
2259 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002260 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002261 self.expr.to_tokens(tokens);
2262 }
2263 }
2264
Michael Layzell734adb42017-06-07 16:58:31 -04002265 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002266 impl ToTokens for ExprInPlace {
2267 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002268 match self.kind {
2269 InPlaceKind::Arrow(ref arrow) => {
2270 self.place.to_tokens(tokens);
2271 arrow.to_tokens(tokens);
2272 self.value.to_tokens(tokens);
2273 }
2274 InPlaceKind::In(ref _in) => {
2275 _in.to_tokens(tokens);
2276 self.place.to_tokens(tokens);
2277 self.value.to_tokens(tokens);
2278 }
2279 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002280 }
2281 }
2282
Michael Layzell734adb42017-06-07 16:58:31 -04002283 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002284 impl ToTokens for ExprArray {
2285 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002286 self.bracket_token.surround(tokens, |tokens| {
2287 self.exprs.to_tokens(tokens);
2288 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002289 }
2290 }
2291
2292 impl ToTokens for ExprCall {
2293 fn to_tokens(&self, tokens: &mut Tokens) {
2294 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002295 self.paren_token.surround(tokens, |tokens| {
2296 self.args.to_tokens(tokens);
2297 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002298 }
2299 }
2300
Michael Layzell734adb42017-06-07 16:58:31 -04002301 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002302 impl ToTokens for ExprMethodCall {
2303 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002304 self.expr.to_tokens(tokens);
2305 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002306 self.method.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002307 self.colon2_token.to_tokens(tokens);
2308 self.lt_token.to_tokens(tokens);
2309 self.typarams.to_tokens(tokens);
2310 self.gt_token.to_tokens(tokens);
2311 self.paren_token.surround(tokens, |tokens| {
2312 self.args.to_tokens(tokens);
2313 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002314 }
2315 }
2316
Michael Layzell734adb42017-06-07 16:58:31 -04002317 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002318 impl ToTokens for ExprTup {
2319 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002320 self.paren_token.surround(tokens, |tokens| {
2321 self.args.to_tokens(tokens);
2322 self.lone_comma.to_tokens(tokens);
2323 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002324 }
2325 }
2326
2327 impl ToTokens for ExprBinary {
2328 fn to_tokens(&self, tokens: &mut Tokens) {
2329 self.left.to_tokens(tokens);
2330 self.op.to_tokens(tokens);
2331 self.right.to_tokens(tokens);
2332 }
2333 }
2334
2335 impl ToTokens for ExprUnary {
2336 fn to_tokens(&self, tokens: &mut Tokens) {
2337 self.op.to_tokens(tokens);
2338 self.expr.to_tokens(tokens);
2339 }
2340 }
2341
2342 impl ToTokens for ExprCast {
2343 fn to_tokens(&self, tokens: &mut Tokens) {
2344 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002345 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002346 self.ty.to_tokens(tokens);
2347 }
2348 }
2349
2350 impl ToTokens for ExprType {
2351 fn to_tokens(&self, tokens: &mut Tokens) {
2352 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002353 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002354 self.ty.to_tokens(tokens);
2355 }
2356 }
2357
Michael Layzell734adb42017-06-07 16:58:31 -04002358 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002359 impl ToTokens for ExprIf {
2360 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002361 self.if_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002362 self.cond.to_tokens(tokens);
2363 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002364 self.else_token.to_tokens(tokens);
2365 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002366 }
2367 }
2368
Michael Layzell734adb42017-06-07 16:58:31 -04002369 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002370 impl ToTokens for ExprIfLet {
2371 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002372 self.if_token.to_tokens(tokens);
2373 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002374 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002375 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002376 self.expr.to_tokens(tokens);
2377 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002378 self.else_token.to_tokens(tokens);
2379 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002380 }
2381 }
2382
Michael Layzell734adb42017-06-07 16:58:31 -04002383 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002384 impl ToTokens for ExprWhile {
2385 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002386 self.label.to_tokens(tokens);
2387 self.colon_token.to_tokens(tokens);
2388 self.while_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002389 self.cond.to_tokens(tokens);
2390 self.body.to_tokens(tokens);
2391 }
2392 }
2393
Michael Layzell734adb42017-06-07 16:58:31 -04002394 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002395 impl ToTokens for ExprWhileLet {
2396 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002397 self.label.to_tokens(tokens);
2398 self.colon_token.to_tokens(tokens);
2399 self.while_token.to_tokens(tokens);
2400 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002401 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002402 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002403 self.expr.to_tokens(tokens);
2404 self.body.to_tokens(tokens);
2405 }
2406 }
2407
Michael Layzell734adb42017-06-07 16:58:31 -04002408 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002409 impl ToTokens for ExprForLoop {
2410 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002411 self.label.to_tokens(tokens);
2412 self.colon_token.to_tokens(tokens);
2413 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002414 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002415 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002416 self.expr.to_tokens(tokens);
2417 self.body.to_tokens(tokens);
2418 }
2419 }
2420
Michael Layzell734adb42017-06-07 16:58:31 -04002421 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002422 impl ToTokens for ExprLoop {
2423 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002424 self.label.to_tokens(tokens);
2425 self.colon_token.to_tokens(tokens);
2426 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002427 self.body.to_tokens(tokens);
2428 }
2429 }
2430
Michael Layzell734adb42017-06-07 16:58:31 -04002431 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002432 impl ToTokens for ExprMatch {
2433 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002434 self.match_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002435 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002436 self.brace_token.surround(tokens, |tokens| {
2437 tokens.append_all(&self.arms);
2438 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002439 }
2440 }
2441
Michael Layzell734adb42017-06-07 16:58:31 -04002442 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002443 impl ToTokens for ExprCatch {
2444 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002445 self.do_token.to_tokens(tokens);
2446 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002447 self.block.to_tokens(tokens);
2448 }
2449 }
2450
Michael Layzell734adb42017-06-07 16:58:31 -04002451 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002452 impl ToTokens for ExprClosure {
2453 fn to_tokens(&self, tokens: &mut Tokens) {
2454 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002455 self.or1_token.to_tokens(tokens);
2456 for item in self.decl.inputs.iter() {
2457 match **item.item() {
2458 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002459 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002460 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002461 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002462 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002463 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002464 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002465 self.or2_token.to_tokens(tokens);
2466 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 self.body.to_tokens(tokens);
2468 }
2469 }
2470
Michael Layzell734adb42017-06-07 16:58:31 -04002471 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002472 impl ToTokens for ExprBlock {
2473 fn to_tokens(&self, tokens: &mut Tokens) {
2474 self.unsafety.to_tokens(tokens);
2475 self.block.to_tokens(tokens);
2476 }
2477 }
2478
Michael Layzell734adb42017-06-07 16:58:31 -04002479 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002480 impl ToTokens for ExprAssign {
2481 fn to_tokens(&self, tokens: &mut Tokens) {
2482 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002483 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002484 self.right.to_tokens(tokens);
2485 }
2486 }
2487
Michael Layzell734adb42017-06-07 16:58:31 -04002488 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002489 impl ToTokens for ExprAssignOp {
2490 fn to_tokens(&self, tokens: &mut Tokens) {
2491 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002492 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002493 self.right.to_tokens(tokens);
2494 }
2495 }
2496
Michael Layzell734adb42017-06-07 16:58:31 -04002497 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002498 impl ToTokens for ExprField {
2499 fn to_tokens(&self, tokens: &mut Tokens) {
2500 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002501 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002502 self.field.to_tokens(tokens);
2503 }
2504 }
2505
Michael Layzell734adb42017-06-07 16:58:31 -04002506 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002507 impl ToTokens for ExprTupField {
2508 fn to_tokens(&self, tokens: &mut Tokens) {
2509 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002510 self.dot_token.to_tokens(tokens);
2511 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002512 }
2513 }
2514
2515 impl ToTokens for ExprIndex {
2516 fn to_tokens(&self, tokens: &mut Tokens) {
2517 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002518 self.bracket_token.surround(tokens, |tokens| {
2519 self.index.to_tokens(tokens);
2520 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002521 }
2522 }
2523
Michael Layzell734adb42017-06-07 16:58:31 -04002524 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002525 impl ToTokens for ExprRange {
2526 fn to_tokens(&self, tokens: &mut Tokens) {
2527 self.from.to_tokens(tokens);
2528 self.limits.to_tokens(tokens);
2529 self.to.to_tokens(tokens);
2530 }
2531 }
2532
2533 impl ToTokens for ExprPath {
2534 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002535 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002536 }
2537 }
2538
Michael Layzell734adb42017-06-07 16:58:31 -04002539 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002540 impl ToTokens for ExprAddrOf {
2541 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002542 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002543 self.mutbl.to_tokens(tokens);
2544 self.expr.to_tokens(tokens);
2545 }
2546 }
2547
Michael Layzell734adb42017-06-07 16:58:31 -04002548 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002549 impl ToTokens for ExprBreak {
2550 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002551 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002552 self.label.to_tokens(tokens);
2553 self.expr.to_tokens(tokens);
2554 }
2555 }
2556
Michael Layzell734adb42017-06-07 16:58:31 -04002557 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 impl ToTokens for ExprContinue {
2559 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002560 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002561 self.label.to_tokens(tokens);
2562 }
2563 }
2564
Michael Layzell734adb42017-06-07 16:58:31 -04002565 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002566 impl ToTokens for ExprRet {
2567 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002568 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002569 self.expr.to_tokens(tokens);
2570 }
2571 }
2572
Michael Layzell734adb42017-06-07 16:58:31 -04002573 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002574 impl ToTokens for ExprStruct {
2575 fn to_tokens(&self, tokens: &mut Tokens) {
2576 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002577 self.brace_token.surround(tokens, |tokens| {
2578 self.fields.to_tokens(tokens);
2579 self.dot2_token.to_tokens(tokens);
2580 self.rest.to_tokens(tokens);
2581 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002582 }
2583 }
2584
Michael Layzell734adb42017-06-07 16:58:31 -04002585 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002586 impl ToTokens for ExprRepeat {
2587 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002588 self.bracket_token.surround(tokens, |tokens| {
2589 self.expr.to_tokens(tokens);
2590 self.semi_token.to_tokens(tokens);
2591 self.amt.to_tokens(tokens);
2592 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002593 }
2594 }
2595
Michael Layzell93c36282017-06-04 20:43:14 -04002596 impl ToTokens for ExprGroup {
2597 fn to_tokens(&self, tokens: &mut Tokens) {
2598 self.group_token.surround(tokens, |tokens| {
2599 self.expr.to_tokens(tokens);
2600 });
2601 }
2602 }
2603
Alex Crichton62a0a592017-05-22 13:58:53 -07002604 impl ToTokens for ExprParen {
2605 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002606 self.paren_token.surround(tokens, |tokens| {
2607 self.expr.to_tokens(tokens);
2608 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002609 }
2610 }
2611
Michael Layzell734adb42017-06-07 16:58:31 -04002612 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 impl ToTokens for ExprTry {
2614 fn to_tokens(&self, tokens: &mut Tokens) {
2615 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002616 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002617 }
2618 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002619
Michael Layzell734adb42017-06-07 16:58:31 -04002620 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002621 impl ToTokens for FieldValue {
2622 fn to_tokens(&self, tokens: &mut Tokens) {
2623 self.ident.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002624 if !self.is_shorthand {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002625 self.colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002626 self.expr.to_tokens(tokens);
2627 }
David Tolnay055a7042016-10-02 19:23:54 -07002628 }
2629 }
2630
Michael Layzell734adb42017-06-07 16:58:31 -04002631 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002632 impl ToTokens for Arm {
2633 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002634 tokens.append_all(&self.attrs);
2635 self.pats.to_tokens(tokens);
2636 self.if_token.to_tokens(tokens);
2637 self.guard.to_tokens(tokens);
2638 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002639 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002640 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002641 }
2642 }
2643
Michael Layzell734adb42017-06-07 16:58:31 -04002644 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002645 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002646 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002647 self.underscore_token.to_tokens(tokens);
2648 }
2649 }
2650
Michael Layzell734adb42017-06-07 16:58:31 -04002651 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002652 impl ToTokens for PatIdent {
2653 fn to_tokens(&self, tokens: &mut Tokens) {
2654 self.mode.to_tokens(tokens);
2655 self.ident.to_tokens(tokens);
2656 self.at_token.to_tokens(tokens);
2657 self.subpat.to_tokens(tokens);
2658 }
2659 }
2660
Michael Layzell734adb42017-06-07 16:58:31 -04002661 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002662 impl ToTokens for PatStruct {
2663 fn to_tokens(&self, tokens: &mut Tokens) {
2664 self.path.to_tokens(tokens);
2665 self.brace_token.surround(tokens, |tokens| {
2666 self.fields.to_tokens(tokens);
2667 self.dot2_token.to_tokens(tokens);
2668 });
2669 }
2670 }
2671
Michael Layzell734adb42017-06-07 16:58:31 -04002672 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002673 impl ToTokens for PatTupleStruct {
2674 fn to_tokens(&self, tokens: &mut Tokens) {
2675 self.path.to_tokens(tokens);
2676 self.pat.to_tokens(tokens);
2677 }
2678 }
2679
Michael Layzell734adb42017-06-07 16:58:31 -04002680 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002681 impl ToTokens for PatPath {
2682 fn to_tokens(&self, tokens: &mut Tokens) {
2683 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2684 }
2685 }
2686
Michael Layzell734adb42017-06-07 16:58:31 -04002687 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002688 impl ToTokens for PatTuple {
2689 fn to_tokens(&self, tokens: &mut Tokens) {
2690 self.paren_token.surround(tokens, |tokens| {
2691 for (i, token) in self.pats.iter().enumerate() {
2692 if Some(i) == self.dots_pos {
2693 self.dot2_token.to_tokens(tokens);
2694 self.comma_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002695 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002696 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002697 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002698
2699 if Some(self.pats.len()) == self.dots_pos {
2700 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002701 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002702 });
2703 }
2704 }
2705
Michael Layzell734adb42017-06-07 16:58:31 -04002706 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002707 impl ToTokens for PatBox {
2708 fn to_tokens(&self, tokens: &mut Tokens) {
2709 self.box_token.to_tokens(tokens);
2710 self.pat.to_tokens(tokens);
2711 }
2712 }
2713
Michael Layzell734adb42017-06-07 16:58:31 -04002714 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002715 impl ToTokens for PatRef {
2716 fn to_tokens(&self, tokens: &mut Tokens) {
2717 self.and_token.to_tokens(tokens);
2718 self.mutbl.to_tokens(tokens);
2719 self.pat.to_tokens(tokens);
2720 }
2721 }
2722
Michael Layzell734adb42017-06-07 16:58:31 -04002723 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002724 impl ToTokens for PatLit {
2725 fn to_tokens(&self, tokens: &mut Tokens) {
2726 self.expr.to_tokens(tokens);
2727 }
2728 }
2729
Michael Layzell734adb42017-06-07 16:58:31 -04002730 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002731 impl ToTokens for PatRange {
2732 fn to_tokens(&self, tokens: &mut Tokens) {
2733 self.lo.to_tokens(tokens);
2734 self.limits.to_tokens(tokens);
2735 self.hi.to_tokens(tokens);
2736 }
2737 }
2738
Michael Layzell734adb42017-06-07 16:58:31 -04002739 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002740 impl ToTokens for PatSlice {
2741 fn to_tokens(&self, tokens: &mut Tokens) {
2742 self.bracket_token.surround(tokens, |tokens| {
2743 self.front.to_tokens(tokens);
2744 self.middle.to_tokens(tokens);
2745 self.dot2_token.to_tokens(tokens);
2746 self.comma_token.to_tokens(tokens);
2747 self.back.to_tokens(tokens);
2748 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002749 }
2750 }
2751
Michael Layzell734adb42017-06-07 16:58:31 -04002752 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002753 impl ToTokens for RangeLimits {
2754 fn to_tokens(&self, tokens: &mut Tokens) {
2755 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002756 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2757 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002758 }
2759 }
2760 }
2761
Michael Layzell734adb42017-06-07 16:58:31 -04002762 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002763 impl ToTokens for FieldPat {
2764 fn to_tokens(&self, tokens: &mut Tokens) {
2765 if !self.is_shorthand {
2766 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002767 self.colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002768 }
2769 self.pat.to_tokens(tokens);
2770 }
2771 }
2772
Michael Layzell734adb42017-06-07 16:58:31 -04002773 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002774 impl ToTokens for BindingMode {
2775 fn to_tokens(&self, tokens: &mut Tokens) {
2776 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002777 BindingMode::ByRef(ref t, ref m) => {
2778 t.to_tokens(tokens);
2779 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002780 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002781 BindingMode::ByValue(ref m) => {
2782 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002783 }
2784 }
2785 }
2786 }
David Tolnay42602292016-10-01 22:25:45 -07002787
Michael Layzell734adb42017-06-07 16:58:31 -04002788 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002789 impl ToTokens for CaptureBy {
2790 fn to_tokens(&self, tokens: &mut Tokens) {
2791 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002792 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002793 CaptureBy::Ref => {
2794 // nothing
2795 }
David Tolnay89e05672016-10-02 14:39:42 -07002796 }
2797 }
2798 }
2799
Michael Layzell734adb42017-06-07 16:58:31 -04002800 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002801 impl ToTokens for Block {
2802 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002803 self.brace_token.surround(tokens, |tokens| {
2804 tokens.append_all(&self.stmts);
2805 });
David Tolnay42602292016-10-01 22:25:45 -07002806 }
2807 }
2808
Michael Layzell734adb42017-06-07 16:58:31 -04002809 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002810 impl ToTokens for Stmt {
2811 fn to_tokens(&self, tokens: &mut Tokens) {
2812 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002813 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002814 Stmt::Item(ref item) => item.to_tokens(tokens),
2815 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002816 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002817 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002818 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002819 }
David Tolnay13b3d352016-10-03 00:31:15 -07002820 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002821 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002822 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002823 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002824 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002825 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002826 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2827 // no semicolon
2828 }
David Tolnay13b3d352016-10-03 00:31:15 -07002829 }
2830 }
David Tolnay42602292016-10-01 22:25:45 -07002831 }
2832 }
2833 }
David Tolnay191e0582016-10-02 18:31:09 -07002834
Michael Layzell734adb42017-06-07 16:58:31 -04002835 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002836 impl ToTokens for Local {
2837 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002838 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002839 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002840 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002841 self.colon_token.to_tokens(tokens);
2842 self.ty.to_tokens(tokens);
2843 self.eq_token.to_tokens(tokens);
2844 self.init.to_tokens(tokens);
2845 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002846 }
2847 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002848}