blob: db3fb558b9df5c7545a5479a52acba0281d04710 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
Alex Crichton954046c2017-05-30 21:49:42 -070029 pub box_token: tokens::Box_,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub exprs: Delimited<Expr, tokens::Comma>,
42 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 pub args: Delimited<Expr, tokens::Comma>,
49 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
55 /// The vector of `Ty`s are the ascripted type parameters for the method
56 /// (within the angle brackets).
57 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
59 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070063 pub typarams: Delimited<Ty, tokens::Comma>,
64 pub args: Delimited<Expr, tokens::Comma>,
65 pub paren_token: tokens::Paren,
66 pub dot_token: tokens::Dot,
67 pub lt_token: Option<tokens::Lt>,
68 pub colon2_token: Option<tokens::Colon2>,
69 pub gt_token: Option<tokens::Gt>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
Michael Layzell734adb42017-06-07 16:58:31 -040073 pub Tup(ExprTup #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070074 pub args: Delimited<Expr, tokens::Comma>,
75 pub paren_token: tokens::Paren,
76 pub lone_comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070098 pub as_token: tokens::As,
Alex Crichton62a0a592017-05-22 13:58:53 -070099 pub ty: Box<Ty>,
100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// A type ascription, e.g. `foo: f64`.
103 pub Type(ExprType {
104 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 pub ty: Box<Ty>,
107 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500108
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 /// An `if` block, with an optional else block
110 ///
111 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 pub if_token: tokens::If,
117 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700130 pub if_token: tokens::If,
131 pub let_token: tokens::Let,
132 pub eq_token: tokens::Eq,
133 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 pub colon_token: Option<tokens::Colon>,
144 pub while_token: tokens::While,
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700157 pub colon_token: Option<tokens::Colon>,
158 pub while_token: tokens::While,
159 pub let_token: tokens::Let,
160 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700173 pub for_token: tokens::For,
174 pub colon_token: Option<tokens::Colon>,
175 pub in_token: tokens::In,
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700184 pub loop_token: tokens::Loop,
185 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 pub match_token: tokens::Match,
191 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201 pub or1_token: tokens::Or,
202 pub or2_token: tokens::Or,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// A block (`{ ... }` or `unsafe { ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400206 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 pub unsafety: Unsafety,
208 pub block: Block,
209 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700210
Alex Crichton62a0a592017-05-22 13:58:53 -0700211 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700215 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500217
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 /// An assignment with an operator
219 ///
220 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub op: BinOp,
223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// Access of a named struct field (`obj.foo`)
Michael Layzell734adb42017-06-07 16:58:31 -0400228 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 pub expr: Box<Expr>,
230 pub field: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500233
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 /// Access of an unnamed field of a struct or tuple-struct
235 ///
236 /// For example, `foo.0`.
Michael Layzell734adb42017-06-07 16:58:31 -0400237 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700239 pub field: Lit,
240 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500242
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 /// An indexing operation (`foo[2]`)
244 pub Index(ExprIndex {
245 pub expr: Box<Expr>,
246 pub index: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500249
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400251 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 pub from: Option<Box<Expr>>,
253 pub to: Option<Box<Expr>>,
254 pub limits: RangeLimits,
255 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700256
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 /// Variable reference, possibly containing `::` and/or type
258 /// parameters, e.g. foo::bar::<baz>.
259 ///
260 /// Optionally "qualified",
261 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
262 pub Path(ExprPath {
263 pub qself: Option<QSelf>,
264 pub path: Path,
265 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700266
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400268 pub AddrOf(ExprAddrOf #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 pub and_token: tokens::And,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub mutbl: Mutability,
271 pub expr: Box<Expr>,
272 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500273
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400275 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700276 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700278 pub break_token: tokens::Break,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500280
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400282 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700283 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 pub continue_token: tokens::Continue,
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500286
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400288 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 pub return_token: tokens::Return,
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700292
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 /// A macro invocation; pre-expansion
294 pub Mac(Mac),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700295
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 /// A struct literal expression.
297 ///
298 /// For example, `Foo {x: 1, y: 2}`, or
299 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400300 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 pub path: Path,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 pub fields: Delimited<FieldValue, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub rest: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700304 pub dot2_token: Option<tokens::Dot2>,
305 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700307
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 /// An array literal constructed from one repeated element.
309 ///
310 /// For example, `[1; 5]`. The first expression is the element
311 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400312 pub Repeat(ExprRepeat #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 pub bracket_token: tokens::Bracket,
314 pub semi_token: tokens::Semi,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub expr: Box<Expr>,
316 pub amt: Box<Expr>,
317 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700318
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 /// No-op: used solely so we can pretty-print faithfully
320 pub Paren(ExprParen {
321 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700322 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700324
Michael Layzell93c36282017-06-04 20:43:14 -0400325 /// No-op: used solely so we can pretty-print faithfully
326 ///
327 /// A `group` represents a `None`-delimited span in the input
328 /// `TokenStream` which affects the precidence of the resulting
329 /// expression. They are used for macro hygiene.
330 pub Group(ExprGroup {
331 pub expr: Box<Expr>,
332 pub group_token: tokens::Group,
333 }),
334
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400336 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700338 pub question_token: tokens::Question,
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700340
Alex Crichton62a0a592017-05-22 13:58:53 -0700341 /// A catch expression.
342 ///
343 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400344 pub Catch(ExprCatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700345 pub do_token: tokens::Do,
346 pub catch_token: tokens::Catch,
Alex Crichton62a0a592017-05-22 13:58:53 -0700347 pub block: Block,
348 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700349
350 /// A yield expression.
351 ///
352 /// E.g. `yield expr`
353 pub Yield(ExprYield #full {
354 pub yield_token: tokens::Yield,
355 pub expr: Option<Box<Expr>>,
356 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700358}
359
Michael Layzell734adb42017-06-07 16:58:31 -0400360#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700361ast_struct! {
362 /// A field-value pair in a struct literal.
363 pub struct FieldValue {
364 /// Name of the field.
365 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500366
Alex Crichton62a0a592017-05-22 13:58:53 -0700367 /// Value of the field.
368 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500369
Alex Crichton62a0a592017-05-22 13:58:53 -0700370 /// Whether this is a shorthand field, e.g. `Struct { x }`
371 /// instead of `Struct { x: x }`.
372 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500373
Alex Crichton62a0a592017-05-22 13:58:53 -0700374 /// Attributes tagged on the field.
375 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700376
377 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700378 }
David Tolnay055a7042016-10-02 19:23:54 -0700379}
380
Michael Layzell734adb42017-06-07 16:58:31 -0400381#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700382ast_struct! {
383 /// A Block (`{ .. }`).
384 ///
385 /// E.g. `{ .. }` as in `fn foo() { .. }`
386 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700387 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700388 /// Statements in a block
389 pub stmts: Vec<Stmt>,
390 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391}
392
Michael Layzell734adb42017-06-07 16:58:31 -0400393#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700394ast_enum! {
395 /// A statement, usually ending in a semicolon.
396 pub enum Stmt {
397 /// A local (let) binding.
398 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700399
Alex Crichton62a0a592017-05-22 13:58:53 -0700400 /// An item definition.
401 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700402
Alex Crichton62a0a592017-05-22 13:58:53 -0700403 /// Expr without trailing semicolon.
404 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700405
Alex Crichton62a0a592017-05-22 13:58:53 -0700406 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700407 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700408
Alex Crichton62a0a592017-05-22 13:58:53 -0700409 /// Macro invocation.
410 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
411 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700412}
413
Michael Layzell734adb42017-06-07 16:58:31 -0400414#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700415ast_enum! {
416 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700417 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 pub enum MacStmtStyle {
419 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
420 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700421 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500422
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 /// The macro statement had braces; e.g. foo! { ... }
424 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500425
Alex Crichton62a0a592017-05-22 13:58:53 -0700426 /// The macro statement had parentheses or brackets and no semicolon; e.g.
427 /// `foo!(...)`. All of these will end up being converted into macro
428 /// expressions.
429 NoBraces,
430 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700431}
432
Michael Layzell734adb42017-06-07 16:58:31 -0400433#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700434ast_struct! {
435 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
436 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700437 pub let_token: tokens::Let,
438 pub colon_token: Option<tokens::Colon>,
439 pub eq_token: Option<tokens::Eq>,
440 pub semi_token: tokens::Semi,
441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 pub pat: Box<Pat>,
443 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Initializer expression to set the value, if any
446 pub init: Option<Box<Expr>>,
447 pub attrs: Vec<Attribute>,
448 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700449}
450
Michael Layzell734adb42017-06-07 16:58:31 -0400451#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700452ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700453 // Clippy false positive
454 // https://github.com/Manishearth/rust-clippy/issues/1241
455 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
456 pub enum Pat {
457 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458 pub Wild(PatWild {
459 pub underscore_token: tokens::Underscore,
460 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
463 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
464 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
465 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700466 pub Ident(PatIdent {
467 pub mode: BindingMode,
468 pub ident: Ident,
469 pub subpat: Option<Box<Pat>>,
470 pub at_token: Option<tokens::At>,
471 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700472
Alex Crichton62a0a592017-05-22 13:58:53 -0700473 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
474 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 pub Struct(PatStruct {
476 pub path: Path,
477 pub fields: Delimited<FieldPat, tokens::Comma>,
478 pub brace_token: tokens::Brace,
479 pub dot2_token: Option<tokens::Dot2>,
480 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
483 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
484 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 pub TupleStruct(PatTupleStruct {
486 pub path: Path,
487 pub pat: PatTuple,
488 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A possibly qualified path pattern.
491 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
492 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
493 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 pub Path(PatPath {
495 pub qself: Option<QSelf>,
496 pub path: Path,
497 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700498
Alex Crichton62a0a592017-05-22 13:58:53 -0700499 /// A tuple pattern `(a, b)`.
500 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
501 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub Tuple(PatTuple {
503 pub pats: Delimited<Pat, tokens::Comma>,
504 pub dots_pos: Option<usize>,
505 pub paren_token: tokens::Paren,
506 pub dot2_token: Option<tokens::Dot2>,
507 pub comma_token: Option<tokens::Comma>,
508 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700509 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700510 pub Box(PatBox {
511 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700512 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Ref(PatRef {
516 pub pat: Box<Pat>,
517 pub mutbl: Mutability,
518 pub and_token: tokens::And,
519 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700520 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 pub Lit(PatLit {
522 pub expr: Box<Expr>,
523 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700524 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub Range(PatRange {
526 pub lo: Box<Expr>,
527 pub hi: Box<Expr>,
528 pub limits: RangeLimits,
529 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700530 /// `[a, b, ..i, y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 pub Slice(PatSlice {
532 pub front: Delimited<Pat, tokens::Comma>,
533 pub middle: Option<Box<Pat>>,
534 pub back: Delimited<Pat, tokens::Comma>,
535 pub dot2_token: Option<tokens::Dot2>,
536 pub comma_token: Option<tokens::Comma>,
537 pub bracket_token: tokens::Bracket,
538 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700540 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700541 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700542}
543
Michael Layzell734adb42017-06-07 16:58:31 -0400544#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700545ast_struct! {
546 /// An arm of a 'match'.
547 ///
548 /// E.g. `0...10 => { println!("match!") }` as in
549 ///
550 /// ```rust,ignore
551 /// match n {
552 /// 0...10 => { println!("match!") },
553 /// // ..
554 /// }
555 /// ```
556 pub struct Arm {
557 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 pub pats: Delimited<Pat, tokens::Or>,
559 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700561 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700563 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700565}
566
Michael Layzell734adb42017-06-07 16:58:31 -0400567#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700568ast_enum! {
569 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700570 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 Ref,
574 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700575}
576
Michael Layzell734adb42017-06-07 16:58:31 -0400577#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700578ast_enum! {
579 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700580 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub enum RangeLimits {
582 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700583 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700585 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587}
588
Michael Layzell734adb42017-06-07 16:58:31 -0400589#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700590ast_struct! {
591 /// A single field in a struct pattern
592 ///
593 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
594 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
595 /// except `is_shorthand` is true
596 pub struct FieldPat {
597 /// The identifier for the field
598 pub ident: Ident,
599 /// The pattern the field is destructured to
600 pub pat: Box<Pat>,
601 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700602 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 pub attrs: Vec<Attribute>,
604 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700605}
606
Michael Layzell734adb42017-06-07 16:58:31 -0400607#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700608ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700609 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700611 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700612 ByValue(Mutability),
613 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700614}
615
Michael Layzell734adb42017-06-07 16:58:31 -0400616#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400617ast_enum! {
618 #[cfg_attr(feature = "clone-impls", derive(Copy))]
619 pub enum InPlaceKind {
620 Arrow(tokens::LArrow),
621 In(tokens::In),
622 }
623}
624
David Tolnayb9c8e322016-09-23 20:48:37 -0700625#[cfg(feature = "parsing")]
626pub mod parsing {
627 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700628 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700629
Michael Layzell734adb42017-06-07 16:58:31 -0400630 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700631 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400632 use synom::{PResult, Cursor, Synom};
633 #[cfg(feature = "full")]
634 use synom::parse_error;
Alex Crichton954046c2017-05-30 21:49:42 -0700635 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700636
Michael Layzellb78f3b52017-06-04 19:03:03 -0400637 /// When we're parsing expressions which occur before blocks, like in
638 /// an if statement's condition, we cannot parse a struct literal.
639 ///
640 /// Struct literals are ambiguous in certain positions
641 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700642 macro_rules! ambiguous_expr {
643 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700644 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700645 };
646 }
647
Michael Layzellb78f3b52017-06-04 19:03:03 -0400648 /// When we are parsing an optional suffix expression, we cannot allow
649 /// blocks if structs are not allowed.
650 ///
651 /// Example:
652 /// ```ignore
653 /// if break { } { }
654 /// // is ambiguous between:
655 /// if (break { }) { }
656 /// // - or -
657 /// if (break) { } { }
658 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400659 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400660 macro_rules! opt_ambiguous_expr {
661 ($i:expr, $allow_struct:ident) => {
662 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
663 };
664 }
665
Alex Crichton954046c2017-05-30 21:49:42 -0700666 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400667 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700668
669 fn description() -> Option<&'static str> {
670 Some("expression")
671 }
672 }
673
Michael Layzell734adb42017-06-07 16:58:31 -0400674 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700675 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
676
Michael Layzellb78f3b52017-06-04 19:03:03 -0400677 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400678 #[cfg(feature = "full")]
679 fn ambiguous_expr(i: Cursor,
680 allow_struct: bool,
681 allow_block: bool)
682 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400683 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700684 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400685 call!(assign_expr, allow_struct, allow_block),
686 ExprKind::into
687 )
688 }
689
Michael Layzell734adb42017-06-07 16:58:31 -0400690 #[cfg(not(feature = "full"))]
691 fn ambiguous_expr(i: Cursor,
692 allow_struct: bool,
693 allow_block: bool)
694 -> PResult<Expr> {
695 map!(
696 i,
697 // NOTE: We intentionally skip assign_expr, placement_expr, and
698 // range_expr, as they are not parsed in non-full mode.
699 call!(or_expr, allow_struct, allow_block),
700 ExprKind::into
701 )
702 }
703
Michael Layzellb78f3b52017-06-04 19:03:03 -0400704 /// Parse a left-associative binary operator.
705 macro_rules! binop {
706 (
707 $name: ident,
708 $next: ident,
709 $submac: ident!( $($args:tt)* )
710 ) => {
711 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
712 mut e: call!($next, allow_struct, allow_block) >>
713 many0!(do_parse!(
714 op: $submac!($($args)*) >>
715 rhs: call!($next, allow_struct, true) >>
716 ({
717 e = ExprBinary {
718 left: Box::new(e.into()),
719 op: op,
720 right: Box::new(rhs.into()),
721 }.into();
722 })
723 )) >>
724 (e)
725 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700726 }
David Tolnay54e854d2016-10-24 12:03:30 -0700727 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700728
Michael Layzellb78f3b52017-06-04 19:03:03 -0400729 /// ```ignore
730 /// <placement> = <placement> ..
731 /// <placement> += <placement> ..
732 /// <placement> -= <placement> ..
733 /// <placement> *= <placement> ..
734 /// <placement> /= <placement> ..
735 /// <placement> %= <placement> ..
736 /// <placement> ^= <placement> ..
737 /// <placement> &= <placement> ..
738 /// <placement> |= <placement> ..
739 /// <placement> <<= <placement> ..
740 /// <placement> >>= <placement> ..
741 /// ```
742 ///
743 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400744 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400745 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
746 mut e: call!(placement_expr, allow_struct, allow_block) >>
747 alt!(
748 do_parse!(
749 eq: syn!(Eq) >>
750 // Recurse into self to parse right-associative operator.
751 rhs: call!(assign_expr, allow_struct, true) >>
752 ({
753 e = ExprAssign {
754 left: Box::new(e.into()),
755 eq_token: eq,
756 right: Box::new(rhs.into()),
757 }.into();
758 })
759 )
760 |
761 do_parse!(
762 op: call!(BinOp::parse_assign_op) >>
763 // Recurse into self to parse right-associative operator.
764 rhs: call!(assign_expr, allow_struct, true) >>
765 ({
766 e = ExprAssignOp {
767 left: Box::new(e.into()),
768 op: op,
769 right: Box::new(rhs.into()),
770 }.into();
771 })
772 )
773 |
774 epsilon!()
775 ) >>
776 (e)
777 ));
778
779 /// ```ignore
780 /// <range> <- <range> ..
781 /// ```
782 ///
783 /// NOTE: The `in place { expr }` version of this syntax is parsed in
784 /// `atom_expr`, not here.
785 ///
786 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400787 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400788 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
789 mut e: call!(range_expr, allow_struct, allow_block) >>
790 alt!(
791 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400792 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400793 // Recurse into self to parse right-associative operator.
794 rhs: call!(placement_expr, allow_struct, true) >>
795 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400796 e = ExprInPlace {
797 // op: BinOp::Place(larrow),
798 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400799 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400800 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400801 }.into();
802 })
803 )
804 |
805 epsilon!()
806 ) >>
807 (e)
808 ));
809
810 /// ```ignore
811 /// <or> ... <or> ..
812 /// <or> .. <or> ..
813 /// <or> ..
814 /// ```
815 ///
816 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
817 /// rules are for parsing these expressions are, but this is not correct.
818 /// For example, `a .. b .. c` is not a legal expression. It should not
819 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
820 ///
821 /// NOTE: The form of ranges which don't include a preceding expression are
822 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400823 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400824 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
825 mut e: call!(or_expr, allow_struct, allow_block) >>
826 many0!(do_parse!(
827 limits: syn!(RangeLimits) >>
828 // We don't want to allow blocks here if we don't allow structs. See
829 // the reasoning for `opt_ambiguous_expr!` above.
830 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
831 ({
832 e = ExprRange {
833 from: Some(Box::new(e.into())),
834 limits: limits,
835 to: hi.map(|e| Box::new(e.into())),
836 }.into();
837 })
838 )) >>
839 (e)
840 ));
841
842 /// ```ignore
843 /// <and> || <and> ...
844 /// ```
845 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
846
847 /// ```ignore
848 /// <compare> && <compare> ...
849 /// ```
850 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
851
852 /// ```ignore
853 /// <bitor> == <bitor> ...
854 /// <bitor> != <bitor> ...
855 /// <bitor> >= <bitor> ...
856 /// <bitor> <= <bitor> ...
857 /// <bitor> > <bitor> ...
858 /// <bitor> < <bitor> ...
859 /// ```
860 ///
861 /// NOTE: This operator appears to be parsed as left-associative, but errors
862 /// if it is used in a non-associative manner.
863 binop!(compare_expr, bitor_expr, alt!(
864 syn!(EqEq) => { BinOp::Eq }
865 |
866 syn!(Ne) => { BinOp::Ne }
867 |
868 // must be above Lt
869 syn!(Le) => { BinOp::Le }
870 |
871 // must be above Gt
872 syn!(Ge) => { BinOp::Ge }
873 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400874 do_parse!(
875 // Make sure that we don't eat the < part of a <- operator
876 not!(syn!(LArrow)) >>
877 t: syn!(Lt) >>
878 (BinOp::Lt(t))
879 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400880 |
881 syn!(Gt) => { BinOp::Gt }
882 ));
883
884 /// ```ignore
885 /// <bitxor> | <bitxor> ...
886 /// ```
887 binop!(bitor_expr, bitxor_expr, do_parse!(
888 not!(syn!(OrOr)) >>
889 not!(syn!(OrEq)) >>
890 t: syn!(Or) >>
891 (BinOp::BitOr(t))
892 ));
893
894 /// ```ignore
895 /// <bitand> ^ <bitand> ...
896 /// ```
897 binop!(bitxor_expr, bitand_expr, do_parse!(
898 // NOTE: Make sure we aren't looking at ^=.
899 not!(syn!(CaretEq)) >>
900 t: syn!(Caret) >>
901 (BinOp::BitXor(t))
902 ));
903
904 /// ```ignore
905 /// <shift> & <shift> ...
906 /// ```
907 binop!(bitand_expr, shift_expr, do_parse!(
908 // NOTE: Make sure we aren't looking at && or &=.
909 not!(syn!(AndAnd)) >>
910 not!(syn!(AndEq)) >>
911 t: syn!(And) >>
912 (BinOp::BitAnd(t))
913 ));
914
915 /// ```ignore
916 /// <arith> << <arith> ...
917 /// <arith> >> <arith> ...
918 /// ```
919 binop!(shift_expr, arith_expr, alt!(
920 syn!(Shl) => { BinOp::Shl }
921 |
922 syn!(Shr) => { BinOp::Shr }
923 ));
924
925 /// ```ignore
926 /// <term> + <term> ...
927 /// <term> - <term> ...
928 /// ```
929 binop!(arith_expr, term_expr, alt!(
930 syn!(Add) => { BinOp::Add }
931 |
932 syn!(Sub) => { BinOp::Sub }
933 ));
934
935 /// ```ignore
936 /// <cast> * <cast> ...
937 /// <cast> / <cast> ...
938 /// <cast> % <cast> ...
939 /// ```
940 binop!(term_expr, cast_expr, alt!(
941 syn!(Star) => { BinOp::Mul }
942 |
943 syn!(Div) => { BinOp::Div }
944 |
945 syn!(Rem) => { BinOp::Rem }
946 ));
947
948 /// ```ignore
949 /// <unary> as <ty>
950 /// <unary> : <ty>
951 /// ```
952 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
953 mut e: call!(unary_expr, allow_struct, allow_block) >>
954 many0!(alt!(
955 do_parse!(
956 as_: syn!(As) >>
957 // We can't accept `A + B` in cast expressions, as it's
958 // ambiguous with the + expression.
959 ty: call!(Ty::without_plus) >>
960 ({
961 e = ExprCast {
962 expr: Box::new(e.into()),
963 as_token: as_,
964 ty: Box::new(ty),
965 }.into();
966 })
967 )
968 |
969 do_parse!(
970 colon: syn!(Colon) >>
971 // We can't accept `A + B` in cast expressions, as it's
972 // ambiguous with the + expression.
973 ty: call!(Ty::without_plus) >>
974 ({
975 e = ExprType {
976 expr: Box::new(e.into()),
977 colon_token: colon,
978 ty: Box::new(ty),
979 }.into();
980 })
981 )
982 )) >>
983 (e)
984 ));
985
986 /// ```
987 /// <UnOp> <trailer>
988 /// & <trailer>
989 /// &mut <trailer>
990 /// box <trailer>
991 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400992 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400993 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
994 do_parse!(
995 op: syn!(UnOp) >>
996 expr: call!(unary_expr, allow_struct, true) >>
997 (ExprUnary {
998 op: op,
999 expr: Box::new(expr.into()),
1000 }.into())
1001 )
1002 |
1003 do_parse!(
1004 and: syn!(And) >>
1005 mutability: syn!(Mutability) >>
1006 expr: call!(unary_expr, allow_struct, true) >>
1007 (ExprAddrOf {
1008 and_token: and,
1009 mutbl: mutability,
1010 expr: Box::new(expr.into()),
1011 }.into())
1012 )
1013 |
1014 do_parse!(
1015 box_: syn!(Box_) >>
1016 expr: call!(unary_expr, allow_struct, true) >>
1017 (ExprBox {
1018 box_token: box_,
1019 expr: Box::new(expr.into()),
1020 }.into())
1021 )
1022 |
1023 call!(trailer_expr, allow_struct, allow_block)
1024 ));
1025
Michael Layzell734adb42017-06-07 16:58:31 -04001026 // XXX: This duplication is ugly
1027 #[cfg(not(feature = "full"))]
1028 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1029 do_parse!(
1030 op: syn!(UnOp) >>
1031 expr: call!(unary_expr, allow_struct, true) >>
1032 (ExprUnary {
1033 op: op,
1034 expr: Box::new(expr.into()),
1035 }.into())
1036 )
1037 |
1038 call!(trailer_expr, allow_struct, allow_block)
1039 ));
1040
Michael Layzellb78f3b52017-06-04 19:03:03 -04001041 /// ```ignore
1042 /// <atom> (..<args>) ...
1043 /// <atom> . <ident> (..<args>) ...
1044 /// <atom> . <ident> ...
1045 /// <atom> . <lit> ...
1046 /// <atom> [ <expr> ] ...
1047 /// <atom> ? ...
1048 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001049 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001050 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1051 mut e: call!(atom_expr, allow_struct, allow_block) >>
1052 many0!(alt!(
1053 tap!(args: and_call => {
1054 let (args, paren) = args;
1055 e = ExprCall {
1056 func: Box::new(e.into()),
1057 args: args,
1058 paren_token: paren,
1059 }.into();
1060 })
1061 |
1062 tap!(more: and_method_call => {
1063 let mut call = more;
1064 call.expr = Box::new(e.into());
1065 e = call.into();
1066 })
1067 |
1068 tap!(field: and_field => {
1069 let (field, token) = field;
1070 e = ExprField {
1071 expr: Box::new(e.into()),
1072 field: field,
1073 dot_token: token,
1074 }.into();
1075 })
1076 |
1077 tap!(field: and_tup_field => {
1078 let (field, token) = field;
1079 e = ExprTupField {
1080 expr: Box::new(e.into()),
1081 field: field,
1082 dot_token: token,
1083 }.into();
1084 })
1085 |
1086 tap!(i: and_index => {
1087 let (i, token) = i;
1088 e = ExprIndex {
1089 expr: Box::new(e.into()),
1090 bracket_token: token,
1091 index: Box::new(i),
1092 }.into();
1093 })
1094 |
1095 tap!(question: syn!(Question) => {
1096 e = ExprTry {
1097 expr: Box::new(e.into()),
1098 question_token: question,
1099 }.into();
1100 })
1101 )) >>
1102 (e)
1103 ));
1104
Michael Layzell734adb42017-06-07 16:58:31 -04001105 // XXX: Duplication == ugly
1106 #[cfg(not(feature = "full"))]
1107 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1108 mut e: call!(atom_expr, allow_struct, allow_block) >>
1109 many0!(alt!(
1110 tap!(args: and_call => {
1111 let (args, paren) = args;
1112 e = ExprCall {
1113 func: Box::new(e.into()),
1114 args: args,
1115 paren_token: paren,
1116 }.into();
1117 })
1118 |
1119 tap!(i: and_index => {
1120 let (i, token) = i;
1121 e = ExprIndex {
1122 expr: Box::new(e.into()),
1123 bracket_token: token,
1124 index: Box::new(i),
1125 }.into();
1126 })
1127 )) >>
1128 (e)
1129 ));
1130
Michael Layzellb78f3b52017-06-04 19:03:03 -04001131 /// Parse all atomic expressions which don't have to worry about precidence
1132 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001133 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001134 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001135 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1136 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001137 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1138 |
1139 // must be before expr_path
1140 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1141 |
1142 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1143 |
1144 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1145 |
1146 call!(expr_break, allow_struct) // must be before expr_path
1147 |
1148 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1149 |
1150 call!(expr_ret, allow_struct) // must be before expr_path
1151 |
1152 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1153 syn!(ExprInPlace) => { ExprKind::InPlace }
1154 |
1155 syn!(ExprArray) => { ExprKind::Array }
1156 |
1157 syn!(ExprTup) => { ExprKind::Tup }
1158 |
1159 syn!(ExprIf) => { ExprKind::If }
1160 |
1161 syn!(ExprIfLet) => { ExprKind::IfLet }
1162 |
1163 syn!(ExprWhile) => { ExprKind::While }
1164 |
1165 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1166 |
1167 syn!(ExprForLoop) => { ExprKind::ForLoop }
1168 |
1169 syn!(ExprLoop) => { ExprKind::Loop }
1170 |
1171 syn!(ExprMatch) => { ExprKind::Match }
1172 |
1173 syn!(ExprCatch) => { ExprKind::Catch }
1174 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001175 syn!(ExprYield) => { ExprKind::Yield }
1176 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001177 call!(expr_closure, allow_struct)
1178 |
1179 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1180 |
1181 // NOTE: This is the prefix-form of range
1182 call!(expr_range, allow_struct)
1183 |
1184 syn!(ExprPath) => { ExprKind::Path }
1185 |
1186 syn!(ExprRepeat) => { ExprKind::Repeat }
1187 ));
1188
Michael Layzell734adb42017-06-07 16:58:31 -04001189 #[cfg(not(feature = "full"))]
1190 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1191 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1192 |
1193 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1194 |
1195 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1196 |
1197 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1198 |
1199 syn!(ExprPath) => { ExprKind::Path }
1200 ));
1201
1202
1203 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001204 named!(expr_nosemi -> Expr, map!(alt!(
1205 syn!(ExprIf) => { ExprKind::If }
1206 |
1207 syn!(ExprIfLet) => { ExprKind::IfLet }
1208 |
1209 syn!(ExprWhile) => { ExprKind::While }
1210 |
1211 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1212 |
1213 syn!(ExprForLoop) => { ExprKind::ForLoop }
1214 |
1215 syn!(ExprLoop) => { ExprKind::Loop }
1216 |
1217 syn!(ExprMatch) => { ExprKind::Match }
1218 |
1219 syn!(ExprCatch) => { ExprKind::Catch }
1220 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001221 syn!(ExprYield) => { ExprKind::Yield }
1222 |
Michael Layzell35418782017-06-07 09:20:25 -04001223 syn!(ExprBlock) => { ExprKind::Block }
1224 ), Expr::from));
1225
Michael Layzell93c36282017-06-04 20:43:14 -04001226 impl Synom for ExprGroup {
1227 named!(parse -> Self, do_parse!(
1228 e: grouped!(syn!(Expr)) >>
1229 (ExprGroup {
1230 expr: Box::new(e.0),
1231 group_token: e.1,
1232 }.into())
1233 ));
1234 }
1235
Alex Crichton954046c2017-05-30 21:49:42 -07001236 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001237 named!(parse -> Self, do_parse!(
1238 e: parens!(syn!(Expr)) >>
1239 (ExprParen {
1240 expr: Box::new(e.0),
1241 paren_token: e.1,
1242 }.into())
1243 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001244 }
David Tolnay89e05672016-10-02 14:39:42 -07001245
Michael Layzell734adb42017-06-07 16:58:31 -04001246 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001247 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001248 named!(parse -> Self, do_parse!(
1249 in_: syn!(In) >>
1250 place: expr_no_struct >>
1251 value: braces!(call!(Block::parse_within)) >>
1252 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001253 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001254 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001255 value: Box::new(Expr {
1256 node: ExprBlock {
1257 unsafety: Unsafety::Normal,
1258 block: Block {
1259 stmts: value.0,
1260 brace_token: value.1,
1261 },
1262 }.into(),
1263 attrs: Vec::new(),
1264 }),
1265 })
1266 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001267 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001268
Michael Layzell734adb42017-06-07 16:58:31 -04001269 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001270 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001271 named!(parse -> Self, do_parse!(
1272 elems: brackets!(call!(Delimited::parse_terminated)) >>
1273 (ExprArray {
1274 exprs: elems.0,
1275 bracket_token: elems.1,
1276 })
1277 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001278 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001279
Alex Crichton954046c2017-05-30 21:49:42 -07001280 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1281 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001282
Michael Layzell734adb42017-06-07 16:58:31 -04001283 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001284 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001285 dot: syn!(Dot) >>
1286 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001287 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001288 colon2: syn!(Colon2) >>
1289 lt: syn!(Lt) >>
1290 tys: call!(Delimited::parse_terminated) >>
1291 gt: syn!(Gt) >>
1292 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001293 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001294 args: parens!(call!(Delimited::parse_terminated)) >>
1295 ({
1296 let (colon2, lt, tys, gt) = match typarams {
1297 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1298 None => (None, None, None, None),
1299 };
1300 ExprMethodCall {
1301 // this expr will get overwritten after being returned
1302 expr: Box::new(ExprKind::Lit(Lit {
1303 span: Span::default(),
1304 value: LitKind::Bool(false),
1305 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001306
Alex Crichton954046c2017-05-30 21:49:42 -07001307 method: method,
1308 args: args.0,
1309 paren_token: args.1,
1310 dot_token: dot,
1311 lt_token: lt,
1312 gt_token: gt,
1313 colon2_token: colon2,
1314 typarams: tys.unwrap_or_default(),
1315 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001316 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001317 ));
1318
Michael Layzell734adb42017-06-07 16:58:31 -04001319 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001320 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001321 named!(parse -> Self, do_parse!(
1322 elems: parens!(call!(Delimited::parse_terminated)) >>
1323 (ExprTup {
1324 args: elems.0,
1325 paren_token: elems.1,
1326 lone_comma: None, // TODO: parse this
1327 })
1328 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001329 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001330
Michael Layzell734adb42017-06-07 16:58:31 -04001331 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001332 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001333 named!(parse -> Self, do_parse!(
1334 if_: syn!(If) >>
1335 let_: syn!(Let) >>
1336 pat: syn!(Pat) >>
1337 eq: syn!(Eq) >>
1338 cond: expr_no_struct >>
1339 then_block: braces!(call!(Block::parse_within)) >>
1340 else_block: option!(else_block) >>
1341 (ExprIfLet {
1342 pat: Box::new(pat),
1343 let_token: let_,
1344 eq_token: eq,
1345 expr: Box::new(cond),
1346 if_true: Block {
1347 stmts: then_block.0,
1348 brace_token: then_block.1,
1349 },
1350 if_token: if_,
1351 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1352 if_false: else_block.map(|p| Box::new(p.1.into())),
1353 })
1354 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001355 }
1356
Michael Layzell734adb42017-06-07 16:58:31 -04001357 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001358 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001359 named!(parse -> Self, do_parse!(
1360 if_: syn!(If) >>
1361 cond: expr_no_struct >>
1362 then_block: braces!(call!(Block::parse_within)) >>
1363 else_block: option!(else_block) >>
1364 (ExprIf {
1365 cond: Box::new(cond),
1366 if_true: Block {
1367 stmts: then_block.0,
1368 brace_token: then_block.1,
1369 },
1370 if_token: if_,
1371 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1372 if_false: else_block.map(|p| Box::new(p.1.into())),
1373 })
1374 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001375 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001376
Michael Layzell734adb42017-06-07 16:58:31 -04001377 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001378 named!(else_block -> (Else, ExprKind), do_parse!(
1379 else_: syn!(Else) >>
1380 expr: alt!(
1381 syn!(ExprIf) => { ExprKind::If }
1382 |
1383 syn!(ExprIfLet) => { ExprKind::IfLet }
1384 |
1385 do_parse!(
1386 else_block: braces!(call!(Block::parse_within)) >>
1387 (ExprKind::Block(ExprBlock {
1388 unsafety: Unsafety::Normal,
1389 block: Block {
1390 stmts: else_block.0,
1391 brace_token: else_block.1,
1392 },
1393 }))
David Tolnay939766a2016-09-23 23:48:12 -07001394 )
Alex Crichton954046c2017-05-30 21:49:42 -07001395 ) >>
1396 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001397 ));
1398
David Tolnaybb6feae2016-10-02 21:25:20 -07001399
Michael Layzell734adb42017-06-07 16:58:31 -04001400 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001401 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001402 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001403 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001404 for_: syn!(For) >>
1405 pat: syn!(Pat) >>
1406 in_: syn!(In) >>
1407 expr: expr_no_struct >>
1408 loop_block: syn!(Block) >>
1409 (ExprForLoop {
1410 for_token: for_,
1411 in_token: in_,
1412 pat: Box::new(pat),
1413 expr: Box::new(expr),
1414 body: loop_block,
1415 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1416 label: lbl.map(|p| p.0),
1417 })
1418 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001419 }
Gregory Katze5f35682016-09-27 14:20:55 -04001420
Michael Layzell734adb42017-06-07 16:58:31 -04001421 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001422 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001423 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001424 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001425 loop_: syn!(Loop) >>
1426 loop_block: syn!(Block) >>
1427 (ExprLoop {
1428 loop_token: loop_,
1429 body: loop_block,
1430 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1431 label: lbl.map(|p| p.0),
1432 })
1433 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001434 }
1435
Michael Layzell734adb42017-06-07 16:58:31 -04001436 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001437 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001438 named!(parse -> Self, do_parse!(
1439 match_: syn!(Match) >>
1440 obj: expr_no_struct >>
1441 res: braces!(do_parse!(
1442 mut arms: many0!(do_parse!(
1443 arm: syn!(Arm) >>
1444 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1445 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1446 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001447 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001448 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001449 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001450 arms.extend(last_arm);
1451 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001452 })
Michael Layzell92639a52017-06-01 00:07:44 -04001453 )) >>
1454 ({
1455 let (mut arms, brace) = res;
1456 ExprMatch {
1457 expr: Box::new(obj),
1458 match_token: match_,
1459 brace_token: brace,
1460 arms: {
1461 for arm in &mut arms {
1462 if arm_requires_comma(arm) {
1463 arm.comma = Some(tokens::Comma::default());
1464 }
1465 }
1466 arms
1467 },
1468 }
1469 })
1470 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001471 }
David Tolnay1978c672016-10-27 22:05:52 -07001472
Michael Layzell734adb42017-06-07 16:58:31 -04001473 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001474 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001475 named!(parse -> Self, do_parse!(
1476 do_: syn!(Do) >>
1477 catch_: syn!(Catch) >>
1478 catch_block: syn!(Block) >>
1479 (ExprCatch {
1480 block: catch_block,
1481 do_token: do_,
1482 catch_token: catch_,
1483 }.into())
1484 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001485 }
Arnavion02ef13f2017-04-25 00:54:31 -07001486
Michael Layzell734adb42017-06-07 16:58:31 -04001487 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001488 impl Synom for ExprYield {
1489 named!(parse -> Self, do_parse!(
1490 yield_: syn!(Yield) >>
1491 expr: option!(syn!(Expr)) >>
1492 (ExprYield {
1493 yield_token: yield_,
1494 expr: expr.map(Box::new),
1495 })
1496 ));
1497 }
1498
1499 #[cfg(feature = "full")]
David Tolnay1978c672016-10-27 22:05:52 -07001500 fn arm_requires_comma(arm: &Arm) -> bool {
Alex Crichton62a0a592017-05-22 13:58:53 -07001501 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
David Tolnay1978c672016-10-27 22:05:52 -07001502 false
1503 } else {
1504 true
1505 }
1506 }
1507
Michael Layzell734adb42017-06-07 16:58:31 -04001508 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001509 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001510 named!(parse -> Self, do_parse!(
1511 attrs: many0!(call!(Attribute::parse_outer)) >>
1512 pats: call!(Delimited::parse_separated_nonempty) >>
1513 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1514 rocket: syn!(Rocket) >>
1515 body: alt!(
1516 map!(syn!(Block), |blk| {
1517 ExprKind::Block(ExprBlock {
1518 unsafety: Unsafety::Normal,
1519 block: blk,
1520 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001521 })
Michael Layzell92639a52017-06-01 00:07:44 -04001522 |
1523 syn!(Expr)
1524 ) >>
1525 (Arm {
1526 rocket_token: rocket,
1527 if_token: guard.as_ref().map(|p| If((p.0).0)),
1528 attrs: attrs,
1529 pats: pats,
1530 guard: guard.map(|p| Box::new(p.1)),
1531 body: Box::new(body),
1532 comma: None,
1533 })
1534 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001535 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001536
Michael Layzell734adb42017-06-07 16:58:31 -04001537 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001538 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001539 capture: syn!(CaptureBy) >>
1540 or1: syn!(Or) >>
1541 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1542 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001543 ret_and_body: alt!(
1544 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001545 arrow: syn!(RArrow) >>
1546 ty: syn!(Ty) >>
1547 body: syn!(Block) >>
1548 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001549 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001550 unsafety: Unsafety::Normal,
1551 block: body,
1552 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001553 )
1554 |
David Tolnay58af3552016-12-22 16:58:07 -05001555 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001556 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001557 (ExprClosure {
1558 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001559 or1_token: or1,
1560 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001561 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001562 inputs: inputs,
1563 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001564 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001565 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001566 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001567 generics: Generics::default(),
1568 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001569 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001570 body: Box::new(ret_and_body.1),
1571 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001572 ));
1573
Michael Layzell734adb42017-06-07 16:58:31 -04001574 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001575 named!(fn_arg -> FnArg, do_parse!(
1576 pat: syn!(Pat) >>
1577 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1578 ({
1579 let (colon, ty) = ty.unwrap_or_else(|| {
1580 (Colon::default(), TyInfer {
1581 underscore_token: Underscore::default(),
1582 }.into())
1583 });
1584 ArgCaptured {
1585 pat: pat,
1586 colon_token: colon,
1587 ty: ty,
1588 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001589 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001590 ));
1591
Michael Layzell734adb42017-06-07 16:58:31 -04001592 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001593 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001594 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001595 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001596 while_: syn!(While) >>
1597 cond: expr_no_struct >>
1598 while_block: syn!(Block) >>
1599 (ExprWhile {
1600 while_token: while_,
1601 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1602 cond: Box::new(cond),
1603 body: while_block,
1604 label: lbl.map(|p| p.0),
1605 })
1606 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001607 }
1608
Michael Layzell734adb42017-06-07 16:58:31 -04001609 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001610 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001611 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001612 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001613 while_: syn!(While) >>
1614 let_: syn!(Let) >>
1615 pat: syn!(Pat) >>
1616 eq: syn!(Eq) >>
1617 value: expr_no_struct >>
1618 while_block: syn!(Block) >>
1619 (ExprWhileLet {
1620 eq_token: eq,
1621 let_token: let_,
1622 while_token: while_,
1623 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1624 pat: Box::new(pat),
1625 expr: Box::new(value),
1626 body: while_block,
1627 label: lbl.map(|p| p.0),
1628 })
1629 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001630 }
1631
Michael Layzell734adb42017-06-07 16:58:31 -04001632 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001633 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001634 named!(parse -> Self, do_parse!(
1635 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001636 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001637 (ExprContinue {
1638 continue_token: cont,
1639 label: lbl,
1640 })
1641 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001642 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001643
Michael Layzell734adb42017-06-07 16:58:31 -04001644 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001645 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001646 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001647 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001648 // We can't allow blocks after a `break` expression when we wouldn't
1649 // allow structs, as this expression is ambiguous.
1650 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001651 (ExprBreak {
1652 label: lbl,
1653 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001654 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001655 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001656 ));
1657
Michael Layzell734adb42017-06-07 16:58:31 -04001658 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001659 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001660 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001661 // NOTE: return is greedy and eats blocks after it even when in a
1662 // position where structs are not allowed, such as in if statement
1663 // conditions. For example:
1664 //
1665 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001666 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001667 (ExprRet {
1668 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001669 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001670 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001671 ));
1672
Michael Layzell734adb42017-06-07 16:58:31 -04001673 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001674 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001675 named!(parse -> Self, do_parse!(
1676 path: syn!(Path) >>
1677 data: braces!(do_parse!(
1678 fields: call!(Delimited::parse_terminated) >>
1679 base: option!(
1680 cond!(fields.is_empty() || fields.trailing_delim(),
1681 do_parse!(
1682 dots: syn!(Dot2) >>
1683 base: syn!(Expr) >>
1684 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001685 )
Michael Layzell92639a52017-06-01 00:07:44 -04001686 )
1687 ) >>
1688 (fields, base)
1689 )) >>
1690 ({
1691 let ((fields, base), brace) = data;
1692 let (dots, rest) = match base.and_then(|b| b) {
1693 Some((dots, base)) => (Some(dots), Some(base)),
1694 None => (None, None),
1695 };
1696 ExprStruct {
1697 brace_token: brace,
1698 path: path,
1699 fields: fields,
1700 dot2_token: dots,
1701 rest: rest.map(Box::new),
1702 }
1703 })
1704 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001705 }
1706
Michael Layzell734adb42017-06-07 16:58:31 -04001707 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001708 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001709 named!(parse -> Self, alt!(
1710 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001711 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001712 colon: syn!(Colon) >>
1713 value: syn!(Expr) >>
1714 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001715 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001716 expr: value,
1717 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001718 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001719 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001720 })
Michael Layzell92639a52017-06-01 00:07:44 -04001721 )
1722 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001723 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001724 ident: name.clone(),
1725 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1726 is_shorthand: true,
1727 attrs: Vec::new(),
1728 colon_token: None,
1729 })
1730 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001731 }
David Tolnay055a7042016-10-02 19:23:54 -07001732
Michael Layzell734adb42017-06-07 16:58:31 -04001733 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001734 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001735 named!(parse -> Self, do_parse!(
1736 data: brackets!(do_parse!(
1737 value: syn!(Expr) >>
1738 semi: syn!(Semi) >>
1739 times: syn!(Expr) >>
1740 (value, semi, times)
1741 )) >>
1742 (ExprRepeat {
1743 expr: Box::new((data.0).0),
1744 amt: Box::new((data.0).2),
1745 bracket_token: data.1,
1746 semi_token: (data.0).1,
1747 })
1748 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001749 }
David Tolnay055a7042016-10-02 19:23:54 -07001750
Michael Layzell734adb42017-06-07 16:58:31 -04001751 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001752 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001753 named!(parse -> Self, do_parse!(
1754 rules: syn!(Unsafety) >>
1755 b: syn!(Block) >>
1756 (ExprBlock {
1757 unsafety: rules,
1758 block: b,
1759 })
1760 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001761 }
David Tolnay89e05672016-10-02 14:39:42 -07001762
Michael Layzell734adb42017-06-07 16:58:31 -04001763 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001764 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001765 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001766 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001767 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001768 ));
1769
Michael Layzell734adb42017-06-07 16:58:31 -04001770 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001771 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001772 named!(parse -> Self, alt!(
1773 // Must come before Dot2
1774 syn!(Dot3) => { RangeLimits::Closed }
1775 |
1776 syn!(Dot2) => { RangeLimits::HalfOpen }
1777 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001778 }
David Tolnay438c9052016-10-07 23:24:48 -07001779
Alex Crichton954046c2017-05-30 21:49:42 -07001780 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001781 named!(parse -> Self, do_parse!(
1782 pair: qpath >>
1783 (ExprPath {
1784 qself: pair.0,
1785 path: pair.1,
1786 })
1787 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001788 }
David Tolnay42602292016-10-01 22:25:45 -07001789
Michael Layzell734adb42017-06-07 16:58:31 -04001790 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001791 named!(and_field -> (Ident, Dot),
1792 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001793
Michael Layzell734adb42017-06-07 16:58:31 -04001794 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001795 named!(and_tup_field -> (Lit, Dot),
1796 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001797
Alex Crichton954046c2017-05-30 21:49:42 -07001798 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001799
Michael Layzell734adb42017-06-07 16:58:31 -04001800 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001801 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001802 named!(parse -> Self, do_parse!(
1803 stmts: braces!(call!(Block::parse_within)) >>
1804 (Block {
1805 stmts: stmts.0,
1806 brace_token: stmts.1,
1807 })
1808 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001809 }
David Tolnay939766a2016-09-23 23:48:12 -07001810
Michael Layzell734adb42017-06-07 16:58:31 -04001811 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001812 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001813 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1814 many0!(syn!(Semi)) >>
1815 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
1816 last: option!(syn!(Expr)) >>
1817 (match last {
1818 None => standalone,
1819 Some(last) => {
1820 standalone.push(Stmt::Expr(Box::new(last)));
1821 standalone
1822 }
1823 })
1824 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001825 }
1826
Michael Layzell734adb42017-06-07 16:58:31 -04001827 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001828 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001829 named!(parse -> Self, alt!(
1830 stmt_mac
1831 |
1832 stmt_local
1833 |
1834 stmt_item
1835 |
Michael Layzell35418782017-06-07 09:20:25 -04001836 stmt_blockexpr
1837 |
Michael Layzell92639a52017-06-01 00:07:44 -04001838 stmt_expr
1839 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001840 }
David Tolnay939766a2016-09-23 23:48:12 -07001841
Michael Layzell734adb42017-06-07 16:58:31 -04001842 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001843 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001844 attrs: many0!(call!(Attribute::parse_outer)) >>
1845 what: syn!(Path) >>
1846 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001847 // Only parse braces here; paren and bracket will get parsed as
1848 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001849 data: braces!(syn!(TokenStream)) >>
1850 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001851 (Stmt::Mac(Box::new((
1852 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001853 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001854 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001855 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001856 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001857 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001858 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001859 })],
1860 },
Alex Crichton954046c2017-05-30 21:49:42 -07001861 match semi {
1862 Some(semi) => MacStmtStyle::Semicolon(semi),
1863 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001864 },
David Tolnayeea28d62016-10-25 20:44:08 -07001865 attrs,
1866 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001867 ));
1868
Michael Layzell734adb42017-06-07 16:58:31 -04001869 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001870 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001871 attrs: many0!(call!(Attribute::parse_outer)) >>
1872 let_: syn!(Let) >>
1873 pat: syn!(Pat) >>
1874 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1875 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1876 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001877 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001878 let_token: let_,
1879 semi_token: semi,
1880 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1881 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001882 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001883 ty: ty.map(|p| Box::new(p.1)),
1884 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001885 attrs: attrs,
1886 })))
1887 ));
1888
Michael Layzell734adb42017-06-07 16:58:31 -04001889 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001890 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001891
Michael Layzell734adb42017-06-07 16:58:31 -04001892 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001893 named!(stmt_blockexpr -> Stmt, do_parse!(
1894 attrs: many0!(call!(Attribute::parse_outer)) >>
1895 mut e: expr_nosemi >>
1896 // If the next token is a `.` or a `?` it is special-cased to parse as
1897 // an expression instead of a blockexpression.
1898 not!(syn!(Dot)) >>
1899 not!(syn!(Question)) >>
1900 semi: option!(syn!(Semi)) >>
1901 ({
1902 e.attrs = attrs;
1903 if let Some(semi) = semi {
1904 Stmt::Semi(Box::new(e), semi)
1905 } else {
1906 Stmt::Expr(Box::new(e))
1907 }
1908 })
1909 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001910
Michael Layzell734adb42017-06-07 16:58:31 -04001911 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001912 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001913 attrs: many0!(call!(Attribute::parse_outer)) >>
1914 mut e: syn!(Expr) >>
Michael Layzell35418782017-06-07 09:20:25 -04001915 semi: syn!(Semi) >>
David Tolnay7184b132016-10-30 10:06:37 -07001916 ({
1917 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001918 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001919 })
David Tolnay939766a2016-09-23 23:48:12 -07001920 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001921
Michael Layzell734adb42017-06-07 16:58:31 -04001922 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001923 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001924 named!(parse -> Self, alt!(
1925 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1926 |
1927 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1928 |
1929 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1930 |
1931 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1932 |
1933 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1934 |
1935 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1936 |
1937 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1938 |
1939 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1940 |
1941 syn!(PatPath) => { Pat::Path }
1942 |
1943 syn!(PatTuple) => { Pat::Tuple }
1944 |
1945 syn!(PatRef) => { Pat::Ref }
1946 |
1947 syn!(PatSlice) => { Pat::Slice }
1948 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001949 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001950
Michael Layzell734adb42017-06-07 16:58:31 -04001951 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001952 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001953 named!(parse -> Self, map!(
1954 syn!(Underscore),
1955 |u| PatWild { underscore_token: u }
1956 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001957 }
David Tolnay84aa0752016-10-02 23:01:13 -07001958
Michael Layzell734adb42017-06-07 16:58:31 -04001959 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001960 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001961 named!(parse -> Self, do_parse!(
1962 boxed: syn!(Box_) >>
1963 pat: syn!(Pat) >>
1964 (PatBox {
1965 pat: Box::new(pat),
1966 box_token: boxed,
1967 })
1968 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001969 }
1970
Michael Layzell734adb42017-06-07 16:58:31 -04001971 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001972 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001973 named!(parse -> Self, do_parse!(
1974 mode: option!(syn!(Ref)) >>
1975 mutability: syn!(Mutability) >>
1976 name: alt!(
1977 syn!(Ident)
1978 |
1979 syn!(Self_) => { Into::into }
1980 ) >>
1981 not!(syn!(Lt)) >>
1982 not!(syn!(Colon2)) >>
1983 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1984 (PatIdent {
1985 mode: match mode {
1986 Some(mode) => BindingMode::ByRef(mode, mutability),
1987 None => BindingMode::ByValue(mutability),
1988 },
1989 ident: name,
1990 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1991 subpat: subpat.map(|p| Box::new(p.1)),
1992 })
1993 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001994 }
1995
Michael Layzell734adb42017-06-07 16:58:31 -04001996 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001997 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001998 named!(parse -> Self, do_parse!(
1999 path: syn!(Path) >>
2000 tuple: syn!(PatTuple) >>
2001 (PatTupleStruct {
2002 path: path,
2003 pat: tuple,
2004 })
2005 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002006 }
2007
Michael Layzell734adb42017-06-07 16:58:31 -04002008 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002009 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002010 named!(parse -> Self, do_parse!(
2011 path: syn!(Path) >>
2012 data: braces!(do_parse!(
2013 fields: call!(Delimited::parse_terminated) >>
2014 base: option!(
2015 cond!(fields.is_empty() || fields.trailing_delim(),
2016 syn!(Dot2))
2017 ) >>
2018 (fields, base)
2019 )) >>
2020 (PatStruct {
2021 path: path,
2022 fields: (data.0).0,
2023 brace_token: data.1,
2024 dot2_token: (data.0).1.and_then(|m| m),
2025 })
2026 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002027 }
2028
Michael Layzell734adb42017-06-07 16:58:31 -04002029 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002030 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002031 named!(parse -> Self, alt!(
2032 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002033 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04002034 colon: syn!(Colon) >>
2035 pat: syn!(Pat) >>
2036 (FieldPat {
2037 ident: ident,
2038 pat: Box::new(pat),
2039 is_shorthand: false,
2040 attrs: Vec::new(),
2041 colon_token: Some(colon),
2042 })
2043 )
2044 |
2045 do_parse!(
2046 boxed: option!(syn!(Box_)) >>
2047 mode: option!(syn!(Ref)) >>
2048 mutability: syn!(Mutability) >>
2049 ident: syn!(Ident) >>
2050 ({
2051 let mut pat: Pat = PatIdent {
2052 mode: if let Some(mode) = mode {
2053 BindingMode::ByRef(mode, mutability)
2054 } else {
2055 BindingMode::ByValue(mutability)
2056 },
2057 ident: ident.clone(),
2058 subpat: None,
2059 at_token: None,
2060 }.into();
2061 if let Some(boxed) = boxed {
2062 pat = PatBox {
2063 pat: Box::new(pat),
2064 box_token: boxed,
2065 }.into();
2066 }
2067 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002068 ident: ident,
2069 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002070 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002071 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002072 colon_token: None,
2073 }
2074 })
2075 )
2076 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002077 }
2078
Michael Layzell734adb42017-06-07 16:58:31 -04002079 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002080 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002081 syn!(Ident)
2082 |
2083 do_parse!(
2084 lit: syn!(Lit) >>
2085 ({
David Tolnay570695e2017-06-03 16:15:13 -07002086 let s = lit.to_string();
2087 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002088 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002089 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002090 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002091 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002092 })
2093 )
2094 ));
2095
Michael Layzell734adb42017-06-07 16:58:31 -04002096 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002097 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002098 named!(parse -> Self, map!(
2099 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002100 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002101 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002102 }
David Tolnay9636c052016-10-02 17:11:17 -07002103
Michael Layzell734adb42017-06-07 16:58:31 -04002104 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002105 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002106 named!(parse -> Self, do_parse!(
2107 data: parens!(do_parse!(
2108 elems: call!(Delimited::parse_terminated) >>
2109 dotdot: map!(cond!(
2110 elems.is_empty() || elems.trailing_delim(),
2111 option!(do_parse!(
2112 dots: syn!(Dot2) >>
2113 trailing: option!(syn!(Comma)) >>
2114 (dots, trailing)
2115 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002116 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002117 rest: cond!(match dotdot {
2118 Some((_, Some(_))) => true,
2119 _ => false,
2120 },
2121 call!(Delimited::parse_terminated)) >>
2122 (elems, dotdot, rest)
2123 )) >>
2124 ({
2125 let ((mut elems, dotdot, rest), parens) = data;
2126 let (dotdot, trailing) = match dotdot {
2127 Some((a, b)) => (Some(a), Some(b)),
2128 None => (None, None),
2129 };
2130 PatTuple {
2131 paren_token: parens,
2132 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2133 dot2_token: dotdot,
2134 comma_token: trailing.and_then(|b| b),
2135 pats: {
2136 if let Some(rest) = rest {
2137 for elem in rest {
2138 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002139 }
Michael Layzell92639a52017-06-01 00:07:44 -04002140 }
2141 elems
2142 },
2143 }
2144 })
2145 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002146 }
David Tolnayfbb73232016-10-03 01:00:06 -07002147
Michael Layzell734adb42017-06-07 16:58:31 -04002148 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002149 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002150 named!(parse -> Self, do_parse!(
2151 and: syn!(And) >>
2152 mutability: syn!(Mutability) >>
2153 pat: syn!(Pat) >>
2154 (PatRef {
2155 pat: Box::new(pat),
2156 mutbl: mutability,
2157 and_token: and,
2158 })
2159 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002160 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002161
Michael Layzell734adb42017-06-07 16:58:31 -04002162 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002163 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002164 named!(parse -> Self, do_parse!(
2165 lit: pat_lit_expr >>
2166 (if let ExprKind::Path(_) = lit.node {
2167 return parse_error(); // these need to be parsed by pat_path
2168 } else {
2169 PatLit {
2170 expr: Box::new(lit),
2171 }
2172 })
2173 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002174 }
David Tolnaye1310902016-10-29 23:40:00 -07002175
Michael Layzell734adb42017-06-07 16:58:31 -04002176 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002177 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002178 named!(parse -> Self, do_parse!(
2179 lo: pat_lit_expr >>
2180 limits: syn!(RangeLimits) >>
2181 hi: pat_lit_expr >>
2182 (PatRange {
2183 lo: Box::new(lo),
2184 hi: Box::new(hi),
2185 limits: limits,
2186 })
2187 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002188 }
David Tolnaye1310902016-10-29 23:40:00 -07002189
Michael Layzell734adb42017-06-07 16:58:31 -04002190 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002191 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002192 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002193 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002194 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002195 |
Alex Crichton954046c2017-05-30 21:49:42 -07002196 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002197 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002198 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002199 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002200 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002201 expr: Box::new(v.into())
2202 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002203 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002204 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002205 })
2206 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002207
Michael Layzell734adb42017-06-07 16:58:31 -04002208 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002209 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002210 named!(parse -> Self, map!(
2211 brackets!(do_parse!(
2212 before: call!(Delimited::parse_terminated) >>
2213 middle: option!(do_parse!(
2214 dots: syn!(Dot2) >>
2215 trailing: option!(syn!(Comma)) >>
2216 (dots, trailing)
2217 )) >>
2218 after: cond!(
2219 match middle {
2220 Some((_, ref trailing)) => trailing.is_some(),
2221 _ => false,
2222 },
2223 call!(Delimited::parse_terminated)
2224 ) >>
2225 (before, middle, after)
2226 )),
2227 |((before, middle, after), brackets)| {
2228 let mut before: Delimited<Pat, tokens::Comma> = before;
2229 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2230 let middle: Option<(Dot2, Option<Comma>)> = middle;
2231 PatSlice {
2232 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2233 comma_token: middle.as_ref().and_then(|m| {
2234 m.1.as_ref().map(|m| Comma(m.0))
2235 }),
2236 bracket_token: brackets,
2237 middle: middle.and_then(|_| {
2238 if !before.is_empty() && !before.trailing_delim() {
2239 Some(Box::new(before.pop().unwrap().into_item()))
2240 } else {
2241 None
2242 }
2243 }),
2244 front: before,
2245 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002246 }
Alex Crichton954046c2017-05-30 21:49:42 -07002247 }
Michael Layzell92639a52017-06-01 00:07:44 -04002248 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002249 }
David Tolnay435a9a82016-10-29 13:47:20 -07002250
Michael Layzell734adb42017-06-07 16:58:31 -04002251 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002252 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002253 named!(parse -> Self, alt!(
2254 syn!(Move) => { CaptureBy::Value }
2255 |
2256 epsilon!() => { |_| CaptureBy::Ref }
2257 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002258 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002259}
2260
David Tolnayf4bbbd92016-09-23 14:41:55 -07002261#[cfg(feature = "printing")]
2262mod printing {
2263 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002264 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002265 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002266 use quote::{Tokens, ToTokens};
2267
2268 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002269 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002270 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002271 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002272 self.node.to_tokens(tokens)
2273 }
Michael Layzell734adb42017-06-07 16:58:31 -04002274
2275 #[cfg(not(feature = "full"))]
2276 fn to_tokens(&self, tokens: &mut Tokens) {
2277 self.node.to_tokens(tokens)
2278 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002279 }
2280
Michael Layzell734adb42017-06-07 16:58:31 -04002281 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002282 impl ToTokens for ExprBox {
2283 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002284 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002285 self.expr.to_tokens(tokens);
2286 }
2287 }
2288
Michael Layzell734adb42017-06-07 16:58:31 -04002289 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002290 impl ToTokens for ExprInPlace {
2291 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002292 match self.kind {
2293 InPlaceKind::Arrow(ref arrow) => {
2294 self.place.to_tokens(tokens);
2295 arrow.to_tokens(tokens);
2296 self.value.to_tokens(tokens);
2297 }
2298 InPlaceKind::In(ref _in) => {
2299 _in.to_tokens(tokens);
2300 self.place.to_tokens(tokens);
2301 self.value.to_tokens(tokens);
2302 }
2303 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002304 }
2305 }
2306
Michael Layzell734adb42017-06-07 16:58:31 -04002307 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002308 impl ToTokens for ExprArray {
2309 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002310 self.bracket_token.surround(tokens, |tokens| {
2311 self.exprs.to_tokens(tokens);
2312 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002313 }
2314 }
2315
2316 impl ToTokens for ExprCall {
2317 fn to_tokens(&self, tokens: &mut Tokens) {
2318 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002319 self.paren_token.surround(tokens, |tokens| {
2320 self.args.to_tokens(tokens);
2321 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002322 }
2323 }
2324
Michael Layzell734adb42017-06-07 16:58:31 -04002325 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002326 impl ToTokens for ExprMethodCall {
2327 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002328 self.expr.to_tokens(tokens);
2329 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002330 self.method.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002331 self.colon2_token.to_tokens(tokens);
2332 self.lt_token.to_tokens(tokens);
2333 self.typarams.to_tokens(tokens);
2334 self.gt_token.to_tokens(tokens);
2335 self.paren_token.surround(tokens, |tokens| {
2336 self.args.to_tokens(tokens);
2337 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002338 }
2339 }
2340
Michael Layzell734adb42017-06-07 16:58:31 -04002341 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002342 impl ToTokens for ExprTup {
2343 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002344 self.paren_token.surround(tokens, |tokens| {
2345 self.args.to_tokens(tokens);
2346 self.lone_comma.to_tokens(tokens);
2347 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002348 }
2349 }
2350
2351 impl ToTokens for ExprBinary {
2352 fn to_tokens(&self, tokens: &mut Tokens) {
2353 self.left.to_tokens(tokens);
2354 self.op.to_tokens(tokens);
2355 self.right.to_tokens(tokens);
2356 }
2357 }
2358
2359 impl ToTokens for ExprUnary {
2360 fn to_tokens(&self, tokens: &mut Tokens) {
2361 self.op.to_tokens(tokens);
2362 self.expr.to_tokens(tokens);
2363 }
2364 }
2365
2366 impl ToTokens for ExprCast {
2367 fn to_tokens(&self, tokens: &mut Tokens) {
2368 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002369 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002370 self.ty.to_tokens(tokens);
2371 }
2372 }
2373
2374 impl ToTokens for ExprType {
2375 fn to_tokens(&self, tokens: &mut Tokens) {
2376 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002377 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002378 self.ty.to_tokens(tokens);
2379 }
2380 }
2381
Michael Layzell734adb42017-06-07 16:58:31 -04002382 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002383 impl ToTokens for ExprIf {
2384 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002385 self.if_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002386 self.cond.to_tokens(tokens);
2387 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002388 self.else_token.to_tokens(tokens);
2389 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002390 }
2391 }
2392
Michael Layzell734adb42017-06-07 16:58:31 -04002393 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002394 impl ToTokens for ExprIfLet {
2395 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002396 self.if_token.to_tokens(tokens);
2397 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002398 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002399 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002400 self.expr.to_tokens(tokens);
2401 self.if_true.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002402 self.else_token.to_tokens(tokens);
2403 self.if_false.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002404 }
2405 }
2406
Michael Layzell734adb42017-06-07 16:58:31 -04002407 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002408 impl ToTokens for ExprWhile {
2409 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002410 self.label.to_tokens(tokens);
2411 self.colon_token.to_tokens(tokens);
2412 self.while_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002413 self.cond.to_tokens(tokens);
2414 self.body.to_tokens(tokens);
2415 }
2416 }
2417
Michael Layzell734adb42017-06-07 16:58:31 -04002418 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002419 impl ToTokens for ExprWhileLet {
2420 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002421 self.label.to_tokens(tokens);
2422 self.colon_token.to_tokens(tokens);
2423 self.while_token.to_tokens(tokens);
2424 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002425 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002426 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002427 self.expr.to_tokens(tokens);
2428 self.body.to_tokens(tokens);
2429 }
2430 }
2431
Michael Layzell734adb42017-06-07 16:58:31 -04002432 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002433 impl ToTokens for ExprForLoop {
2434 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002435 self.label.to_tokens(tokens);
2436 self.colon_token.to_tokens(tokens);
2437 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002438 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002439 self.in_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002440 self.expr.to_tokens(tokens);
2441 self.body.to_tokens(tokens);
2442 }
2443 }
2444
Michael Layzell734adb42017-06-07 16:58:31 -04002445 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002446 impl ToTokens for ExprLoop {
2447 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002448 self.label.to_tokens(tokens);
2449 self.colon_token.to_tokens(tokens);
2450 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002451 self.body.to_tokens(tokens);
2452 }
2453 }
2454
Michael Layzell734adb42017-06-07 16:58:31 -04002455 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002456 impl ToTokens for ExprMatch {
2457 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002458 self.match_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002459 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002460 self.brace_token.surround(tokens, |tokens| {
2461 tokens.append_all(&self.arms);
2462 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002463 }
2464 }
2465
Michael Layzell734adb42017-06-07 16:58:31 -04002466 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 impl ToTokens for ExprCatch {
2468 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002469 self.do_token.to_tokens(tokens);
2470 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002471 self.block.to_tokens(tokens);
2472 }
2473 }
2474
Michael Layzell734adb42017-06-07 16:58:31 -04002475 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002476 impl ToTokens for ExprYield {
2477 fn to_tokens(&self, tokens: &mut Tokens) {
2478 self.yield_token.to_tokens(tokens);
2479 self.expr.to_tokens(tokens);
2480 }
2481 }
2482
2483 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002484 impl ToTokens for ExprClosure {
2485 fn to_tokens(&self, tokens: &mut Tokens) {
2486 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002487 self.or1_token.to_tokens(tokens);
2488 for item in self.decl.inputs.iter() {
2489 match **item.item() {
2490 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002491 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002492 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002493 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002494 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002495 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002496 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002497 self.or2_token.to_tokens(tokens);
2498 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002499 self.body.to_tokens(tokens);
2500 }
2501 }
2502
Michael Layzell734adb42017-06-07 16:58:31 -04002503 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002504 impl ToTokens for ExprBlock {
2505 fn to_tokens(&self, tokens: &mut Tokens) {
2506 self.unsafety.to_tokens(tokens);
2507 self.block.to_tokens(tokens);
2508 }
2509 }
2510
Michael Layzell734adb42017-06-07 16:58:31 -04002511 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002512 impl ToTokens for ExprAssign {
2513 fn to_tokens(&self, tokens: &mut Tokens) {
2514 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002515 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002516 self.right.to_tokens(tokens);
2517 }
2518 }
2519
Michael Layzell734adb42017-06-07 16:58:31 -04002520 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002521 impl ToTokens for ExprAssignOp {
2522 fn to_tokens(&self, tokens: &mut Tokens) {
2523 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002524 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002525 self.right.to_tokens(tokens);
2526 }
2527 }
2528
Michael Layzell734adb42017-06-07 16:58:31 -04002529 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002530 impl ToTokens for ExprField {
2531 fn to_tokens(&self, tokens: &mut Tokens) {
2532 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002533 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002534 self.field.to_tokens(tokens);
2535 }
2536 }
2537
Michael Layzell734adb42017-06-07 16:58:31 -04002538 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002539 impl ToTokens for ExprTupField {
2540 fn to_tokens(&self, tokens: &mut Tokens) {
2541 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002542 self.dot_token.to_tokens(tokens);
2543 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002544 }
2545 }
2546
2547 impl ToTokens for ExprIndex {
2548 fn to_tokens(&self, tokens: &mut Tokens) {
2549 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002550 self.bracket_token.surround(tokens, |tokens| {
2551 self.index.to_tokens(tokens);
2552 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002553 }
2554 }
2555
Michael Layzell734adb42017-06-07 16:58:31 -04002556 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002557 impl ToTokens for ExprRange {
2558 fn to_tokens(&self, tokens: &mut Tokens) {
2559 self.from.to_tokens(tokens);
2560 self.limits.to_tokens(tokens);
2561 self.to.to_tokens(tokens);
2562 }
2563 }
2564
2565 impl ToTokens for ExprPath {
2566 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002567 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002568 }
2569 }
2570
Michael Layzell734adb42017-06-07 16:58:31 -04002571 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002572 impl ToTokens for ExprAddrOf {
2573 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002574 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002575 self.mutbl.to_tokens(tokens);
2576 self.expr.to_tokens(tokens);
2577 }
2578 }
2579
Michael Layzell734adb42017-06-07 16:58:31 -04002580 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002581 impl ToTokens for ExprBreak {
2582 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002583 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002584 self.label.to_tokens(tokens);
2585 self.expr.to_tokens(tokens);
2586 }
2587 }
2588
Michael Layzell734adb42017-06-07 16:58:31 -04002589 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002590 impl ToTokens for ExprContinue {
2591 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002592 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002593 self.label.to_tokens(tokens);
2594 }
2595 }
2596
Michael Layzell734adb42017-06-07 16:58:31 -04002597 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002598 impl ToTokens for ExprRet {
2599 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002600 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002601 self.expr.to_tokens(tokens);
2602 }
2603 }
2604
Michael Layzell734adb42017-06-07 16:58:31 -04002605 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002606 impl ToTokens for ExprStruct {
2607 fn to_tokens(&self, tokens: &mut Tokens) {
2608 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002609 self.brace_token.surround(tokens, |tokens| {
2610 self.fields.to_tokens(tokens);
2611 self.dot2_token.to_tokens(tokens);
2612 self.rest.to_tokens(tokens);
2613 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002614 }
2615 }
2616
Michael Layzell734adb42017-06-07 16:58:31 -04002617 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002618 impl ToTokens for ExprRepeat {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002620 self.bracket_token.surround(tokens, |tokens| {
2621 self.expr.to_tokens(tokens);
2622 self.semi_token.to_tokens(tokens);
2623 self.amt.to_tokens(tokens);
2624 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002625 }
2626 }
2627
Michael Layzell93c36282017-06-04 20:43:14 -04002628 impl ToTokens for ExprGroup {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
2630 self.group_token.surround(tokens, |tokens| {
2631 self.expr.to_tokens(tokens);
2632 });
2633 }
2634 }
2635
Alex Crichton62a0a592017-05-22 13:58:53 -07002636 impl ToTokens for ExprParen {
2637 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002638 self.paren_token.surround(tokens, |tokens| {
2639 self.expr.to_tokens(tokens);
2640 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002641 }
2642 }
2643
Michael Layzell734adb42017-06-07 16:58:31 -04002644 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002645 impl ToTokens for ExprTry {
2646 fn to_tokens(&self, tokens: &mut Tokens) {
2647 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002648 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002649 }
2650 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002651
Michael Layzell734adb42017-06-07 16:58:31 -04002652 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002653 impl ToTokens for FieldValue {
2654 fn to_tokens(&self, tokens: &mut Tokens) {
2655 self.ident.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002656 if !self.is_shorthand {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002657 self.colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002658 self.expr.to_tokens(tokens);
2659 }
David Tolnay055a7042016-10-02 19:23:54 -07002660 }
2661 }
2662
Michael Layzell734adb42017-06-07 16:58:31 -04002663 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002664 impl ToTokens for Arm {
2665 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002666 tokens.append_all(&self.attrs);
2667 self.pats.to_tokens(tokens);
2668 self.if_token.to_tokens(tokens);
2669 self.guard.to_tokens(tokens);
2670 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002671 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002672 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002673 }
2674 }
2675
Michael Layzell734adb42017-06-07 16:58:31 -04002676 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002677 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002678 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002679 self.underscore_token.to_tokens(tokens);
2680 }
2681 }
2682
Michael Layzell734adb42017-06-07 16:58:31 -04002683 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002684 impl ToTokens for PatIdent {
2685 fn to_tokens(&self, tokens: &mut Tokens) {
2686 self.mode.to_tokens(tokens);
2687 self.ident.to_tokens(tokens);
2688 self.at_token.to_tokens(tokens);
2689 self.subpat.to_tokens(tokens);
2690 }
2691 }
2692
Michael Layzell734adb42017-06-07 16:58:31 -04002693 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002694 impl ToTokens for PatStruct {
2695 fn to_tokens(&self, tokens: &mut Tokens) {
2696 self.path.to_tokens(tokens);
2697 self.brace_token.surround(tokens, |tokens| {
2698 self.fields.to_tokens(tokens);
2699 self.dot2_token.to_tokens(tokens);
2700 });
2701 }
2702 }
2703
Michael Layzell734adb42017-06-07 16:58:31 -04002704 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002705 impl ToTokens for PatTupleStruct {
2706 fn to_tokens(&self, tokens: &mut Tokens) {
2707 self.path.to_tokens(tokens);
2708 self.pat.to_tokens(tokens);
2709 }
2710 }
2711
Michael Layzell734adb42017-06-07 16:58:31 -04002712 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002713 impl ToTokens for PatPath {
2714 fn to_tokens(&self, tokens: &mut Tokens) {
2715 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2716 }
2717 }
2718
Michael Layzell734adb42017-06-07 16:58:31 -04002719 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002720 impl ToTokens for PatTuple {
2721 fn to_tokens(&self, tokens: &mut Tokens) {
2722 self.paren_token.surround(tokens, |tokens| {
2723 for (i, token) in self.pats.iter().enumerate() {
2724 if Some(i) == self.dots_pos {
2725 self.dot2_token.to_tokens(tokens);
2726 self.comma_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002727 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002728 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002729 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002730
2731 if Some(self.pats.len()) == self.dots_pos {
2732 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002733 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002734 });
2735 }
2736 }
2737
Michael Layzell734adb42017-06-07 16:58:31 -04002738 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002739 impl ToTokens for PatBox {
2740 fn to_tokens(&self, tokens: &mut Tokens) {
2741 self.box_token.to_tokens(tokens);
2742 self.pat.to_tokens(tokens);
2743 }
2744 }
2745
Michael Layzell734adb42017-06-07 16:58:31 -04002746 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002747 impl ToTokens for PatRef {
2748 fn to_tokens(&self, tokens: &mut Tokens) {
2749 self.and_token.to_tokens(tokens);
2750 self.mutbl.to_tokens(tokens);
2751 self.pat.to_tokens(tokens);
2752 }
2753 }
2754
Michael Layzell734adb42017-06-07 16:58:31 -04002755 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002756 impl ToTokens for PatLit {
2757 fn to_tokens(&self, tokens: &mut Tokens) {
2758 self.expr.to_tokens(tokens);
2759 }
2760 }
2761
Michael Layzell734adb42017-06-07 16:58:31 -04002762 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002763 impl ToTokens for PatRange {
2764 fn to_tokens(&self, tokens: &mut Tokens) {
2765 self.lo.to_tokens(tokens);
2766 self.limits.to_tokens(tokens);
2767 self.hi.to_tokens(tokens);
2768 }
2769 }
2770
Michael Layzell734adb42017-06-07 16:58:31 -04002771 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002772 impl ToTokens for PatSlice {
2773 fn to_tokens(&self, tokens: &mut Tokens) {
2774 self.bracket_token.surround(tokens, |tokens| {
2775 self.front.to_tokens(tokens);
2776 self.middle.to_tokens(tokens);
2777 self.dot2_token.to_tokens(tokens);
2778 self.comma_token.to_tokens(tokens);
2779 self.back.to_tokens(tokens);
2780 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002781 }
2782 }
2783
Michael Layzell734adb42017-06-07 16:58:31 -04002784 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002785 impl ToTokens for RangeLimits {
2786 fn to_tokens(&self, tokens: &mut Tokens) {
2787 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002788 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2789 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002790 }
2791 }
2792 }
2793
Michael Layzell734adb42017-06-07 16:58:31 -04002794 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002795 impl ToTokens for FieldPat {
2796 fn to_tokens(&self, tokens: &mut Tokens) {
2797 if !self.is_shorthand {
2798 self.ident.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002799 self.colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002800 }
2801 self.pat.to_tokens(tokens);
2802 }
2803 }
2804
Michael Layzell734adb42017-06-07 16:58:31 -04002805 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002806 impl ToTokens for BindingMode {
2807 fn to_tokens(&self, tokens: &mut Tokens) {
2808 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002809 BindingMode::ByRef(ref t, ref m) => {
2810 t.to_tokens(tokens);
2811 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002812 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002813 BindingMode::ByValue(ref m) => {
2814 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002815 }
2816 }
2817 }
2818 }
David Tolnay42602292016-10-01 22:25:45 -07002819
Michael Layzell734adb42017-06-07 16:58:31 -04002820 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002821 impl ToTokens for CaptureBy {
2822 fn to_tokens(&self, tokens: &mut Tokens) {
2823 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002824 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002825 CaptureBy::Ref => {
2826 // nothing
2827 }
David Tolnay89e05672016-10-02 14:39:42 -07002828 }
2829 }
2830 }
2831
Michael Layzell734adb42017-06-07 16:58:31 -04002832 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002833 impl ToTokens for Block {
2834 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002835 self.brace_token.surround(tokens, |tokens| {
2836 tokens.append_all(&self.stmts);
2837 });
David Tolnay42602292016-10-01 22:25:45 -07002838 }
2839 }
2840
Michael Layzell734adb42017-06-07 16:58:31 -04002841 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002842 impl ToTokens for Stmt {
2843 fn to_tokens(&self, tokens: &mut Tokens) {
2844 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002845 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002846 Stmt::Item(ref item) => item.to_tokens(tokens),
2847 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002848 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002849 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002850 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002851 }
David Tolnay13b3d352016-10-03 00:31:15 -07002852 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002853 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002854 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002855 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002856 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002857 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002858 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2859 // no semicolon
2860 }
David Tolnay13b3d352016-10-03 00:31:15 -07002861 }
2862 }
David Tolnay42602292016-10-01 22:25:45 -07002863 }
2864 }
2865 }
David Tolnay191e0582016-10-02 18:31:09 -07002866
Michael Layzell734adb42017-06-07 16:58:31 -04002867 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002868 impl ToTokens for Local {
2869 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002870 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002871 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002872 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002873 self.colon_token.to_tokens(tokens);
2874 self.ty.to_tokens(tokens);
2875 self.eq_token.to_tokens(tokens);
2876 self.init.to_tokens(tokens);
2877 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002878 }
2879 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07002880}