blob: 1356fa864229b1bcfdff9fdb288dded100ab5ced [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf4bbbd92016-09-23 14:41:55 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An expression.
6 pub struct Expr {
7 /// Type of the expression.
8 pub node: ExprKind,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the expression.
11 pub attrs: Vec<Attribute>,
12 }
David Tolnay7184b132016-10-30 10:06:37 -070013}
14
15impl From<ExprKind> for Expr {
16 fn from(node: ExprKind) -> Expr {
17 Expr {
18 node: node,
19 attrs: Vec::new(),
20 }
21 }
22}
23
Alex Crichton62a0a592017-05-22 13:58:53 -070024ast_enum_of_structs! {
25 pub enum ExprKind {
26 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Box(ExprBox #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070028 pub expr: Box<Expr>,
Alex Crichton954046c2017-05-30 21:49:42 -070029 pub box_token: tokens::Box_,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Michael Layzellb78f3b52017-06-04 19:03:03 -040032 /// E.g. 'place <- val' or `in place { val }`.
Michael Layzell734adb42017-06-07 16:58:31 -040033 pub InPlace(ExprInPlace #full {
Alex Crichton62a0a592017-05-22 13:58:53 -070034 pub place: Box<Expr>,
Michael Layzell6a5a1642017-06-04 19:35:15 -040035 pub kind: InPlaceKind,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub value: Box<Expr>,
37 }),
Clar Charrd22b5702017-03-10 15:24:56 -050038
Alex Crichton62a0a592017-05-22 13:58:53 -070039 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040040 pub Array(ExprArray #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 pub exprs: Delimited<Expr, tokens::Comma>,
42 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -070043 }),
Clar Charrd22b5702017-03-10 15:24:56 -050044
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// A function call.
46 pub Call(ExprCall {
47 pub func: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 pub args: Delimited<Expr, tokens::Comma>,
49 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -070050 }),
Clar Charrd22b5702017-03-10 15:24:56 -050051
Alex Crichton62a0a592017-05-22 13:58:53 -070052 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
53 ///
54 /// The `Ident` is the identifier for the method name.
55 /// The vector of `Ty`s are the ascripted type parameters for the method
56 /// (within the angle brackets).
57 ///
Alex Crichton62a0a592017-05-22 13:58:53 -070058 /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
59 /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`.
Michael Layzell734adb42017-06-07 16:58:31 -040060 pub MethodCall(ExprMethodCall #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070061 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070062 pub method: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070063 pub typarams: Delimited<Ty, tokens::Comma>,
64 pub args: Delimited<Expr, tokens::Comma>,
65 pub paren_token: tokens::Paren,
66 pub dot_token: tokens::Dot,
67 pub lt_token: Option<tokens::Lt>,
68 pub colon2_token: Option<tokens::Colon2>,
69 pub gt_token: Option<tokens::Gt>,
Alex Crichton62a0a592017-05-22 13:58:53 -070070 }),
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// A tuple, e.g. `(a, b, c, d)`.
Michael Layzell734adb42017-06-07 16:58:31 -040073 pub Tup(ExprTup #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070074 pub args: Delimited<Expr, tokens::Comma>,
75 pub paren_token: tokens::Paren,
76 pub lone_comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// A binary operation, e.g. `a + b`, `a * b`.
80 pub Binary(ExprBinary {
81 pub op: BinOp,
82 pub left: Box<Expr>,
83 pub right: Box<Expr>,
84 }),
Clar Charrd22b5702017-03-10 15:24:56 -050085
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// A unary operation, e.g. `!x`, `*x`.
87 pub Unary(ExprUnary {
88 pub op: UnOp,
89 pub expr: Box<Expr>,
90 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A literal, e.g. `1`, `"foo"`.
93 pub Lit(Lit),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A cast, e.g. `foo as f64`.
96 pub Cast(ExprCast {
97 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070098 pub as_token: tokens::As,
Alex Crichton62a0a592017-05-22 13:58:53 -070099 pub ty: Box<Ty>,
100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// A type ascription, e.g. `foo: f64`.
103 pub Type(ExprType {
104 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700105 pub colon_token: tokens::Colon,
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 pub ty: Box<Ty>,
107 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500108
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 /// An `if` block, with an optional else block
110 ///
111 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400112 pub If(ExprIf #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700113 pub cond: Box<Expr>,
114 pub if_true: Block,
115 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 pub if_token: tokens::If,
117 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700118 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500119
Alex Crichton62a0a592017-05-22 13:58:53 -0700120 /// An `if let` expression with an optional else block
121 ///
122 /// E.g., `if let pat = expr { block } else { expr }`
123 ///
124 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400125 pub IfLet(ExprIfLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 pub pat: Box<Pat>,
127 pub expr: Box<Expr>,
128 pub if_true: Block,
129 pub if_false: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700130 pub if_token: tokens::If,
131 pub let_token: tokens::Let,
132 pub eq_token: tokens::Eq,
133 pub else_token: Option<tokens::Else>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700134 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500135
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 /// A while loop, with an optional label
137 ///
138 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400139 pub While(ExprWhile #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 pub cond: Box<Expr>,
141 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700142 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 pub colon_token: Option<tokens::Colon>,
144 pub while_token: tokens::While,
Alex Crichton62a0a592017-05-22 13:58:53 -0700145 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500146
Alex Crichton62a0a592017-05-22 13:58:53 -0700147 /// A while-let loop, with an optional label.
148 ///
149 /// E.g., `'label: while let pat = expr { block }`
150 ///
151 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400152 pub WhileLet(ExprWhileLet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 pub pat: Box<Pat>,
154 pub expr: Box<Expr>,
155 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700156 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700157 pub colon_token: Option<tokens::Colon>,
158 pub while_token: tokens::While,
159 pub let_token: tokens::Let,
160 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700161 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500162
Alex Crichton62a0a592017-05-22 13:58:53 -0700163 /// A for loop, with an optional label.
164 ///
165 /// E.g., `'label: for pat in expr { block }`
166 ///
167 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400168 pub ForLoop(ExprForLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
170 pub expr: Box<Expr>,
171 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700172 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700173 pub for_token: tokens::For,
174 pub colon_token: Option<tokens::Colon>,
175 pub in_token: tokens::In,
Alex Crichton62a0a592017-05-22 13:58:53 -0700176 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500177
Alex Crichton62a0a592017-05-22 13:58:53 -0700178 /// Conditionless loop with an optional label.
179 ///
180 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400181 pub Loop(ExprLoop #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 pub body: Block,
David Tolnay63e3dee2017-06-03 20:13:17 -0700183 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700184 pub loop_token: tokens::Loop,
185 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500187
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400189 pub Match(ExprMatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 pub match_token: tokens::Match,
191 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub expr: Box<Expr>,
193 pub arms: Vec<Arm>,
194 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500195
Alex Crichton62a0a592017-05-22 13:58:53 -0700196 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400197 pub Closure(ExprClosure #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700198 pub capture: CaptureBy,
199 pub decl: Box<FnDecl>,
200 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700201 pub or1_token: tokens::Or,
202 pub or2_token: tokens::Or,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Alex Crichton62a0a592017-05-22 13:58:53 -0700205 /// A block (`{ ... }` or `unsafe { ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400206 pub Block(ExprBlock #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700207 pub unsafety: Unsafety,
208 pub block: Block,
209 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700210
Alex Crichton62a0a592017-05-22 13:58:53 -0700211 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400212 pub Assign(ExprAssign #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub left: Box<Expr>,
214 pub right: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700215 pub eq_token: tokens::Eq,
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500217
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 /// An assignment with an operator
219 ///
220 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400221 pub AssignOp(ExprAssignOp #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub op: BinOp,
223 pub left: Box<Expr>,
224 pub right: Box<Expr>,
225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// Access of a named struct field (`obj.foo`)
Michael Layzell734adb42017-06-07 16:58:31 -0400228 pub Field(ExprField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 pub expr: Box<Expr>,
230 pub field: Ident,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500233
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 /// Access of an unnamed field of a struct or tuple-struct
235 ///
236 /// For example, `foo.0`.
Michael Layzell734adb42017-06-07 16:58:31 -0400237 pub TupField(ExprTupField #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700238 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700239 pub field: Lit,
240 pub dot_token: tokens::Dot,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500242
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 /// An indexing operation (`foo[2]`)
244 pub Index(ExprIndex {
245 pub expr: Box<Expr>,
246 pub index: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 pub bracket_token: tokens::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500249
Alex Crichton62a0a592017-05-22 13:58:53 -0700250 /// A range (`1..2`, `1..`, `..2`, `1...2`, `1...`, `...2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400251 pub Range(ExprRange #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 pub from: Option<Box<Expr>>,
253 pub to: Option<Box<Expr>>,
254 pub limits: RangeLimits,
255 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700256
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 /// Variable reference, possibly containing `::` and/or type
258 /// parameters, e.g. foo::bar::<baz>.
259 ///
260 /// Optionally "qualified",
261 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
262 pub Path(ExprPath {
263 pub qself: Option<QSelf>,
264 pub path: Path,
265 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700266
Alex Crichton62a0a592017-05-22 13:58:53 -0700267 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400268 pub AddrOf(ExprAddrOf #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 pub and_token: tokens::And,
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 pub mutbl: Mutability,
271 pub expr: Box<Expr>,
272 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500273
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400275 pub Break(ExprBreak #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700276 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700278 pub break_token: tokens::Break,
Alex Crichton62a0a592017-05-22 13:58:53 -0700279 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500280
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400282 pub Continue(ExprContinue #full {
David Tolnay63e3dee2017-06-03 20:13:17 -0700283 pub label: Option<Lifetime>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 pub continue_token: tokens::Continue,
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500286
Alex Crichton62a0a592017-05-22 13:58:53 -0700287 /// A `return`, with an optional value to be returned
Michael Layzell734adb42017-06-07 16:58:31 -0400288 pub Ret(ExprRet #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 pub expr: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700290 pub return_token: tokens::Return,
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700292
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 /// A macro invocation; pre-expansion
294 pub Mac(Mac),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700295
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 /// A struct literal expression.
297 ///
298 /// For example, `Foo {x: 1, y: 2}`, or
299 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400300 pub Struct(ExprStruct #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 pub path: Path,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 pub fields: Delimited<FieldValue, tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 pub rest: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700304 pub dot2_token: Option<tokens::Dot2>,
305 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700307
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 /// An array literal constructed from one repeated element.
309 ///
310 /// For example, `[1; 5]`. The first expression is the element
311 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400312 pub Repeat(ExprRepeat #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700313 pub bracket_token: tokens::Bracket,
314 pub semi_token: tokens::Semi,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub expr: Box<Expr>,
316 pub amt: Box<Expr>,
317 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700318
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 /// No-op: used solely so we can pretty-print faithfully
320 pub Paren(ExprParen {
321 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700322 pub paren_token: tokens::Paren,
Alex Crichton62a0a592017-05-22 13:58:53 -0700323 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700324
Michael Layzell93c36282017-06-04 20:43:14 -0400325 /// No-op: used solely so we can pretty-print faithfully
326 ///
327 /// A `group` represents a `None`-delimited span in the input
328 /// `TokenStream` which affects the precidence of the resulting
329 /// expression. They are used for macro hygiene.
330 pub Group(ExprGroup {
331 pub expr: Box<Expr>,
332 pub group_token: tokens::Group,
333 }),
334
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400336 pub Try(ExprTry #full {
Alex Crichton62a0a592017-05-22 13:58:53 -0700337 pub expr: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700338 pub question_token: tokens::Question,
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700340
Alex Crichton62a0a592017-05-22 13:58:53 -0700341 /// A catch expression.
342 ///
343 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400344 pub Catch(ExprCatch #full {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700345 pub do_token: tokens::Do,
346 pub catch_token: tokens::Catch,
Alex Crichton62a0a592017-05-22 13:58:53 -0700347 pub block: Block,
348 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700349
350 /// A yield expression.
351 ///
352 /// E.g. `yield expr`
353 pub Yield(ExprYield #full {
354 pub yield_token: tokens::Yield,
355 pub expr: Option<Box<Expr>>,
356 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700358}
359
Michael Layzell734adb42017-06-07 16:58:31 -0400360#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700361ast_struct! {
362 /// A field-value pair in a struct literal.
363 pub struct FieldValue {
364 /// Name of the field.
365 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -0500366
Alex Crichton62a0a592017-05-22 13:58:53 -0700367 /// Value of the field.
368 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500369
Alex Crichton62a0a592017-05-22 13:58:53 -0700370 /// Whether this is a shorthand field, e.g. `Struct { x }`
371 /// instead of `Struct { x: x }`.
372 pub is_shorthand: bool,
Clar Charrd22b5702017-03-10 15:24:56 -0500373
Alex Crichton62a0a592017-05-22 13:58:53 -0700374 /// Attributes tagged on the field.
375 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700376
377 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700378 }
David Tolnay055a7042016-10-02 19:23:54 -0700379}
380
Michael Layzell734adb42017-06-07 16:58:31 -0400381#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700382ast_struct! {
383 /// A Block (`{ .. }`).
384 ///
385 /// E.g. `{ .. }` as in `fn foo() { .. }`
386 pub struct Block {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700387 pub brace_token: tokens::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700388 /// Statements in a block
389 pub stmts: Vec<Stmt>,
390 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700391}
392
Michael Layzell734adb42017-06-07 16:58:31 -0400393#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700394ast_enum! {
395 /// A statement, usually ending in a semicolon.
396 pub enum Stmt {
397 /// A local (let) binding.
398 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700399
Alex Crichton62a0a592017-05-22 13:58:53 -0700400 /// An item definition.
401 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700402
Alex Crichton62a0a592017-05-22 13:58:53 -0700403 /// Expr without trailing semicolon.
404 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700405
Alex Crichton62a0a592017-05-22 13:58:53 -0700406 /// Expression with trailing semicolon;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700407 Semi(Box<Expr>, tokens::Semi),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700408
Alex Crichton62a0a592017-05-22 13:58:53 -0700409 /// Macro invocation.
410 Mac(Box<(Mac, MacStmtStyle, Vec<Attribute>)>),
411 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700412}
413
Michael Layzell734adb42017-06-07 16:58:31 -0400414#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700415ast_enum! {
416 /// How a macro was invoked.
Alex Crichton2e0229c2017-05-23 09:34:50 -0700417 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700418 pub enum MacStmtStyle {
419 /// The macro statement had a trailing semicolon, e.g. `foo! { ... };`
420 /// `foo!(...);`, `foo![...];`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700421 Semicolon(tokens::Semi),
Clar Charrd22b5702017-03-10 15:24:56 -0500422
Alex Crichton62a0a592017-05-22 13:58:53 -0700423 /// The macro statement had braces; e.g. foo! { ... }
424 Braces,
Clar Charrd22b5702017-03-10 15:24:56 -0500425
Alex Crichton62a0a592017-05-22 13:58:53 -0700426 /// The macro statement had parentheses or brackets and no semicolon; e.g.
427 /// `foo!(...)`. All of these will end up being converted into macro
428 /// expressions.
429 NoBraces,
430 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700431}
432
Michael Layzell734adb42017-06-07 16:58:31 -0400433#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700434ast_struct! {
435 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
436 pub struct Local {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700437 pub let_token: tokens::Let,
438 pub colon_token: Option<tokens::Colon>,
439 pub eq_token: Option<tokens::Eq>,
440 pub semi_token: tokens::Semi,
441
Alex Crichton62a0a592017-05-22 13:58:53 -0700442 pub pat: Box<Pat>,
443 pub ty: Option<Box<Ty>>,
Clar Charrd22b5702017-03-10 15:24:56 -0500444
Alex Crichton62a0a592017-05-22 13:58:53 -0700445 /// Initializer expression to set the value, if any
446 pub init: Option<Box<Expr>>,
447 pub attrs: Vec<Attribute>,
448 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700449}
450
Michael Layzell734adb42017-06-07 16:58:31 -0400451#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700452ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700453 // Clippy false positive
454 // https://github.com/Manishearth/rust-clippy/issues/1241
455 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
456 pub enum Pat {
457 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700458 pub Wild(PatWild {
459 pub underscore_token: tokens::Underscore,
460 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700461
Alex Crichton62a0a592017-05-22 13:58:53 -0700462 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
463 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
464 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
465 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700466 pub Ident(PatIdent {
467 pub mode: BindingMode,
468 pub ident: Ident,
469 pub subpat: Option<Box<Pat>>,
470 pub at_token: Option<tokens::At>,
471 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700472
Alex Crichton62a0a592017-05-22 13:58:53 -0700473 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
474 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700475 pub Struct(PatStruct {
476 pub path: Path,
477 pub fields: Delimited<FieldPat, tokens::Comma>,
478 pub brace_token: tokens::Brace,
479 pub dot2_token: Option<tokens::Dot2>,
480 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700481
Alex Crichton62a0a592017-05-22 13:58:53 -0700482 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
483 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
484 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700485 pub TupleStruct(PatTupleStruct {
486 pub path: Path,
487 pub pat: PatTuple,
488 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700489
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A possibly qualified path pattern.
491 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
492 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
493 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700494 pub Path(PatPath {
495 pub qself: Option<QSelf>,
496 pub path: Path,
497 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700498
Alex Crichton62a0a592017-05-22 13:58:53 -0700499 /// A tuple pattern `(a, b)`.
500 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
501 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700502 pub Tuple(PatTuple {
503 pub pats: Delimited<Pat, tokens::Comma>,
504 pub dots_pos: Option<usize>,
505 pub paren_token: tokens::Paren,
506 pub dot2_token: Option<tokens::Dot2>,
507 pub comma_token: Option<tokens::Comma>,
508 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700509 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700510 pub Box(PatBox {
511 pub pat: Box<Pat>,
Alex Crichton954046c2017-05-30 21:49:42 -0700512 pub box_token: tokens::Box_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700513 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700514 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700515 pub Ref(PatRef {
516 pub pat: Box<Pat>,
517 pub mutbl: Mutability,
518 pub and_token: tokens::And,
519 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700520 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700521 pub Lit(PatLit {
522 pub expr: Box<Expr>,
523 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700524 /// A range pattern, e.g. `1...2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700525 pub Range(PatRange {
526 pub lo: Box<Expr>,
527 pub hi: Box<Expr>,
528 pub limits: RangeLimits,
529 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400530 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700531 pub Slice(PatSlice {
532 pub front: Delimited<Pat, tokens::Comma>,
533 pub middle: Option<Box<Pat>>,
534 pub back: Delimited<Pat, tokens::Comma>,
535 pub dot2_token: Option<tokens::Dot2>,
536 pub comma_token: Option<tokens::Comma>,
537 pub bracket_token: tokens::Bracket,
538 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// A macro pattern; pre-expansion
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700540 pub Mac(Mac),
Alex Crichton62a0a592017-05-22 13:58:53 -0700541 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700542}
543
Michael Layzell734adb42017-06-07 16:58:31 -0400544#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700545ast_struct! {
546 /// An arm of a 'match'.
547 ///
548 /// E.g. `0...10 => { println!("match!") }` as in
549 ///
550 /// ```rust,ignore
551 /// match n {
552 /// 0...10 => { println!("match!") },
553 /// // ..
554 /// }
555 /// ```
556 pub struct Arm {
557 pub attrs: Vec<Attribute>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558 pub pats: Delimited<Pat, tokens::Or>,
559 pub if_token: Option<tokens::If>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700560 pub guard: Option<Box<Expr>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700561 pub rocket_token: tokens::Rocket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 pub body: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700563 pub comma: Option<tokens::Comma>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700564 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700565}
566
Michael Layzell734adb42017-06-07 16:58:31 -0400567#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700568ast_enum! {
569 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700570 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 pub enum CaptureBy {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 Value(tokens::Move),
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 Ref,
574 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700575}
576
Michael Layzell734adb42017-06-07 16:58:31 -0400577#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700578ast_enum! {
579 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700580 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700581 pub enum RangeLimits {
582 /// Inclusive at the beginning, exclusive at the end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700583 HalfOpen(tokens::Dot2),
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 /// Inclusive at the beginning and end
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700585 Closed(tokens::Dot3),
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587}
588
Michael Layzell734adb42017-06-07 16:58:31 -0400589#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700590ast_struct! {
591 /// A single field in a struct pattern
592 ///
593 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
594 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
595 /// except `is_shorthand` is true
596 pub struct FieldPat {
597 /// The identifier for the field
598 pub ident: Ident,
599 /// The pattern the field is destructured to
600 pub pat: Box<Pat>,
601 pub is_shorthand: bool,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700602 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 pub attrs: Vec<Attribute>,
604 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700605}
606
Michael Layzell734adb42017-06-07 16:58:31 -0400607#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700608ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700609 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700610 pub enum BindingMode {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700611 ByRef(tokens::Ref, Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700612 ByValue(Mutability),
613 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700614}
615
Michael Layzell734adb42017-06-07 16:58:31 -0400616#[cfg(feature = "full")]
Michael Layzell6a5a1642017-06-04 19:35:15 -0400617ast_enum! {
618 #[cfg_attr(feature = "clone-impls", derive(Copy))]
619 pub enum InPlaceKind {
620 Arrow(tokens::LArrow),
621 In(tokens::In),
622 }
623}
624
Michael Layzell3936ceb2017-07-08 00:28:36 -0400625#[cfg(any(feature = "parsing", feature = "printing"))]
626#[cfg(feature = "full")]
627fn arm_requires_comma(arm: &Arm) -> bool {
628 if let ExprKind::Block(ExprBlock { unsafety: Unsafety::Normal, .. }) = arm.body.node {
629 false
630 } else {
631 true
632 }
633}
634
David Tolnayb9c8e322016-09-23 20:48:37 -0700635#[cfg(feature = "parsing")]
636pub mod parsing {
637 use super::*;
Alex Crichton954046c2017-05-30 21:49:42 -0700638 use ty::parsing::qpath;
David Tolnayb9c8e322016-09-23 20:48:37 -0700639
Michael Layzell734adb42017-06-07 16:58:31 -0400640 #[cfg(feature = "full")]
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700641 use proc_macro2::{TokenStream, TokenNode, Delimiter, Term};
Michael Layzell734adb42017-06-07 16:58:31 -0400642 use synom::{PResult, Cursor, Synom};
643 #[cfg(feature = "full")]
644 use synom::parse_error;
Alex Crichton954046c2017-05-30 21:49:42 -0700645 use synom::tokens::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700646
Michael Layzellb78f3b52017-06-04 19:03:03 -0400647 /// When we're parsing expressions which occur before blocks, like in
648 /// an if statement's condition, we cannot parse a struct literal.
649 ///
650 /// Struct literals are ambiguous in certain positions
651 /// https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700652 macro_rules! ambiguous_expr {
653 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700654 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700655 };
656 }
657
Michael Layzellb78f3b52017-06-04 19:03:03 -0400658 /// When we are parsing an optional suffix expression, we cannot allow
659 /// blocks if structs are not allowed.
660 ///
661 /// Example:
662 /// ```ignore
663 /// if break { } { }
664 /// // is ambiguous between:
665 /// if (break { }) { }
666 /// // - or -
667 /// if (break) { } { }
668 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -0400669 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400670 macro_rules! opt_ambiguous_expr {
671 ($i:expr, $allow_struct:ident) => {
672 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
673 };
674 }
675
Alex Crichton954046c2017-05-30 21:49:42 -0700676 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400677 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700678
679 fn description() -> Option<&'static str> {
680 Some("expression")
681 }
682 }
683
Michael Layzell734adb42017-06-07 16:58:31 -0400684 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700685 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
686
Michael Layzellb78f3b52017-06-04 19:03:03 -0400687 /// Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400688 #[cfg(feature = "full")]
689 fn ambiguous_expr(i: Cursor,
690 allow_struct: bool,
691 allow_block: bool)
692 -> PResult<Expr> {
Michael Layzellb78f3b52017-06-04 19:03:03 -0400693 map!(
David Tolnay54e854d2016-10-24 12:03:30 -0700694 i,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400695 call!(assign_expr, allow_struct, allow_block),
696 ExprKind::into
697 )
698 }
699
Michael Layzell734adb42017-06-07 16:58:31 -0400700 #[cfg(not(feature = "full"))]
701 fn ambiguous_expr(i: Cursor,
702 allow_struct: bool,
703 allow_block: bool)
704 -> PResult<Expr> {
705 map!(
706 i,
707 // NOTE: We intentionally skip assign_expr, placement_expr, and
708 // range_expr, as they are not parsed in non-full mode.
709 call!(or_expr, allow_struct, allow_block),
710 ExprKind::into
711 )
712 }
713
Michael Layzellb78f3b52017-06-04 19:03:03 -0400714 /// Parse a left-associative binary operator.
715 macro_rules! binop {
716 (
717 $name: ident,
718 $next: ident,
719 $submac: ident!( $($args:tt)* )
720 ) => {
721 named!($name(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
722 mut e: call!($next, allow_struct, allow_block) >>
723 many0!(do_parse!(
724 op: $submac!($($args)*) >>
725 rhs: call!($next, allow_struct, true) >>
726 ({
727 e = ExprBinary {
728 left: Box::new(e.into()),
729 op: op,
730 right: Box::new(rhs.into()),
731 }.into();
732 })
733 )) >>
734 (e)
735 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700736 }
David Tolnay54e854d2016-10-24 12:03:30 -0700737 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700738
Michael Layzellb78f3b52017-06-04 19:03:03 -0400739 /// ```ignore
740 /// <placement> = <placement> ..
741 /// <placement> += <placement> ..
742 /// <placement> -= <placement> ..
743 /// <placement> *= <placement> ..
744 /// <placement> /= <placement> ..
745 /// <placement> %= <placement> ..
746 /// <placement> ^= <placement> ..
747 /// <placement> &= <placement> ..
748 /// <placement> |= <placement> ..
749 /// <placement> <<= <placement> ..
750 /// <placement> >>= <placement> ..
751 /// ```
752 ///
753 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400754 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400755 named!(assign_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
756 mut e: call!(placement_expr, allow_struct, allow_block) >>
757 alt!(
758 do_parse!(
759 eq: syn!(Eq) >>
760 // Recurse into self to parse right-associative operator.
761 rhs: call!(assign_expr, allow_struct, true) >>
762 ({
763 e = ExprAssign {
764 left: Box::new(e.into()),
765 eq_token: eq,
766 right: Box::new(rhs.into()),
767 }.into();
768 })
769 )
770 |
771 do_parse!(
772 op: call!(BinOp::parse_assign_op) >>
773 // Recurse into self to parse right-associative operator.
774 rhs: call!(assign_expr, allow_struct, true) >>
775 ({
776 e = ExprAssignOp {
777 left: Box::new(e.into()),
778 op: op,
779 right: Box::new(rhs.into()),
780 }.into();
781 })
782 )
783 |
784 epsilon!()
785 ) >>
786 (e)
787 ));
788
789 /// ```ignore
790 /// <range> <- <range> ..
791 /// ```
792 ///
793 /// NOTE: The `in place { expr }` version of this syntax is parsed in
794 /// `atom_expr`, not here.
795 ///
796 /// NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400797 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400798 named!(placement_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
799 mut e: call!(range_expr, allow_struct, allow_block) >>
800 alt!(
801 do_parse!(
Michael Layzell6a5a1642017-06-04 19:35:15 -0400802 arrow: syn!(LArrow) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400803 // Recurse into self to parse right-associative operator.
804 rhs: call!(placement_expr, allow_struct, true) >>
805 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400806 e = ExprInPlace {
807 // op: BinOp::Place(larrow),
808 place: Box::new(e.into()),
Michael Layzell6a5a1642017-06-04 19:35:15 -0400809 kind: InPlaceKind::Arrow(arrow),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400810 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400811 }.into();
812 })
813 )
814 |
815 epsilon!()
816 ) >>
817 (e)
818 ));
819
820 /// ```ignore
821 /// <or> ... <or> ..
822 /// <or> .. <or> ..
823 /// <or> ..
824 /// ```
825 ///
826 /// NOTE: This is currently parsed oddly - I'm not sure of what the exact
827 /// rules are for parsing these expressions are, but this is not correct.
828 /// For example, `a .. b .. c` is not a legal expression. It should not
829 /// be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
830 ///
831 /// NOTE: The form of ranges which don't include a preceding expression are
832 /// parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400833 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400834 named!(range_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
835 mut e: call!(or_expr, allow_struct, allow_block) >>
836 many0!(do_parse!(
837 limits: syn!(RangeLimits) >>
838 // We don't want to allow blocks here if we don't allow structs. See
839 // the reasoning for `opt_ambiguous_expr!` above.
840 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
841 ({
842 e = ExprRange {
843 from: Some(Box::new(e.into())),
844 limits: limits,
845 to: hi.map(|e| Box::new(e.into())),
846 }.into();
847 })
848 )) >>
849 (e)
850 ));
851
852 /// ```ignore
853 /// <and> || <and> ...
854 /// ```
855 binop!(or_expr, and_expr, map!(syn!(OrOr), BinOp::Or));
856
857 /// ```ignore
858 /// <compare> && <compare> ...
859 /// ```
860 binop!(and_expr, compare_expr, map!(syn!(AndAnd), BinOp::And));
861
862 /// ```ignore
863 /// <bitor> == <bitor> ...
864 /// <bitor> != <bitor> ...
865 /// <bitor> >= <bitor> ...
866 /// <bitor> <= <bitor> ...
867 /// <bitor> > <bitor> ...
868 /// <bitor> < <bitor> ...
869 /// ```
870 ///
871 /// NOTE: This operator appears to be parsed as left-associative, but errors
872 /// if it is used in a non-associative manner.
873 binop!(compare_expr, bitor_expr, alt!(
874 syn!(EqEq) => { BinOp::Eq }
875 |
876 syn!(Ne) => { BinOp::Ne }
877 |
878 // must be above Lt
879 syn!(Le) => { BinOp::Le }
880 |
881 // must be above Gt
882 syn!(Ge) => { BinOp::Ge }
883 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400884 do_parse!(
885 // Make sure that we don't eat the < part of a <- operator
886 not!(syn!(LArrow)) >>
887 t: syn!(Lt) >>
888 (BinOp::Lt(t))
889 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400890 |
891 syn!(Gt) => { BinOp::Gt }
892 ));
893
894 /// ```ignore
895 /// <bitxor> | <bitxor> ...
896 /// ```
897 binop!(bitor_expr, bitxor_expr, do_parse!(
898 not!(syn!(OrOr)) >>
899 not!(syn!(OrEq)) >>
900 t: syn!(Or) >>
901 (BinOp::BitOr(t))
902 ));
903
904 /// ```ignore
905 /// <bitand> ^ <bitand> ...
906 /// ```
907 binop!(bitxor_expr, bitand_expr, do_parse!(
908 // NOTE: Make sure we aren't looking at ^=.
909 not!(syn!(CaretEq)) >>
910 t: syn!(Caret) >>
911 (BinOp::BitXor(t))
912 ));
913
914 /// ```ignore
915 /// <shift> & <shift> ...
916 /// ```
917 binop!(bitand_expr, shift_expr, do_parse!(
918 // NOTE: Make sure we aren't looking at && or &=.
919 not!(syn!(AndAnd)) >>
920 not!(syn!(AndEq)) >>
921 t: syn!(And) >>
922 (BinOp::BitAnd(t))
923 ));
924
925 /// ```ignore
926 /// <arith> << <arith> ...
927 /// <arith> >> <arith> ...
928 /// ```
929 binop!(shift_expr, arith_expr, alt!(
930 syn!(Shl) => { BinOp::Shl }
931 |
932 syn!(Shr) => { BinOp::Shr }
933 ));
934
935 /// ```ignore
936 /// <term> + <term> ...
937 /// <term> - <term> ...
938 /// ```
939 binop!(arith_expr, term_expr, alt!(
940 syn!(Add) => { BinOp::Add }
941 |
942 syn!(Sub) => { BinOp::Sub }
943 ));
944
945 /// ```ignore
946 /// <cast> * <cast> ...
947 /// <cast> / <cast> ...
948 /// <cast> % <cast> ...
949 /// ```
950 binop!(term_expr, cast_expr, alt!(
951 syn!(Star) => { BinOp::Mul }
952 |
953 syn!(Div) => { BinOp::Div }
954 |
955 syn!(Rem) => { BinOp::Rem }
956 ));
957
958 /// ```ignore
959 /// <unary> as <ty>
960 /// <unary> : <ty>
961 /// ```
962 named!(cast_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
963 mut e: call!(unary_expr, allow_struct, allow_block) >>
964 many0!(alt!(
965 do_parse!(
966 as_: syn!(As) >>
967 // We can't accept `A + B` in cast expressions, as it's
968 // ambiguous with the + expression.
969 ty: call!(Ty::without_plus) >>
970 ({
971 e = ExprCast {
972 expr: Box::new(e.into()),
973 as_token: as_,
974 ty: Box::new(ty),
975 }.into();
976 })
977 )
978 |
979 do_parse!(
980 colon: syn!(Colon) >>
981 // We can't accept `A + B` in cast expressions, as it's
982 // ambiguous with the + expression.
983 ty: call!(Ty::without_plus) >>
984 ({
985 e = ExprType {
986 expr: Box::new(e.into()),
987 colon_token: colon,
988 ty: Box::new(ty),
989 }.into();
990 })
991 )
992 )) >>
993 (e)
994 ));
995
996 /// ```
997 /// <UnOp> <trailer>
998 /// & <trailer>
999 /// &mut <trailer>
1000 /// box <trailer>
1001 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001002 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001003 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1004 do_parse!(
1005 op: syn!(UnOp) >>
1006 expr: call!(unary_expr, allow_struct, true) >>
1007 (ExprUnary {
1008 op: op,
1009 expr: Box::new(expr.into()),
1010 }.into())
1011 )
1012 |
1013 do_parse!(
1014 and: syn!(And) >>
1015 mutability: syn!(Mutability) >>
1016 expr: call!(unary_expr, allow_struct, true) >>
1017 (ExprAddrOf {
1018 and_token: and,
1019 mutbl: mutability,
1020 expr: Box::new(expr.into()),
1021 }.into())
1022 )
1023 |
1024 do_parse!(
1025 box_: syn!(Box_) >>
1026 expr: call!(unary_expr, allow_struct, true) >>
1027 (ExprBox {
1028 box_token: box_,
1029 expr: Box::new(expr.into()),
1030 }.into())
1031 )
1032 |
1033 call!(trailer_expr, allow_struct, allow_block)
1034 ));
1035
Michael Layzell734adb42017-06-07 16:58:31 -04001036 // XXX: This duplication is ugly
1037 #[cfg(not(feature = "full"))]
1038 named!(unary_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
1039 do_parse!(
1040 op: syn!(UnOp) >>
1041 expr: call!(unary_expr, allow_struct, true) >>
1042 (ExprUnary {
1043 op: op,
1044 expr: Box::new(expr.into()),
1045 }.into())
1046 )
1047 |
1048 call!(trailer_expr, allow_struct, allow_block)
1049 ));
1050
Michael Layzellb78f3b52017-06-04 19:03:03 -04001051 /// ```ignore
1052 /// <atom> (..<args>) ...
1053 /// <atom> . <ident> (..<args>) ...
1054 /// <atom> . <ident> ...
1055 /// <atom> . <lit> ...
1056 /// <atom> [ <expr> ] ...
1057 /// <atom> ? ...
1058 /// ```
Michael Layzell734adb42017-06-07 16:58:31 -04001059 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001060 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1061 mut e: call!(atom_expr, allow_struct, allow_block) >>
1062 many0!(alt!(
1063 tap!(args: and_call => {
1064 let (args, paren) = args;
1065 e = ExprCall {
1066 func: Box::new(e.into()),
1067 args: args,
1068 paren_token: paren,
1069 }.into();
1070 })
1071 |
1072 tap!(more: and_method_call => {
1073 let mut call = more;
1074 call.expr = Box::new(e.into());
1075 e = call.into();
1076 })
1077 |
1078 tap!(field: and_field => {
1079 let (field, token) = field;
1080 e = ExprField {
1081 expr: Box::new(e.into()),
1082 field: field,
1083 dot_token: token,
1084 }.into();
1085 })
1086 |
1087 tap!(field: and_tup_field => {
1088 let (field, token) = field;
1089 e = ExprTupField {
1090 expr: Box::new(e.into()),
1091 field: field,
1092 dot_token: token,
1093 }.into();
1094 })
1095 |
1096 tap!(i: and_index => {
1097 let (i, token) = i;
1098 e = ExprIndex {
1099 expr: Box::new(e.into()),
1100 bracket_token: token,
1101 index: Box::new(i),
1102 }.into();
1103 })
1104 |
1105 tap!(question: syn!(Question) => {
1106 e = ExprTry {
1107 expr: Box::new(e.into()),
1108 question_token: question,
1109 }.into();
1110 })
1111 )) >>
1112 (e)
1113 ));
1114
Michael Layzell734adb42017-06-07 16:58:31 -04001115 // XXX: Duplication == ugly
1116 #[cfg(not(feature = "full"))]
1117 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> ExprKind, do_parse!(
1118 mut e: call!(atom_expr, allow_struct, allow_block) >>
1119 many0!(alt!(
1120 tap!(args: and_call => {
1121 let (args, paren) = args;
1122 e = ExprCall {
1123 func: Box::new(e.into()),
1124 args: args,
1125 paren_token: paren,
1126 }.into();
1127 })
1128 |
1129 tap!(i: and_index => {
1130 let (i, token) = i;
1131 e = ExprIndex {
1132 expr: Box::new(e.into()),
1133 bracket_token: token,
1134 index: Box::new(i),
1135 }.into();
1136 })
1137 )) >>
1138 (e)
1139 ));
1140
Michael Layzellb78f3b52017-06-04 19:03:03 -04001141 /// Parse all atomic expressions which don't have to worry about precidence
1142 /// interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001143 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001144 named!(atom_expr(allow_struct: bool, allow_block: bool) -> ExprKind, alt!(
Michael Layzell93c36282017-06-04 20:43:14 -04001145 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1146 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001147 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1148 |
1149 // must be before expr_path
1150 cond_reduce!(allow_struct, map!(syn!(ExprStruct), ExprKind::Struct))
1151 |
1152 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1153 |
1154 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1155 |
1156 call!(expr_break, allow_struct) // must be before expr_path
1157 |
1158 syn!(ExprContinue) => { ExprKind::Continue } // must be before expr_path
1159 |
1160 call!(expr_ret, allow_struct) // must be before expr_path
1161 |
1162 // NOTE: The `in place { expr }` form. `place <- expr` is parsed above.
1163 syn!(ExprInPlace) => { ExprKind::InPlace }
1164 |
1165 syn!(ExprArray) => { ExprKind::Array }
1166 |
1167 syn!(ExprTup) => { ExprKind::Tup }
1168 |
1169 syn!(ExprIf) => { ExprKind::If }
1170 |
1171 syn!(ExprIfLet) => { ExprKind::IfLet }
1172 |
1173 syn!(ExprWhile) => { ExprKind::While }
1174 |
1175 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1176 |
1177 syn!(ExprForLoop) => { ExprKind::ForLoop }
1178 |
1179 syn!(ExprLoop) => { ExprKind::Loop }
1180 |
1181 syn!(ExprMatch) => { ExprKind::Match }
1182 |
1183 syn!(ExprCatch) => { ExprKind::Catch }
1184 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001185 syn!(ExprYield) => { ExprKind::Yield }
1186 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001187 call!(expr_closure, allow_struct)
1188 |
1189 cond_reduce!(allow_block, map!(syn!(ExprBlock), ExprKind::Block))
1190 |
1191 // NOTE: This is the prefix-form of range
1192 call!(expr_range, allow_struct)
1193 |
1194 syn!(ExprPath) => { ExprKind::Path }
1195 |
1196 syn!(ExprRepeat) => { ExprKind::Repeat }
1197 ));
1198
Michael Layzell734adb42017-06-07 16:58:31 -04001199 #[cfg(not(feature = "full"))]
1200 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> ExprKind, alt!(
1201 syn!(ExprGroup) => { ExprKind::Group } // must be placed first
1202 |
1203 syn!(Lit) => { ExprKind::Lit } // must be before expr_struct
1204 |
1205 syn!(ExprParen) => { ExprKind::Paren } // must be before expr_tup
1206 |
1207 syn!(Mac) => { ExprKind::Mac } // must be before expr_path
1208 |
1209 syn!(ExprPath) => { ExprKind::Path }
1210 ));
1211
1212
1213 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001214 named!(expr_nosemi -> Expr, map!(alt!(
1215 syn!(ExprIf) => { ExprKind::If }
1216 |
1217 syn!(ExprIfLet) => { ExprKind::IfLet }
1218 |
1219 syn!(ExprWhile) => { ExprKind::While }
1220 |
1221 syn!(ExprWhileLet) => { ExprKind::WhileLet }
1222 |
1223 syn!(ExprForLoop) => { ExprKind::ForLoop }
1224 |
1225 syn!(ExprLoop) => { ExprKind::Loop }
1226 |
1227 syn!(ExprMatch) => { ExprKind::Match }
1228 |
1229 syn!(ExprCatch) => { ExprKind::Catch }
1230 |
Alex Crichtonfe110462017-06-01 12:49:27 -07001231 syn!(ExprYield) => { ExprKind::Yield }
1232 |
Michael Layzell35418782017-06-07 09:20:25 -04001233 syn!(ExprBlock) => { ExprKind::Block }
1234 ), Expr::from));
1235
Michael Layzell93c36282017-06-04 20:43:14 -04001236 impl Synom for ExprGroup {
1237 named!(parse -> Self, do_parse!(
1238 e: grouped!(syn!(Expr)) >>
1239 (ExprGroup {
1240 expr: Box::new(e.0),
1241 group_token: e.1,
1242 }.into())
1243 ));
1244 }
1245
Alex Crichton954046c2017-05-30 21:49:42 -07001246 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001247 named!(parse -> Self, do_parse!(
1248 e: parens!(syn!(Expr)) >>
1249 (ExprParen {
1250 expr: Box::new(e.0),
1251 paren_token: e.1,
1252 }.into())
1253 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001254 }
David Tolnay89e05672016-10-02 14:39:42 -07001255
Michael Layzell734adb42017-06-07 16:58:31 -04001256 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001257 impl Synom for ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001258 named!(parse -> Self, do_parse!(
1259 in_: syn!(In) >>
1260 place: expr_no_struct >>
1261 value: braces!(call!(Block::parse_within)) >>
1262 (ExprInPlace {
Michael Layzell92639a52017-06-01 00:07:44 -04001263 place: Box::new(place),
Michael Layzell6a5a1642017-06-04 19:35:15 -04001264 kind: InPlaceKind::In(in_),
Michael Layzell92639a52017-06-01 00:07:44 -04001265 value: Box::new(Expr {
1266 node: ExprBlock {
1267 unsafety: Unsafety::Normal,
1268 block: Block {
1269 stmts: value.0,
1270 brace_token: value.1,
1271 },
1272 }.into(),
1273 attrs: Vec::new(),
1274 }),
1275 })
1276 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001277 }
David Tolnay6696c3e2016-10-30 11:45:10 -07001278
Michael Layzell734adb42017-06-07 16:58:31 -04001279 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001280 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001281 named!(parse -> Self, do_parse!(
1282 elems: brackets!(call!(Delimited::parse_terminated)) >>
1283 (ExprArray {
1284 exprs: elems.0,
1285 bracket_token: elems.1,
1286 })
1287 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001288 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001289
Alex Crichton954046c2017-05-30 21:49:42 -07001290 named!(and_call -> (Delimited<Expr, tokens::Comma>, tokens::Paren),
1291 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001292
Michael Layzell734adb42017-06-07 16:58:31 -04001293 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001294 named!(and_method_call -> ExprMethodCall, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001295 dot: syn!(Dot) >>
1296 method: syn!(Ident) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001297 typarams: option!(do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001298 colon2: syn!(Colon2) >>
1299 lt: syn!(Lt) >>
1300 tys: call!(Delimited::parse_terminated) >>
1301 gt: syn!(Gt) >>
1302 (colon2, lt, tys, gt)
David Tolnayfa0edf22016-09-23 22:58:24 -07001303 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001304 args: parens!(call!(Delimited::parse_terminated)) >>
1305 ({
1306 let (colon2, lt, tys, gt) = match typarams {
1307 Some((a, b, c, d)) => (Some(a), Some(b), Some(c), Some(d)),
1308 None => (None, None, None, None),
1309 };
1310 ExprMethodCall {
1311 // this expr will get overwritten after being returned
1312 expr: Box::new(ExprKind::Lit(Lit {
1313 span: Span::default(),
1314 value: LitKind::Bool(false),
1315 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001316
Alex Crichton954046c2017-05-30 21:49:42 -07001317 method: method,
1318 args: args.0,
1319 paren_token: args.1,
1320 dot_token: dot,
1321 lt_token: lt,
1322 gt_token: gt,
1323 colon2_token: colon2,
1324 typarams: tys.unwrap_or_default(),
1325 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001326 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001327 ));
1328
Michael Layzell734adb42017-06-07 16:58:31 -04001329 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001330 impl Synom for ExprTup {
Michael Layzell92639a52017-06-01 00:07:44 -04001331 named!(parse -> Self, do_parse!(
1332 elems: parens!(call!(Delimited::parse_terminated)) >>
1333 (ExprTup {
1334 args: elems.0,
1335 paren_token: elems.1,
1336 lone_comma: None, // TODO: parse this
1337 })
1338 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001339 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001340
Michael Layzell734adb42017-06-07 16:58:31 -04001341 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001342 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001343 named!(parse -> Self, do_parse!(
1344 if_: syn!(If) >>
1345 let_: syn!(Let) >>
1346 pat: syn!(Pat) >>
1347 eq: syn!(Eq) >>
1348 cond: expr_no_struct >>
1349 then_block: braces!(call!(Block::parse_within)) >>
1350 else_block: option!(else_block) >>
1351 (ExprIfLet {
1352 pat: Box::new(pat),
1353 let_token: let_,
1354 eq_token: eq,
1355 expr: Box::new(cond),
1356 if_true: Block {
1357 stmts: then_block.0,
1358 brace_token: then_block.1,
1359 },
1360 if_token: if_,
1361 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1362 if_false: else_block.map(|p| Box::new(p.1.into())),
1363 })
1364 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001365 }
1366
Michael Layzell734adb42017-06-07 16:58:31 -04001367 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001368 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001369 named!(parse -> Self, do_parse!(
1370 if_: syn!(If) >>
1371 cond: expr_no_struct >>
1372 then_block: braces!(call!(Block::parse_within)) >>
1373 else_block: option!(else_block) >>
1374 (ExprIf {
1375 cond: Box::new(cond),
1376 if_true: Block {
1377 stmts: then_block.0,
1378 brace_token: then_block.1,
1379 },
1380 if_token: if_,
1381 else_token: else_block.as_ref().map(|p| Else((p.0).0)),
1382 if_false: else_block.map(|p| Box::new(p.1.into())),
1383 })
1384 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001385 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001386
Michael Layzell734adb42017-06-07 16:58:31 -04001387 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001388 named!(else_block -> (Else, ExprKind), do_parse!(
1389 else_: syn!(Else) >>
1390 expr: alt!(
1391 syn!(ExprIf) => { ExprKind::If }
1392 |
1393 syn!(ExprIfLet) => { ExprKind::IfLet }
1394 |
1395 do_parse!(
1396 else_block: braces!(call!(Block::parse_within)) >>
1397 (ExprKind::Block(ExprBlock {
1398 unsafety: Unsafety::Normal,
1399 block: Block {
1400 stmts: else_block.0,
1401 brace_token: else_block.1,
1402 },
1403 }))
David Tolnay939766a2016-09-23 23:48:12 -07001404 )
Alex Crichton954046c2017-05-30 21:49:42 -07001405 ) >>
1406 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001407 ));
1408
David Tolnaybb6feae2016-10-02 21:25:20 -07001409
Michael Layzell734adb42017-06-07 16:58:31 -04001410 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001411 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001412 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001413 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001414 for_: syn!(For) >>
1415 pat: syn!(Pat) >>
1416 in_: syn!(In) >>
1417 expr: expr_no_struct >>
1418 loop_block: syn!(Block) >>
1419 (ExprForLoop {
1420 for_token: for_,
1421 in_token: in_,
1422 pat: Box::new(pat),
1423 expr: Box::new(expr),
1424 body: loop_block,
1425 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1426 label: lbl.map(|p| p.0),
1427 })
1428 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001429 }
Gregory Katze5f35682016-09-27 14:20:55 -04001430
Michael Layzell734adb42017-06-07 16:58:31 -04001431 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001432 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001433 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001434 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001435 loop_: syn!(Loop) >>
1436 loop_block: syn!(Block) >>
1437 (ExprLoop {
1438 loop_token: loop_,
1439 body: loop_block,
1440 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1441 label: lbl.map(|p| p.0),
1442 })
1443 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001444 }
1445
Michael Layzell734adb42017-06-07 16:58:31 -04001446 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001447 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001448 named!(parse -> Self, do_parse!(
1449 match_: syn!(Match) >>
1450 obj: expr_no_struct >>
1451 res: braces!(do_parse!(
1452 mut arms: many0!(do_parse!(
1453 arm: syn!(Arm) >>
1454 cond!(arm_requires_comma(&arm), syn!(Comma)) >>
1455 cond!(!arm_requires_comma(&arm), option!(syn!(Comma))) >>
1456 (arm)
Alex Crichton954046c2017-05-30 21:49:42 -07001457 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001458 last_arm: option!(syn!(Arm)) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001459 ({
Michael Layzell92639a52017-06-01 00:07:44 -04001460 arms.extend(last_arm);
1461 arms
Alex Crichton954046c2017-05-30 21:49:42 -07001462 })
Michael Layzell92639a52017-06-01 00:07:44 -04001463 )) >>
1464 ({
1465 let (mut arms, brace) = res;
1466 ExprMatch {
1467 expr: Box::new(obj),
1468 match_token: match_,
1469 brace_token: brace,
1470 arms: {
1471 for arm in &mut arms {
1472 if arm_requires_comma(arm) {
1473 arm.comma = Some(tokens::Comma::default());
1474 }
1475 }
1476 arms
1477 },
1478 }
1479 })
1480 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001481 }
David Tolnay1978c672016-10-27 22:05:52 -07001482
Michael Layzell734adb42017-06-07 16:58:31 -04001483 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001484 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001485 named!(parse -> Self, do_parse!(
1486 do_: syn!(Do) >>
1487 catch_: syn!(Catch) >>
1488 catch_block: syn!(Block) >>
1489 (ExprCatch {
1490 block: catch_block,
1491 do_token: do_,
1492 catch_token: catch_,
1493 }.into())
1494 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001495 }
Arnavion02ef13f2017-04-25 00:54:31 -07001496
Michael Layzell734adb42017-06-07 16:58:31 -04001497 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001498 impl Synom for ExprYield {
1499 named!(parse -> Self, do_parse!(
1500 yield_: syn!(Yield) >>
1501 expr: option!(syn!(Expr)) >>
1502 (ExprYield {
1503 yield_token: yield_,
1504 expr: expr.map(Box::new),
1505 })
1506 ));
1507 }
1508
1509 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001510 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001511 named!(parse -> Self, do_parse!(
1512 attrs: many0!(call!(Attribute::parse_outer)) >>
1513 pats: call!(Delimited::parse_separated_nonempty) >>
1514 guard: option!(tuple!(syn!(If), syn!(Expr))) >>
1515 rocket: syn!(Rocket) >>
1516 body: alt!(
1517 map!(syn!(Block), |blk| {
1518 ExprKind::Block(ExprBlock {
1519 unsafety: Unsafety::Normal,
1520 block: blk,
1521 }).into()
Alex Crichton954046c2017-05-30 21:49:42 -07001522 })
Michael Layzell92639a52017-06-01 00:07:44 -04001523 |
1524 syn!(Expr)
1525 ) >>
1526 (Arm {
1527 rocket_token: rocket,
1528 if_token: guard.as_ref().map(|p| If((p.0).0)),
1529 attrs: attrs,
1530 pats: pats,
1531 guard: guard.map(|p| Box::new(p.1)),
1532 body: Box::new(body),
1533 comma: None,
1534 })
1535 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001536 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001537
Michael Layzell734adb42017-06-07 16:58:31 -04001538 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001539 named!(expr_closure(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001540 capture: syn!(CaptureBy) >>
1541 or1: syn!(Or) >>
1542 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
1543 or2: syn!(Or) >>
David Tolnay89e05672016-10-02 14:39:42 -07001544 ret_and_body: alt!(
1545 do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001546 arrow: syn!(RArrow) >>
1547 ty: syn!(Ty) >>
1548 body: syn!(Block) >>
1549 (FunctionRetTy::Ty(ty, arrow),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001550 ExprKind::Block(ExprBlock {
Alex Crichton62a0a592017-05-22 13:58:53 -07001551 unsafety: Unsafety::Normal,
1552 block: body,
1553 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001554 )
1555 |
David Tolnay58af3552016-12-22 16:58:07 -05001556 map!(ambiguous_expr!(allow_struct), |e| (FunctionRetTy::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001557 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001558 (ExprClosure {
1559 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001560 or1_token: or1,
1561 or2_token: or2,
Alex Crichton62a0a592017-05-22 13:58:53 -07001562 decl: Box::new(FnDecl {
David Tolnay89e05672016-10-02 14:39:42 -07001563 inputs: inputs,
1564 output: ret_and_body.0,
David Tolnay292e6002016-10-29 22:03:51 -07001565 variadic: false,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001566 dot_tokens: None,
Alex Crichton954046c2017-05-30 21:49:42 -07001567 fn_token: tokens::Fn_::default(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001568 generics: Generics::default(),
1569 paren_token: tokens::Paren::default(),
David Tolnay89e05672016-10-02 14:39:42 -07001570 }),
Alex Crichton62a0a592017-05-22 13:58:53 -07001571 body: Box::new(ret_and_body.1),
1572 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001573 ));
1574
Michael Layzell734adb42017-06-07 16:58:31 -04001575 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001576 named!(fn_arg -> FnArg, do_parse!(
1577 pat: syn!(Pat) >>
1578 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1579 ({
1580 let (colon, ty) = ty.unwrap_or_else(|| {
1581 (Colon::default(), TyInfer {
1582 underscore_token: Underscore::default(),
1583 }.into())
1584 });
1585 ArgCaptured {
1586 pat: pat,
1587 colon_token: colon,
1588 ty: ty,
1589 }.into()
David Tolnaybb6feae2016-10-02 21:25:20 -07001590 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001591 ));
1592
Michael Layzell734adb42017-06-07 16:58:31 -04001593 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001594 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001595 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001596 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001597 while_: syn!(While) >>
1598 cond: expr_no_struct >>
1599 while_block: syn!(Block) >>
1600 (ExprWhile {
1601 while_token: while_,
1602 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1603 cond: Box::new(cond),
1604 body: while_block,
1605 label: lbl.map(|p| p.0),
1606 })
1607 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001608 }
1609
Michael Layzell734adb42017-06-07 16:58:31 -04001610 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001611 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001612 named!(parse -> Self, do_parse!(
David Tolnay63e3dee2017-06-03 20:13:17 -07001613 lbl: option!(tuple!(syn!(Lifetime), syn!(Colon))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001614 while_: syn!(While) >>
1615 let_: syn!(Let) >>
1616 pat: syn!(Pat) >>
1617 eq: syn!(Eq) >>
1618 value: expr_no_struct >>
1619 while_block: syn!(Block) >>
1620 (ExprWhileLet {
1621 eq_token: eq,
1622 let_token: let_,
1623 while_token: while_,
1624 colon_token: lbl.as_ref().map(|p| Colon((p.1).0)),
1625 pat: Box::new(pat),
1626 expr: Box::new(value),
1627 body: while_block,
1628 label: lbl.map(|p| p.0),
1629 })
1630 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001631 }
1632
Michael Layzell734adb42017-06-07 16:58:31 -04001633 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001634 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001635 named!(parse -> Self, do_parse!(
1636 cont: syn!(Continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001637 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001638 (ExprContinue {
1639 continue_token: cont,
1640 label: lbl,
1641 })
1642 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001643 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001644
Michael Layzell734adb42017-06-07 16:58:31 -04001645 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001646 named!(expr_break(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001647 break_: syn!(Break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001648 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001649 // We can't allow blocks after a `break` expression when we wouldn't
1650 // allow structs, as this expression is ambiguous.
1651 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001652 (ExprBreak {
1653 label: lbl,
1654 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001655 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001656 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001657 ));
1658
Michael Layzell734adb42017-06-07 16:58:31 -04001659 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001660 named!(expr_ret(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001661 return_: syn!(Return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001662 // NOTE: return is greedy and eats blocks after it even when in a
1663 // position where structs are not allowed, such as in if statement
1664 // conditions. For example:
1665 //
1666 // if return { println!("A") } { } // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001667 ret_value: option!(ambiguous_expr!(allow_struct)) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001668 (ExprRet {
1669 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001670 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001671 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001672 ));
1673
Michael Layzell734adb42017-06-07 16:58:31 -04001674 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001675 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001676 named!(parse -> Self, do_parse!(
1677 path: syn!(Path) >>
1678 data: braces!(do_parse!(
1679 fields: call!(Delimited::parse_terminated) >>
1680 base: option!(
1681 cond!(fields.is_empty() || fields.trailing_delim(),
1682 do_parse!(
1683 dots: syn!(Dot2) >>
1684 base: syn!(Expr) >>
1685 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001686 )
Michael Layzell92639a52017-06-01 00:07:44 -04001687 )
1688 ) >>
1689 (fields, base)
1690 )) >>
1691 ({
1692 let ((fields, base), brace) = data;
1693 let (dots, rest) = match base.and_then(|b| b) {
1694 Some((dots, base)) => (Some(dots), Some(base)),
1695 None => (None, None),
1696 };
1697 ExprStruct {
1698 brace_token: brace,
1699 path: path,
1700 fields: fields,
1701 dot2_token: dots,
1702 rest: rest.map(Box::new),
1703 }
1704 })
1705 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001706 }
1707
Michael Layzell734adb42017-06-07 16:58:31 -04001708 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001709 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001710 named!(parse -> Self, alt!(
1711 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07001712 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04001713 colon: syn!(Colon) >>
1714 value: syn!(Expr) >>
1715 (FieldValue {
David Tolnay570695e2017-06-03 16:15:13 -07001716 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04001717 expr: value,
1718 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001719 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001720 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001721 })
Michael Layzell92639a52017-06-01 00:07:44 -04001722 )
1723 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001724 map!(syn!(Ident), |name| FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001725 ident: name.clone(),
1726 expr: ExprKind::Path(ExprPath { qself: None, path: name.into() }).into(),
1727 is_shorthand: true,
1728 attrs: Vec::new(),
1729 colon_token: None,
1730 })
1731 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001732 }
David Tolnay055a7042016-10-02 19:23:54 -07001733
Michael Layzell734adb42017-06-07 16:58:31 -04001734 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001735 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001736 named!(parse -> Self, do_parse!(
1737 data: brackets!(do_parse!(
1738 value: syn!(Expr) >>
1739 semi: syn!(Semi) >>
1740 times: syn!(Expr) >>
1741 (value, semi, times)
1742 )) >>
1743 (ExprRepeat {
1744 expr: Box::new((data.0).0),
1745 amt: Box::new((data.0).2),
1746 bracket_token: data.1,
1747 semi_token: (data.0).1,
1748 })
1749 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001750 }
David Tolnay055a7042016-10-02 19:23:54 -07001751
Michael Layzell734adb42017-06-07 16:58:31 -04001752 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001753 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001754 named!(parse -> Self, do_parse!(
1755 rules: syn!(Unsafety) >>
1756 b: syn!(Block) >>
1757 (ExprBlock {
1758 unsafety: rules,
1759 block: b,
1760 })
1761 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001762 }
David Tolnay89e05672016-10-02 14:39:42 -07001763
Michael Layzell734adb42017-06-07 16:58:31 -04001764 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -04001765 named!(expr_range(allow_struct: bool) -> ExprKind, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001766 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001767 hi: opt_ambiguous_expr!(allow_struct) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001768 (ExprRange { from: None, to: hi.map(Box::new), limits: limits }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001769 ));
1770
Michael Layzell734adb42017-06-07 16:58:31 -04001771 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001772 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001773 named!(parse -> Self, alt!(
1774 // Must come before Dot2
1775 syn!(Dot3) => { RangeLimits::Closed }
1776 |
1777 syn!(Dot2) => { RangeLimits::HalfOpen }
1778 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001779 }
David Tolnay438c9052016-10-07 23:24:48 -07001780
Alex Crichton954046c2017-05-30 21:49:42 -07001781 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001782 named!(parse -> Self, do_parse!(
1783 pair: qpath >>
1784 (ExprPath {
1785 qself: pair.0,
1786 path: pair.1,
1787 })
1788 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001789 }
David Tolnay42602292016-10-01 22:25:45 -07001790
Michael Layzell734adb42017-06-07 16:58:31 -04001791 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001792 named!(and_field -> (Ident, Dot),
1793 map!(tuple!(syn!(Dot), syn!(Ident)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001794
Michael Layzell734adb42017-06-07 16:58:31 -04001795 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001796 named!(and_tup_field -> (Lit, Dot),
1797 map!(tuple!(syn!(Dot), syn!(Lit)), |(a, b)| (b, a)));
David Tolnay438c9052016-10-07 23:24:48 -07001798
Alex Crichton954046c2017-05-30 21:49:42 -07001799 named!(and_index -> (Expr, tokens::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001800
Michael Layzell734adb42017-06-07 16:58:31 -04001801 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001802 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001803 named!(parse -> Self, do_parse!(
1804 stmts: braces!(call!(Block::parse_within)) >>
1805 (Block {
1806 stmts: stmts.0,
1807 brace_token: stmts.1,
1808 })
1809 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001810 }
David Tolnay939766a2016-09-23 23:48:12 -07001811
Michael Layzell734adb42017-06-07 16:58:31 -04001812 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001813 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001814 named!(pub parse_within -> Vec<Stmt>, do_parse!(
1815 many0!(syn!(Semi)) >>
1816 mut standalone: many0!(terminated!(syn!(Stmt), many0!(syn!(Semi)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001817 last: option!(do_parse!(
1818 attrs: many0!(call!(Attribute::parse_outer)) >>
1819 mut e: syn!(Expr) >>
1820 ({
1821 e.attrs = attrs;
1822 Stmt::Expr(Box::new(e))
1823 })
1824 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001825 (match last {
1826 None => standalone,
1827 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001828 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001829 standalone
1830 }
1831 })
1832 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001833 }
1834
Michael Layzell734adb42017-06-07 16:58:31 -04001835 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001836 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001837 named!(parse -> Self, alt!(
1838 stmt_mac
1839 |
1840 stmt_local
1841 |
1842 stmt_item
1843 |
Michael Layzell35418782017-06-07 09:20:25 -04001844 stmt_blockexpr
1845 |
Michael Layzell92639a52017-06-01 00:07:44 -04001846 stmt_expr
1847 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001848 }
David Tolnay939766a2016-09-23 23:48:12 -07001849
Michael Layzell734adb42017-06-07 16:58:31 -04001850 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001851 named!(stmt_mac -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001852 attrs: many0!(call!(Attribute::parse_outer)) >>
1853 what: syn!(Path) >>
1854 bang: syn!(Bang) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001855 // Only parse braces here; paren and bracket will get parsed as
1856 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001857 data: braces!(syn!(TokenStream)) >>
1858 semi: option!(syn!(Semi)) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001859 (Stmt::Mac(Box::new((
1860 Mac {
David Tolnay5d55ef72016-12-21 20:20:04 -05001861 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001862 bang_token: bang,
David Tolnay570695e2017-06-03 16:15:13 -07001863 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001864 tokens: vec![TokenTree(proc_macro2::TokenTree {
Alex Crichton954046c2017-05-30 21:49:42 -07001865 span: ((data.1).0).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001866 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnayeea28d62016-10-25 20:44:08 -07001867 })],
1868 },
Alex Crichton954046c2017-05-30 21:49:42 -07001869 match semi {
1870 Some(semi) => MacStmtStyle::Semicolon(semi),
1871 None => MacStmtStyle::Braces,
David Tolnay60d48942016-10-30 14:34:52 -07001872 },
David Tolnayeea28d62016-10-25 20:44:08 -07001873 attrs,
1874 ))))
David Tolnay13b3d352016-10-03 00:31:15 -07001875 ));
1876
Michael Layzell734adb42017-06-07 16:58:31 -04001877 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07001878 named!(stmt_local -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001879 attrs: many0!(call!(Attribute::parse_outer)) >>
1880 let_: syn!(Let) >>
1881 pat: syn!(Pat) >>
1882 ty: option!(tuple!(syn!(Colon), syn!(Ty))) >>
1883 init: option!(tuple!(syn!(Eq), syn!(Expr))) >>
1884 semi: syn!(Semi) >>
David Tolnay191e0582016-10-02 18:31:09 -07001885 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07001886 let_token: let_,
1887 semi_token: semi,
1888 colon_token: ty.as_ref().map(|p| Colon((p.0).0)),
1889 eq_token: init.as_ref().map(|p| Eq((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07001890 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07001891 ty: ty.map(|p| Box::new(p.1)),
1892 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07001893 attrs: attrs,
1894 })))
1895 ));
1896
Michael Layzell734adb42017-06-07 16:58:31 -04001897 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001898 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07001899
Michael Layzell734adb42017-06-07 16:58:31 -04001900 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001901 named!(stmt_blockexpr -> Stmt, do_parse!(
1902 attrs: many0!(call!(Attribute::parse_outer)) >>
1903 mut e: expr_nosemi >>
1904 // If the next token is a `.` or a `?` it is special-cased to parse as
1905 // an expression instead of a blockexpression.
1906 not!(syn!(Dot)) >>
1907 not!(syn!(Question)) >>
1908 semi: option!(syn!(Semi)) >>
1909 ({
1910 e.attrs = attrs;
1911 if let Some(semi) = semi {
1912 Stmt::Semi(Box::new(e), semi)
1913 } else {
1914 Stmt::Expr(Box::new(e))
1915 }
1916 })
1917 ));
David Tolnaycfe55022016-10-02 22:02:27 -07001918
Michael Layzell734adb42017-06-07 16:58:31 -04001919 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07001920 named!(stmt_expr -> Stmt, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001921 attrs: many0!(call!(Attribute::parse_outer)) >>
1922 mut e: syn!(Expr) >>
Michael Layzell35418782017-06-07 09:20:25 -04001923 semi: syn!(Semi) >>
David Tolnay7184b132016-10-30 10:06:37 -07001924 ({
1925 e.attrs = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04001926 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07001927 })
David Tolnay939766a2016-09-23 23:48:12 -07001928 ));
David Tolnay8b07f372016-09-30 10:28:40 -07001929
Michael Layzell734adb42017-06-07 16:58:31 -04001930 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001931 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04001932 named!(parse -> Self, alt!(
1933 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
1934 |
1935 syn!(PatBox) => { Pat::Box } // must be before pat_ident
1936 |
1937 syn!(PatRange) => { Pat::Range } // must be before pat_lit
1938 |
1939 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
1940 |
1941 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
1942 |
1943 syn!(Mac) => { Pat::Mac } // must be before pat_ident
1944 |
1945 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
1946 |
1947 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
1948 |
1949 syn!(PatPath) => { Pat::Path }
1950 |
1951 syn!(PatTuple) => { Pat::Tuple }
1952 |
1953 syn!(PatRef) => { Pat::Ref }
1954 |
1955 syn!(PatSlice) => { Pat::Slice }
1956 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001957 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001958
Michael Layzell734adb42017-06-07 16:58:31 -04001959 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001960 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04001961 named!(parse -> Self, map!(
1962 syn!(Underscore),
1963 |u| PatWild { underscore_token: u }
1964 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001965 }
David Tolnay84aa0752016-10-02 23:01:13 -07001966
Michael Layzell734adb42017-06-07 16:58:31 -04001967 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001968 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04001969 named!(parse -> Self, do_parse!(
1970 boxed: syn!(Box_) >>
1971 pat: syn!(Pat) >>
1972 (PatBox {
1973 pat: Box::new(pat),
1974 box_token: boxed,
1975 })
1976 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001977 }
1978
Michael Layzell734adb42017-06-07 16:58:31 -04001979 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001980 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04001981 named!(parse -> Self, do_parse!(
1982 mode: option!(syn!(Ref)) >>
1983 mutability: syn!(Mutability) >>
1984 name: alt!(
1985 syn!(Ident)
1986 |
1987 syn!(Self_) => { Into::into }
1988 ) >>
1989 not!(syn!(Lt)) >>
1990 not!(syn!(Colon2)) >>
1991 subpat: option!(tuple!(syn!(At), syn!(Pat))) >>
1992 (PatIdent {
1993 mode: match mode {
1994 Some(mode) => BindingMode::ByRef(mode, mutability),
1995 None => BindingMode::ByValue(mutability),
1996 },
1997 ident: name,
1998 at_token: subpat.as_ref().map(|p| At((p.0).0)),
1999 subpat: subpat.map(|p| Box::new(p.1)),
2000 })
2001 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002002 }
2003
Michael Layzell734adb42017-06-07 16:58:31 -04002004 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002005 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002006 named!(parse -> Self, do_parse!(
2007 path: syn!(Path) >>
2008 tuple: syn!(PatTuple) >>
2009 (PatTupleStruct {
2010 path: path,
2011 pat: tuple,
2012 })
2013 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002014 }
2015
Michael Layzell734adb42017-06-07 16:58:31 -04002016 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002017 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002018 named!(parse -> Self, do_parse!(
2019 path: syn!(Path) >>
2020 data: braces!(do_parse!(
2021 fields: call!(Delimited::parse_terminated) >>
2022 base: option!(
2023 cond!(fields.is_empty() || fields.trailing_delim(),
2024 syn!(Dot2))
2025 ) >>
2026 (fields, base)
2027 )) >>
2028 (PatStruct {
2029 path: path,
2030 fields: (data.0).0,
2031 brace_token: data.1,
2032 dot2_token: (data.0).1.and_then(|m| m),
2033 })
2034 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002035 }
2036
Michael Layzell734adb42017-06-07 16:58:31 -04002037 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002038 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002039 named!(parse -> Self, alt!(
2040 do_parse!(
David Tolnay570695e2017-06-03 16:15:13 -07002041 ident: field_ident >>
Michael Layzell92639a52017-06-01 00:07:44 -04002042 colon: syn!(Colon) >>
2043 pat: syn!(Pat) >>
2044 (FieldPat {
2045 ident: ident,
2046 pat: Box::new(pat),
2047 is_shorthand: false,
2048 attrs: Vec::new(),
2049 colon_token: Some(colon),
2050 })
2051 )
2052 |
2053 do_parse!(
2054 boxed: option!(syn!(Box_)) >>
2055 mode: option!(syn!(Ref)) >>
2056 mutability: syn!(Mutability) >>
2057 ident: syn!(Ident) >>
2058 ({
2059 let mut pat: Pat = PatIdent {
2060 mode: if let Some(mode) = mode {
2061 BindingMode::ByRef(mode, mutability)
2062 } else {
2063 BindingMode::ByValue(mutability)
2064 },
2065 ident: ident.clone(),
2066 subpat: None,
2067 at_token: None,
2068 }.into();
2069 if let Some(boxed) = boxed {
2070 pat = PatBox {
2071 pat: Box::new(pat),
2072 box_token: boxed,
2073 }.into();
2074 }
2075 FieldPat {
Alex Crichton954046c2017-05-30 21:49:42 -07002076 ident: ident,
2077 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002078 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002079 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002080 colon_token: None,
2081 }
2082 })
2083 )
2084 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002085 }
2086
Michael Layzell734adb42017-06-07 16:58:31 -04002087 #[cfg(feature = "full")]
David Tolnay570695e2017-06-03 16:15:13 -07002088 named!(field_ident -> Ident, alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002089 syn!(Ident)
2090 |
2091 do_parse!(
2092 lit: syn!(Lit) >>
2093 ({
David Tolnay570695e2017-06-03 16:15:13 -07002094 let s = lit.to_string();
2095 if s.parse::<usize>().is_ok() {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002096 Ident::new(Term::intern(&s), lit.span)
Alex Crichton954046c2017-05-30 21:49:42 -07002097 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002098 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002099 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002100 })
2101 )
2102 ));
2103
Michael Layzell734adb42017-06-07 16:58:31 -04002104 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002105 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002106 named!(parse -> Self, map!(
2107 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002108 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002109 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002110 }
David Tolnay9636c052016-10-02 17:11:17 -07002111
Michael Layzell734adb42017-06-07 16:58:31 -04002112 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002113 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002114 named!(parse -> Self, do_parse!(
2115 data: parens!(do_parse!(
2116 elems: call!(Delimited::parse_terminated) >>
2117 dotdot: map!(cond!(
2118 elems.is_empty() || elems.trailing_delim(),
2119 option!(do_parse!(
2120 dots: syn!(Dot2) >>
2121 trailing: option!(syn!(Comma)) >>
2122 (dots, trailing)
2123 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002124 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002125 rest: cond!(match dotdot {
2126 Some((_, Some(_))) => true,
2127 _ => false,
2128 },
2129 call!(Delimited::parse_terminated)) >>
2130 (elems, dotdot, rest)
2131 )) >>
2132 ({
2133 let ((mut elems, dotdot, rest), parens) = data;
2134 let (dotdot, trailing) = match dotdot {
2135 Some((a, b)) => (Some(a), Some(b)),
2136 None => (None, None),
2137 };
2138 PatTuple {
2139 paren_token: parens,
2140 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2141 dot2_token: dotdot,
2142 comma_token: trailing.and_then(|b| b),
2143 pats: {
2144 if let Some(rest) = rest {
2145 for elem in rest {
2146 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002147 }
Michael Layzell92639a52017-06-01 00:07:44 -04002148 }
2149 elems
2150 },
2151 }
2152 })
2153 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002154 }
David Tolnayfbb73232016-10-03 01:00:06 -07002155
Michael Layzell734adb42017-06-07 16:58:31 -04002156 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002157 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002158 named!(parse -> Self, do_parse!(
2159 and: syn!(And) >>
2160 mutability: syn!(Mutability) >>
2161 pat: syn!(Pat) >>
2162 (PatRef {
2163 pat: Box::new(pat),
2164 mutbl: mutability,
2165 and_token: and,
2166 })
2167 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002168 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002169
Michael Layzell734adb42017-06-07 16:58:31 -04002170 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002171 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002172 named!(parse -> Self, do_parse!(
2173 lit: pat_lit_expr >>
2174 (if let ExprKind::Path(_) = lit.node {
2175 return parse_error(); // these need to be parsed by pat_path
2176 } else {
2177 PatLit {
2178 expr: Box::new(lit),
2179 }
2180 })
2181 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002182 }
David Tolnaye1310902016-10-29 23:40:00 -07002183
Michael Layzell734adb42017-06-07 16:58:31 -04002184 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002185 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002186 named!(parse -> Self, do_parse!(
2187 lo: pat_lit_expr >>
2188 limits: syn!(RangeLimits) >>
2189 hi: pat_lit_expr >>
2190 (PatRange {
2191 lo: Box::new(lo),
2192 hi: Box::new(hi),
2193 limits: limits,
2194 })
2195 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002196 }
David Tolnaye1310902016-10-29 23:40:00 -07002197
Michael Layzell734adb42017-06-07 16:58:31 -04002198 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002199 named!(pat_lit_expr -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002200 neg: option!(syn!(Sub)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002201 v: alt!(
Alex Crichton954046c2017-05-30 21:49:42 -07002202 syn!(Lit) => { ExprKind::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002203 |
Alex Crichton954046c2017-05-30 21:49:42 -07002204 syn!(ExprPath) => { ExprKind::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002205 ) >>
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002206 (if neg.is_some() {
Alex Crichton62a0a592017-05-22 13:58:53 -07002207 ExprKind::Unary(ExprUnary {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002208 op: UnOp::Neg(tokens::Sub::default()),
Alex Crichton62a0a592017-05-22 13:58:53 -07002209 expr: Box::new(v.into())
2210 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002211 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002212 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002213 })
2214 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002215
Michael Layzell734adb42017-06-07 16:58:31 -04002216 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002217 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002218 named!(parse -> Self, map!(
2219 brackets!(do_parse!(
2220 before: call!(Delimited::parse_terminated) >>
2221 middle: option!(do_parse!(
2222 dots: syn!(Dot2) >>
2223 trailing: option!(syn!(Comma)) >>
2224 (dots, trailing)
2225 )) >>
2226 after: cond!(
2227 match middle {
2228 Some((_, ref trailing)) => trailing.is_some(),
2229 _ => false,
2230 },
2231 call!(Delimited::parse_terminated)
2232 ) >>
2233 (before, middle, after)
2234 )),
2235 |((before, middle, after), brackets)| {
2236 let mut before: Delimited<Pat, tokens::Comma> = before;
2237 let after: Option<Delimited<Pat, tokens::Comma>> = after;
2238 let middle: Option<(Dot2, Option<Comma>)> = middle;
2239 PatSlice {
2240 dot2_token: middle.as_ref().map(|m| Dot2((m.0).0)),
2241 comma_token: middle.as_ref().and_then(|m| {
2242 m.1.as_ref().map(|m| Comma(m.0))
2243 }),
2244 bracket_token: brackets,
2245 middle: middle.and_then(|_| {
2246 if !before.is_empty() && !before.trailing_delim() {
2247 Some(Box::new(before.pop().unwrap().into_item()))
2248 } else {
2249 None
2250 }
2251 }),
2252 front: before,
2253 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002254 }
Alex Crichton954046c2017-05-30 21:49:42 -07002255 }
Michael Layzell92639a52017-06-01 00:07:44 -04002256 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002257 }
David Tolnay435a9a82016-10-29 13:47:20 -07002258
Michael Layzell734adb42017-06-07 16:58:31 -04002259 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002260 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002261 named!(parse -> Self, alt!(
2262 syn!(Move) => { CaptureBy::Value }
2263 |
2264 epsilon!() => { |_| CaptureBy::Ref }
2265 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002266 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002267}
2268
David Tolnayf4bbbd92016-09-23 14:41:55 -07002269#[cfg(feature = "printing")]
2270mod printing {
2271 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002272 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002273 use attr::FilterAttrs;
David Tolnayf4bbbd92016-09-23 14:41:55 -07002274 use quote::{Tokens, ToTokens};
2275
Michael Layzell3936ceb2017-07-08 00:28:36 -04002276 /// If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2277 /// before appending it to `Tokens`.
2278 #[cfg(feature = "full")]
2279 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
2280 if let ExprKind::Struct(_) = e.node {
2281 tokens::Paren::default().surround(tokens, |tokens| {
2282 e.to_tokens(tokens);
2283 });
2284 } else {
2285 e.to_tokens(tokens);
2286 }
2287 }
2288
David Tolnayf4bbbd92016-09-23 14:41:55 -07002289 impl ToTokens for Expr {
Michael Layzell734adb42017-06-07 16:58:31 -04002290 #[cfg(feature = "full")]
David Tolnayf4bbbd92016-09-23 14:41:55 -07002291 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay7184b132016-10-30 10:06:37 -07002292 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002293 self.node.to_tokens(tokens)
2294 }
Michael Layzell734adb42017-06-07 16:58:31 -04002295
2296 #[cfg(not(feature = "full"))]
2297 fn to_tokens(&self, tokens: &mut Tokens) {
2298 self.node.to_tokens(tokens)
2299 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002300 }
2301
Michael Layzell734adb42017-06-07 16:58:31 -04002302 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002303 impl ToTokens for ExprBox {
2304 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002305 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002306 self.expr.to_tokens(tokens);
2307 }
2308 }
2309
Michael Layzell734adb42017-06-07 16:58:31 -04002310 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002311 impl ToTokens for ExprInPlace {
2312 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell6a5a1642017-06-04 19:35:15 -04002313 match self.kind {
2314 InPlaceKind::Arrow(ref arrow) => {
2315 self.place.to_tokens(tokens);
2316 arrow.to_tokens(tokens);
2317 self.value.to_tokens(tokens);
2318 }
2319 InPlaceKind::In(ref _in) => {
2320 _in.to_tokens(tokens);
2321 self.place.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002322 // NOTE: The second operand must be in a block, add one if
2323 // it is not present.
2324 if let ExprKind::Block(_) = self.value.node {
2325 self.value.to_tokens(tokens);
2326 } else {
2327 tokens::Brace::default().surround(tokens, |tokens| {
2328 self.value.to_tokens(tokens);
2329 })
2330 }
Michael Layzell6a5a1642017-06-04 19:35:15 -04002331 }
2332 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002333 }
2334 }
2335
Michael Layzell734adb42017-06-07 16:58:31 -04002336 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002337 impl ToTokens for ExprArray {
2338 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002339 self.bracket_token.surround(tokens, |tokens| {
2340 self.exprs.to_tokens(tokens);
2341 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002342 }
2343 }
2344
2345 impl ToTokens for ExprCall {
2346 fn to_tokens(&self, tokens: &mut Tokens) {
2347 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002348 self.paren_token.surround(tokens, |tokens| {
2349 self.args.to_tokens(tokens);
2350 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002351 }
2352 }
2353
Michael Layzell734adb42017-06-07 16:58:31 -04002354 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002355 impl ToTokens for ExprMethodCall {
2356 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002357 self.expr.to_tokens(tokens);
2358 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002359 self.method.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002360 if !self.typarams.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002361 TokensOrDefault(&self.colon2_token).to_tokens(tokens);
2362 TokensOrDefault(&self.lt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002363 self.typarams.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002364 TokensOrDefault(&self.gt_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002365 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002366 self.paren_token.surround(tokens, |tokens| {
2367 self.args.to_tokens(tokens);
2368 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002369 }
2370 }
2371
Michael Layzell734adb42017-06-07 16:58:31 -04002372 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002373 impl ToTokens for ExprTup {
2374 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002375 self.paren_token.surround(tokens, |tokens| {
2376 self.args.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002377 // If we only have one argument, we need a trailing comma to
2378 // distinguish ExprTup from ExprParen.
2379 if self.args.len() == 1 && !self.args.trailing_delim() {
2380 tokens::Comma::default().to_tokens(tokens);
2381 }
2382 // XXX: Not sure how to handle this, but we never parse it yet.
2383 // Is this for an expression like (0,)? Can't we use the
2384 // trailing delimiter on Delimited for that? (,) isn't a valid
2385 // expression as far as I know.
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002386 self.lone_comma.to_tokens(tokens);
2387 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002388 }
2389 }
2390
2391 impl ToTokens for ExprBinary {
2392 fn to_tokens(&self, tokens: &mut Tokens) {
2393 self.left.to_tokens(tokens);
2394 self.op.to_tokens(tokens);
2395 self.right.to_tokens(tokens);
2396 }
2397 }
2398
2399 impl ToTokens for ExprUnary {
2400 fn to_tokens(&self, tokens: &mut Tokens) {
2401 self.op.to_tokens(tokens);
2402 self.expr.to_tokens(tokens);
2403 }
2404 }
2405
2406 impl ToTokens for ExprCast {
2407 fn to_tokens(&self, tokens: &mut Tokens) {
2408 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002409 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002410 self.ty.to_tokens(tokens);
2411 }
2412 }
2413
2414 impl ToTokens for ExprType {
2415 fn to_tokens(&self, tokens: &mut Tokens) {
2416 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002417 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002418 self.ty.to_tokens(tokens);
2419 }
2420 }
2421
Michael Layzell734adb42017-06-07 16:58:31 -04002422 #[cfg(feature = "full")]
Michael Layzell3936ceb2017-07-08 00:28:36 -04002423 fn maybe_wrap_else(tokens: &mut Tokens,
2424 else_token: &Option<tokens::Else>,
2425 if_false: &Option<Box<Expr>>)
2426 {
2427 if let Some(ref if_false) = *if_false {
Alex Crichton259ee532017-07-14 06:51:02 -07002428 TokensOrDefault(&else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002429
2430 // If we are not one of the valid expressions to exist in an else
2431 // clause, wrap ourselves in a block.
2432 match if_false.node {
2433 ExprKind::If(_) |
2434 ExprKind::IfLet(_) |
2435 ExprKind::Block(_) => {
2436 if_false.to_tokens(tokens);
2437 }
2438 _ => {
2439 tokens::Brace::default().surround(tokens, |tokens| {
2440 if_false.to_tokens(tokens);
2441 });
2442 }
2443 }
2444 }
2445 }
2446
2447 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002448 impl ToTokens for ExprIf {
2449 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002450 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002451 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002452 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002453 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002454 }
2455 }
2456
Michael Layzell734adb42017-06-07 16:58:31 -04002457 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002458 impl ToTokens for ExprIfLet {
2459 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002460 self.if_token.to_tokens(tokens);
2461 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002462 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002463 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002464 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002465 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002466 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 }
2468 }
2469
Michael Layzell734adb42017-06-07 16:58:31 -04002470 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002471 impl ToTokens for ExprWhile {
2472 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002473 if self.label.is_some() {
2474 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002475 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002476 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002477 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002478 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002479 self.body.to_tokens(tokens);
2480 }
2481 }
2482
Michael Layzell734adb42017-06-07 16:58:31 -04002483 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002484 impl ToTokens for ExprWhileLet {
2485 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002486 if self.label.is_some() {
2487 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002488 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002489 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002490 self.while_token.to_tokens(tokens);
2491 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002492 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002493 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002494 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002495 self.body.to_tokens(tokens);
2496 }
2497 }
2498
Michael Layzell734adb42017-06-07 16:58:31 -04002499 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002500 impl ToTokens for ExprForLoop {
2501 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002502 if self.label.is_some() {
2503 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002504 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002505 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002506 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002507 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002508 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002509 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002510 self.body.to_tokens(tokens);
2511 }
2512 }
2513
Michael Layzell734adb42017-06-07 16:58:31 -04002514 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002515 impl ToTokens for ExprLoop {
2516 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002517 if self.label.is_some() {
2518 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002519 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002520 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002521 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002522 self.body.to_tokens(tokens);
2523 }
2524 }
2525
Michael Layzell734adb42017-06-07 16:58:31 -04002526 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002527 impl ToTokens for ExprMatch {
2528 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002529 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002530 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002531 self.brace_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002532 for (i, arm) in self.arms.iter().enumerate() {
2533 arm.to_tokens(tokens);
2534 // Ensure that we have a comma after a non-block arm, except
2535 // for the last one.
2536 let is_last = i == self.arms.len() - 1;
2537 if !is_last && arm_requires_comma(arm) && arm.comma.is_none() {
2538 tokens::Comma::default().to_tokens(tokens);
2539 }
2540 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002541 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002542 }
2543 }
2544
Michael Layzell734adb42017-06-07 16:58:31 -04002545 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002546 impl ToTokens for ExprCatch {
2547 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002548 self.do_token.to_tokens(tokens);
2549 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002550 self.block.to_tokens(tokens);
2551 }
2552 }
2553
Michael Layzell734adb42017-06-07 16:58:31 -04002554 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002555 impl ToTokens for ExprYield {
2556 fn to_tokens(&self, tokens: &mut Tokens) {
2557 self.yield_token.to_tokens(tokens);
2558 self.expr.to_tokens(tokens);
2559 }
2560 }
2561
2562 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002563 impl ToTokens for ExprClosure {
2564 fn to_tokens(&self, tokens: &mut Tokens) {
2565 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002566 self.or1_token.to_tokens(tokens);
2567 for item in self.decl.inputs.iter() {
2568 match **item.item() {
2569 FnArg::Captured(ArgCaptured { ref pat, ty: Ty::Infer(_), .. }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002570 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002571 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002572 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002573 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002574 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002575 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002576 self.or2_token.to_tokens(tokens);
2577 self.decl.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002578 self.body.to_tokens(tokens);
2579 }
2580 }
2581
Michael Layzell734adb42017-06-07 16:58:31 -04002582 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002583 impl ToTokens for ExprBlock {
2584 fn to_tokens(&self, tokens: &mut Tokens) {
2585 self.unsafety.to_tokens(tokens);
2586 self.block.to_tokens(tokens);
2587 }
2588 }
2589
Michael Layzell734adb42017-06-07 16:58:31 -04002590 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002591 impl ToTokens for ExprAssign {
2592 fn to_tokens(&self, tokens: &mut Tokens) {
2593 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002594 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002595 self.right.to_tokens(tokens);
2596 }
2597 }
2598
Michael Layzell734adb42017-06-07 16:58:31 -04002599 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002600 impl ToTokens for ExprAssignOp {
2601 fn to_tokens(&self, tokens: &mut Tokens) {
2602 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002603 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002604 self.right.to_tokens(tokens);
2605 }
2606 }
2607
Michael Layzell734adb42017-06-07 16:58:31 -04002608 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002609 impl ToTokens for ExprField {
2610 fn to_tokens(&self, tokens: &mut Tokens) {
2611 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002612 self.dot_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002613 // XXX: I don't think we can do anything if someone shoves a
2614 // nonsense Lit in here.
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 self.field.to_tokens(tokens);
2616 }
2617 }
2618
Michael Layzell734adb42017-06-07 16:58:31 -04002619 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002620 impl ToTokens for ExprTupField {
2621 fn to_tokens(&self, tokens: &mut Tokens) {
2622 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002623 self.dot_token.to_tokens(tokens);
2624 self.field.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002625 }
2626 }
2627
2628 impl ToTokens for ExprIndex {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
2630 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002631 self.bracket_token.surround(tokens, |tokens| {
2632 self.index.to_tokens(tokens);
2633 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002634 }
2635 }
2636
Michael Layzell734adb42017-06-07 16:58:31 -04002637 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002638 impl ToTokens for ExprRange {
2639 fn to_tokens(&self, tokens: &mut Tokens) {
2640 self.from.to_tokens(tokens);
2641 self.limits.to_tokens(tokens);
2642 self.to.to_tokens(tokens);
2643 }
2644 }
2645
2646 impl ToTokens for ExprPath {
2647 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002648 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002649 }
2650 }
2651
Michael Layzell734adb42017-06-07 16:58:31 -04002652 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 impl ToTokens for ExprAddrOf {
2654 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002655 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002656 self.mutbl.to_tokens(tokens);
2657 self.expr.to_tokens(tokens);
2658 }
2659 }
2660
Michael Layzell734adb42017-06-07 16:58:31 -04002661 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002662 impl ToTokens for ExprBreak {
2663 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002664 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002665 self.label.to_tokens(tokens);
2666 self.expr.to_tokens(tokens);
2667 }
2668 }
2669
Michael Layzell734adb42017-06-07 16:58:31 -04002670 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 impl ToTokens for ExprContinue {
2672 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002673 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002674 self.label.to_tokens(tokens);
2675 }
2676 }
2677
Michael Layzell734adb42017-06-07 16:58:31 -04002678 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002679 impl ToTokens for ExprRet {
2680 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002681 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002682 self.expr.to_tokens(tokens);
2683 }
2684 }
2685
Michael Layzell734adb42017-06-07 16:58:31 -04002686 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002687 impl ToTokens for ExprStruct {
2688 fn to_tokens(&self, tokens: &mut Tokens) {
2689 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002690 self.brace_token.surround(tokens, |tokens| {
2691 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002692 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002693 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002694 self.rest.to_tokens(tokens);
2695 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002696 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002697 }
2698 }
2699
Michael Layzell734adb42017-06-07 16:58:31 -04002700 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002701 impl ToTokens for ExprRepeat {
2702 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002703 self.bracket_token.surround(tokens, |tokens| {
2704 self.expr.to_tokens(tokens);
2705 self.semi_token.to_tokens(tokens);
2706 self.amt.to_tokens(tokens);
2707 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002708 }
2709 }
2710
Michael Layzell93c36282017-06-04 20:43:14 -04002711 impl ToTokens for ExprGroup {
2712 fn to_tokens(&self, tokens: &mut Tokens) {
2713 self.group_token.surround(tokens, |tokens| {
2714 self.expr.to_tokens(tokens);
2715 });
2716 }
2717 }
2718
Alex Crichton62a0a592017-05-22 13:58:53 -07002719 impl ToTokens for ExprParen {
2720 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002721 self.paren_token.surround(tokens, |tokens| {
2722 self.expr.to_tokens(tokens);
2723 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002724 }
2725 }
2726
Michael Layzell734adb42017-06-07 16:58:31 -04002727 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002728 impl ToTokens for ExprTry {
2729 fn to_tokens(&self, tokens: &mut Tokens) {
2730 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002731 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002732 }
2733 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002734
Michael Layzell734adb42017-06-07 16:58:31 -04002735 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002736 impl ToTokens for FieldValue {
2737 fn to_tokens(&self, tokens: &mut Tokens) {
2738 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002739 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2740 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002741 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002742 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002743 self.expr.to_tokens(tokens);
2744 }
David Tolnay055a7042016-10-02 19:23:54 -07002745 }
2746 }
2747
Michael Layzell734adb42017-06-07 16:58:31 -04002748 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002749 impl ToTokens for Arm {
2750 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002751 tokens.append_all(&self.attrs);
2752 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002753 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002754 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002755 self.guard.to_tokens(tokens);
2756 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002757 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002758 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002759 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002760 }
2761 }
2762
Michael Layzell734adb42017-06-07 16:58:31 -04002763 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002764 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002765 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002766 self.underscore_token.to_tokens(tokens);
2767 }
2768 }
2769
Michael Layzell734adb42017-06-07 16:58:31 -04002770 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002771 impl ToTokens for PatIdent {
2772 fn to_tokens(&self, tokens: &mut Tokens) {
2773 self.mode.to_tokens(tokens);
2774 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002775 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002776 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002777 self.subpat.to_tokens(tokens);
2778 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002779 }
2780 }
2781
Michael Layzell734adb42017-06-07 16:58:31 -04002782 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002783 impl ToTokens for PatStruct {
2784 fn to_tokens(&self, tokens: &mut Tokens) {
2785 self.path.to_tokens(tokens);
2786 self.brace_token.surround(tokens, |tokens| {
2787 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002788 // NOTE: We need a comma before the dot2 token if it is present.
2789 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
2790 tokens::Comma::default().to_tokens(tokens);
2791 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002792 self.dot2_token.to_tokens(tokens);
2793 });
2794 }
2795 }
2796
Michael Layzell734adb42017-06-07 16:58:31 -04002797 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002798 impl ToTokens for PatTupleStruct {
2799 fn to_tokens(&self, tokens: &mut Tokens) {
2800 self.path.to_tokens(tokens);
2801 self.pat.to_tokens(tokens);
2802 }
2803 }
2804
Michael Layzell734adb42017-06-07 16:58:31 -04002805 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002806 impl ToTokens for PatPath {
2807 fn to_tokens(&self, tokens: &mut Tokens) {
2808 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2809 }
2810 }
2811
Michael Layzell734adb42017-06-07 16:58:31 -04002812 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002813 impl ToTokens for PatTuple {
2814 fn to_tokens(&self, tokens: &mut Tokens) {
2815 self.paren_token.surround(tokens, |tokens| {
2816 for (i, token) in self.pats.iter().enumerate() {
2817 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07002818 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
2819 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002820 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002821 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002822 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002823
2824 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002825 // Ensure there is a comma before the .. token.
2826 if !self.pats.empty_or_trailing() {
2827 tokens::Comma::default().to_tokens(tokens);
2828 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002829 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002830 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002831 });
2832 }
2833 }
2834
Michael Layzell734adb42017-06-07 16:58:31 -04002835 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002836 impl ToTokens for PatBox {
2837 fn to_tokens(&self, tokens: &mut Tokens) {
2838 self.box_token.to_tokens(tokens);
2839 self.pat.to_tokens(tokens);
2840 }
2841 }
2842
Michael Layzell734adb42017-06-07 16:58:31 -04002843 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002844 impl ToTokens for PatRef {
2845 fn to_tokens(&self, tokens: &mut Tokens) {
2846 self.and_token.to_tokens(tokens);
2847 self.mutbl.to_tokens(tokens);
2848 self.pat.to_tokens(tokens);
2849 }
2850 }
2851
Michael Layzell734adb42017-06-07 16:58:31 -04002852 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002853 impl ToTokens for PatLit {
2854 fn to_tokens(&self, tokens: &mut Tokens) {
2855 self.expr.to_tokens(tokens);
2856 }
2857 }
2858
Michael Layzell734adb42017-06-07 16:58:31 -04002859 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002860 impl ToTokens for PatRange {
2861 fn to_tokens(&self, tokens: &mut Tokens) {
2862 self.lo.to_tokens(tokens);
2863 self.limits.to_tokens(tokens);
2864 self.hi.to_tokens(tokens);
2865 }
2866 }
2867
Michael Layzell734adb42017-06-07 16:58:31 -04002868 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002869 impl ToTokens for PatSlice {
2870 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002871 // XXX: This is a mess, and it will be so easy to screw it up. How
2872 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002873 self.bracket_token.surround(tokens, |tokens| {
2874 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002875
2876 // If we need a comma before the middle or standalone .. token,
2877 // then make sure it's present.
2878 if !self.front.empty_or_trailing() &&
2879 (self.middle.is_some() || self.dot2_token.is_some())
2880 {
2881 tokens::Comma::default().to_tokens(tokens);
2882 }
2883
2884 // If we have an identifier, we always need a .. token.
2885 if self.middle.is_some() {
2886 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002887 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002888 } else if self.dot2_token.is_some() {
2889 self.dot2_token.to_tokens(tokens);
2890 }
2891
2892 // Make sure we have a comma before the back half.
2893 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07002894 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002895 self.back.to_tokens(tokens);
2896 } else {
2897 self.comma_token.to_tokens(tokens);
2898 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002899 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07002900 }
2901 }
2902
Michael Layzell734adb42017-06-07 16:58:31 -04002903 #[cfg(feature = "full")]
Arnavion1992e2f2017-04-25 01:47:46 -07002904 impl ToTokens for RangeLimits {
2905 fn to_tokens(&self, tokens: &mut Tokens) {
2906 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002907 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2908 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
Arnavion1992e2f2017-04-25 01:47:46 -07002909 }
2910 }
2911 }
2912
Michael Layzell734adb42017-06-07 16:58:31 -04002913 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07002914 impl ToTokens for FieldPat {
2915 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002916 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07002917 if !self.is_shorthand {
2918 self.ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002919 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07002920 }
2921 self.pat.to_tokens(tokens);
2922 }
2923 }
2924
Michael Layzell734adb42017-06-07 16:58:31 -04002925 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002926 impl ToTokens for BindingMode {
2927 fn to_tokens(&self, tokens: &mut Tokens) {
2928 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002929 BindingMode::ByRef(ref t, ref m) => {
2930 t.to_tokens(tokens);
2931 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002932 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002933 BindingMode::ByValue(ref m) => {
2934 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002935 }
2936 }
2937 }
2938 }
David Tolnay42602292016-10-01 22:25:45 -07002939
Michael Layzell734adb42017-06-07 16:58:31 -04002940 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07002941 impl ToTokens for CaptureBy {
2942 fn to_tokens(&self, tokens: &mut Tokens) {
2943 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002944 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002945 CaptureBy::Ref => {
2946 // nothing
2947 }
David Tolnay89e05672016-10-02 14:39:42 -07002948 }
2949 }
2950 }
2951
Michael Layzell734adb42017-06-07 16:58:31 -04002952 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002953 impl ToTokens for Block {
2954 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002955 self.brace_token.surround(tokens, |tokens| {
2956 tokens.append_all(&self.stmts);
2957 });
David Tolnay42602292016-10-01 22:25:45 -07002958 }
2959 }
2960
Michael Layzell734adb42017-06-07 16:58:31 -04002961 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07002962 impl ToTokens for Stmt {
2963 fn to_tokens(&self, tokens: &mut Tokens) {
2964 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07002965 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07002966 Stmt::Item(ref item) => item.to_tokens(tokens),
2967 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002968 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07002969 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002970 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07002971 }
David Tolnay13b3d352016-10-03 00:31:15 -07002972 Stmt::Mac(ref mac) => {
Alex Crichton2e0229c2017-05-23 09:34:50 -07002973 let (ref mac, ref style, ref attrs) = **mac;
David Tolnay7184b132016-10-30 10:06:37 -07002974 tokens.append_all(attrs.outer());
David Tolnay13b3d352016-10-03 00:31:15 -07002975 mac.to_tokens(tokens);
Alex Crichton2e0229c2017-05-23 09:34:50 -07002976 match *style {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002977 MacStmtStyle::Semicolon(ref s) => s.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07002978 MacStmtStyle::Braces | MacStmtStyle::NoBraces => {
2979 // no semicolon
2980 }
David Tolnay13b3d352016-10-03 00:31:15 -07002981 }
2982 }
David Tolnay42602292016-10-01 22:25:45 -07002983 }
2984 }
2985 }
David Tolnay191e0582016-10-02 18:31:09 -07002986
Michael Layzell734adb42017-06-07 16:58:31 -04002987 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002988 impl ToTokens for Local {
2989 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07002990 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002991 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07002992 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002993 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002994 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002995 self.ty.to_tokens(tokens);
2996 }
2997 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002998 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002999 self.init.to_tokens(tokens);
3000 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003001 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003002 }
3003 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003004}