blob: b20af262e092fd31b45171b1b94ceb33a53464dc [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay85b69a42017-12-27 20:43:10 -05003use proc_macro2::Span;
David Tolnay14982012017-12-29 00:49:51 -05004#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -05005use std::hash::{Hash, Hasher};
David Tolnayf4bbbd92016-09-23 14:41:55 -07006
Alex Crichton62a0a592017-05-22 13:58:53 -07007ast_enum_of_structs! {
David Tolnay8c91b882017-12-28 23:04:32 -05008 /// An expression.
9 pub enum Expr {
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040011 pub Box(ExprBox #full {
David Tolnay8c91b882017-12-28 23:04:32 -050012 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080013 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -050014 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070015 }),
Clar Charrd22b5702017-03-10 15:24:56 -050016
David Tolnay8701a5c2017-12-28 23:31:10 -050017 /// E.g. 'place <- value'.
Michael Layzell734adb42017-06-07 16:58:31 -040018 pub InPlace(ExprInPlace #full {
David Tolnay8c91b882017-12-28 23:04:32 -050019 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070020 pub place: Box<Expr>,
David Tolnay8701a5c2017-12-28 23:31:10 -050021 pub arrow_token: Token![<-],
Alex Crichton62a0a592017-05-22 13:58:53 -070022 pub value: Box<Expr>,
23 }),
Clar Charrd22b5702017-03-10 15:24:56 -050024
Alex Crichton62a0a592017-05-22 13:58:53 -070025 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040026 pub Array(ExprArray #full {
David Tolnay8c91b882017-12-28 23:04:32 -050027 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050028 pub bracket_token: token::Bracket,
David Tolnay2a86fdd2017-12-28 23:34:28 -050029 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070030 }),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Alex Crichton62a0a592017-05-22 13:58:53 -070032 /// A function call.
33 pub Call(ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -050034 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070035 pub func: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -050036 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -050037 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070038 }),
Clar Charrd22b5702017-03-10 15:24:56 -050039
Alex Crichton62a0a592017-05-22 13:58:53 -070040 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
41 ///
42 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080043 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070044 /// (within the angle brackets).
Michael Layzell734adb42017-06-07 16:58:31 -040045 pub MethodCall(ExprMethodCall #full {
David Tolnay8c91b882017-12-28 23:04:32 -050046 pub attrs: Vec<Attribute>,
David Tolnay76418512017-12-28 23:47:47 -050047 pub receiver: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080048 pub dot_token: Token![.],
David Tolnay4a3f59a2017-12-28 21:21:12 -050049 pub method: Ident,
David Tolnayd60cfec2017-12-29 00:21:38 -050050 pub turbofish: Option<MethodTurbofish>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050051 pub paren_token: token::Paren,
52 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070053 }),
Clar Charrd22b5702017-03-10 15:24:56 -050054
Alex Crichton62a0a592017-05-22 13:58:53 -070055 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050056 pub Tuple(ExprTuple #full {
David Tolnay8c91b882017-12-28 23:04:32 -050057 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050058 pub paren_token: token::Paren,
David Tolnay2a86fdd2017-12-28 23:34:28 -050059 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070060 }),
Clar Charrd22b5702017-03-10 15:24:56 -050061
Alex Crichton62a0a592017-05-22 13:58:53 -070062 /// A binary operation, e.g. `a + b`, `a * b`.
63 pub Binary(ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -050064 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070065 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050066 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -070067 pub right: Box<Expr>,
68 }),
Clar Charrd22b5702017-03-10 15:24:56 -050069
Alex Crichton62a0a592017-05-22 13:58:53 -070070 /// A unary operation, e.g. `!x`, `*x`.
71 pub Unary(ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -050072 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070073 pub op: UnOp,
74 pub expr: Box<Expr>,
75 }),
Clar Charrd22b5702017-03-10 15:24:56 -050076
Alex Crichton62a0a592017-05-22 13:58:53 -070077 /// A literal, e.g. `1`, `"foo"`.
David Tolnay8c91b882017-12-28 23:04:32 -050078 pub Lit(ExprLit {
79 pub attrs: Vec<Attribute>,
80 pub lit: Lit,
81 }),
Clar Charrd22b5702017-03-10 15:24:56 -050082
Alex Crichton62a0a592017-05-22 13:58:53 -070083 /// A cast, e.g. `foo as f64`.
84 pub Cast(ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -050085 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070086 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080087 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080088 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070089 }),
Clar Charrd22b5702017-03-10 15:24:56 -050090
Alex Crichton62a0a592017-05-22 13:58:53 -070091 /// A type ascription, e.g. `foo: f64`.
David Tolnay0cf94f22017-12-28 23:46:26 -050092 pub Type(ExprType #full {
David Tolnay8c91b882017-12-28 23:04:32 -050093 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070094 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080095 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080096 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070097 }),
Clar Charrd22b5702017-03-10 15:24:56 -050098
Alex Crichton62a0a592017-05-22 13:58:53 -070099 /// An `if` block, with an optional else block
100 ///
101 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400102 pub If(ExprIf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500103 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500104 pub if_token: Token![if],
Alex Crichton62a0a592017-05-22 13:58:53 -0700105 pub cond: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500106 pub then_branch: Block,
107 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700108 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500109
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 /// An `if let` expression with an optional else block
111 ///
112 /// E.g., `if let pat = expr { block } else { expr }`
113 ///
114 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400115 pub IfLet(ExprIfLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500116 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800117 pub if_token: Token![if],
118 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500119 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800120 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500121 pub expr: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500122 pub then_branch: Block,
123 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700124 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500125
Alex Crichton62a0a592017-05-22 13:58:53 -0700126 /// A while loop, with an optional label
127 ///
128 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400129 pub While(ExprWhile #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500130 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700131 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800132 pub colon_token: Option<Token![:]>,
133 pub while_token: Token![while],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500134 pub cond: Box<Expr>,
135 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700136 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500137
Alex Crichton62a0a592017-05-22 13:58:53 -0700138 /// A while-let loop, with an optional label.
139 ///
140 /// E.g., `'label: while let pat = expr { block }`
141 ///
142 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400143 pub WhileLet(ExprWhileLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500144 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700145 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800146 pub colon_token: Option<Token![:]>,
147 pub while_token: Token![while],
148 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500149 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800150 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500151 pub expr: Box<Expr>,
152 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700153 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500154
Alex Crichton62a0a592017-05-22 13:58:53 -0700155 /// A for loop, with an optional label.
156 ///
157 /// E.g., `'label: for pat in expr { block }`
158 ///
159 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400160 pub ForLoop(ExprForLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500161 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500162 pub label: Option<Lifetime>,
163 pub colon_token: Option<Token![:]>,
164 pub for_token: Token![for],
Alex Crichton62a0a592017-05-22 13:58:53 -0700165 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500166 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700167 pub expr: Box<Expr>,
168 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500170
Alex Crichton62a0a592017-05-22 13:58:53 -0700171 /// Conditionless loop with an optional label.
172 ///
173 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400174 pub Loop(ExprLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500175 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700176 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800177 pub colon_token: Option<Token![:]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500178 pub loop_token: Token![loop],
179 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700180 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500181
Alex Crichton62a0a592017-05-22 13:58:53 -0700182 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400183 pub Match(ExprMatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500184 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800185 pub match_token: Token![match],
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500187 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700188 pub arms: Vec<Arm>,
189 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500190
Alex Crichton62a0a592017-05-22 13:58:53 -0700191 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400192 pub Closure(ExprClosure #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500193 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800195 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500196 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800197 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500198 pub output: ReturnType,
199 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700200 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500201
Nika Layzell640832a2017-12-04 13:37:09 -0500202 /// An unsafe block (`unsafe { ... }`)
203 pub Unsafe(ExprUnsafe #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500204 pub attrs: Vec<Attribute>,
Nika Layzell640832a2017-12-04 13:37:09 -0500205 pub unsafe_token: Token![unsafe],
206 pub block: Block,
207 }),
208
209 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400210 pub Block(ExprBlock #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500211 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700212 pub block: Block,
213 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700214
Alex Crichton62a0a592017-05-22 13:58:53 -0700215 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400216 pub Assign(ExprAssign #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500217 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 pub left: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800219 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500220 pub right: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700221 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500222
Alex Crichton62a0a592017-05-22 13:58:53 -0700223 /// An assignment with an operator
224 ///
225 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400226 pub AssignOp(ExprAssignOp #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500227 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700228 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500229 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -0700230 pub right: Box<Expr>,
231 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500232
David Tolnay85b69a42017-12-27 20:43:10 -0500233 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
234 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400235 pub Field(ExprField #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500236 pub attrs: Vec<Attribute>,
David Tolnay85b69a42017-12-27 20:43:10 -0500237 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800238 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500239 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700240 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500241
Alex Crichton62a0a592017-05-22 13:58:53 -0700242 /// An indexing operation (`foo[2]`)
243 pub Index(ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -0500244 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700245 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500246 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500247 pub index: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500249
David Tolnaybe55d7b2017-12-17 23:41:20 -0800250 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400251 pub Range(ExprRange #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500252 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700253 pub from: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500255 pub to: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700256 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700257
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 /// Variable reference, possibly containing `::` and/or type
259 /// parameters, e.g. foo::bar::<baz>.
260 ///
261 /// Optionally "qualified",
262 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
263 pub Path(ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -0500264 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700265 pub qself: Option<QSelf>,
266 pub path: Path,
267 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700268
Alex Crichton62a0a592017-05-22 13:58:53 -0700269 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400270 pub AddrOf(ExprAddrOf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500271 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800272 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700273 pub mutbl: Mutability,
274 pub expr: Box<Expr>,
275 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500276
Alex Crichton62a0a592017-05-22 13:58:53 -0700277 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400278 pub Break(ExprBreak #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500279 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500280 pub break_token: Token![break],
David Tolnay63e3dee2017-06-03 20:13:17 -0700281 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700282 pub expr: Option<Box<Expr>>,
283 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500284
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400286 pub Continue(ExprContinue #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500287 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800288 pub continue_token: Token![continue],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500289 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700290 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500291
Alex Crichton62a0a592017-05-22 13:58:53 -0700292 /// A `return`, with an optional value to be returned
David Tolnayc246cd32017-12-28 23:14:32 -0500293 pub Return(ExprReturn #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500294 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800295 pub return_token: Token![return],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500296 pub expr: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700297 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700298
Alex Crichton62a0a592017-05-22 13:58:53 -0700299 /// A macro invocation; pre-expansion
David Tolnay8c91b882017-12-28 23:04:32 -0500300 pub Macro(ExprMacro #full {
301 pub attrs: Vec<Attribute>,
302 pub mac: Macro,
303 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700304
Alex Crichton62a0a592017-05-22 13:58:53 -0700305 /// A struct literal expression.
306 ///
307 /// For example, `Foo {x: 1, y: 2}`, or
308 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400309 pub Struct(ExprStruct #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500310 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700311 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500312 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500313 pub fields: Delimited<FieldValue, Token![,]>,
314 pub dot2_token: Option<Token![..]>,
315 pub rest: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700316 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700317
Alex Crichton62a0a592017-05-22 13:58:53 -0700318 /// An array literal constructed from one repeated element.
319 ///
320 /// For example, `[1; 5]`. The first expression is the element
321 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400322 pub Repeat(ExprRepeat #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500323 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500324 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700325 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500326 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700327 pub amt: Box<Expr>,
328 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700329
Alex Crichton62a0a592017-05-22 13:58:53 -0700330 /// No-op: used solely so we can pretty-print faithfully
David Tolnaye98775f2017-12-28 23:17:00 -0500331 pub Paren(ExprParen #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500332 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500333 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500334 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700335 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700336
Michael Layzell93c36282017-06-04 20:43:14 -0400337 /// No-op: used solely so we can pretty-print faithfully
338 ///
339 /// A `group` represents a `None`-delimited span in the input
340 /// `TokenStream` which affects the precidence of the resulting
341 /// expression. They are used for macro hygiene.
David Tolnaye98775f2017-12-28 23:17:00 -0500342 pub Group(ExprGroup #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500343 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500344 pub group_token: token::Group,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500345 pub expr: Box<Expr>,
Michael Layzell93c36282017-06-04 20:43:14 -0400346 }),
347
Alex Crichton62a0a592017-05-22 13:58:53 -0700348 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400349 pub Try(ExprTry #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500350 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700351 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800352 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700353 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700354
Alex Crichton62a0a592017-05-22 13:58:53 -0700355 /// A catch expression.
356 ///
357 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400358 pub Catch(ExprCatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500359 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800360 pub do_token: Token![do],
361 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700362 pub block: Block,
363 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700364
365 /// A yield expression.
366 ///
367 /// E.g. `yield expr`
368 pub Yield(ExprYield #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500369 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800370 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700371 pub expr: Option<Box<Expr>>,
372 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700373 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700374}
375
David Tolnay8c91b882017-12-28 23:04:32 -0500376impl Expr {
377 // Not public API.
378 #[doc(hidden)]
David Tolnay096d4982017-12-28 23:18:18 -0500379 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500380 pub fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
381 match *self {
382 Expr::Box(ExprBox { ref mut attrs, .. }) |
383 Expr::InPlace(ExprInPlace { ref mut attrs, .. }) |
384 Expr::Array(ExprArray { ref mut attrs, .. }) |
385 Expr::Call(ExprCall { ref mut attrs, .. }) |
386 Expr::MethodCall(ExprMethodCall { ref mut attrs, .. }) |
387 Expr::Tuple(ExprTuple { ref mut attrs, .. }) |
388 Expr::Binary(ExprBinary { ref mut attrs, .. }) |
389 Expr::Unary(ExprUnary { ref mut attrs, .. }) |
390 Expr::Lit(ExprLit { ref mut attrs, .. }) |
391 Expr::Cast(ExprCast { ref mut attrs, .. }) |
392 Expr::Type(ExprType { ref mut attrs, .. }) |
393 Expr::If(ExprIf { ref mut attrs, .. }) |
394 Expr::IfLet(ExprIfLet { ref mut attrs, .. }) |
395 Expr::While(ExprWhile { ref mut attrs, .. }) |
396 Expr::WhileLet(ExprWhileLet { ref mut attrs, .. }) |
397 Expr::ForLoop(ExprForLoop { ref mut attrs, .. }) |
398 Expr::Loop(ExprLoop { ref mut attrs, .. }) |
399 Expr::Match(ExprMatch { ref mut attrs, .. }) |
400 Expr::Closure(ExprClosure { ref mut attrs, .. }) |
401 Expr::Unsafe(ExprUnsafe { ref mut attrs, .. }) |
402 Expr::Block(ExprBlock { ref mut attrs, .. }) |
403 Expr::Assign(ExprAssign { ref mut attrs, .. }) |
404 Expr::AssignOp(ExprAssignOp { ref mut attrs, .. }) |
405 Expr::Field(ExprField { ref mut attrs, .. }) |
406 Expr::Index(ExprIndex { ref mut attrs, .. }) |
407 Expr::Range(ExprRange { ref mut attrs, .. }) |
408 Expr::Path(ExprPath { ref mut attrs, .. }) |
409 Expr::AddrOf(ExprAddrOf { ref mut attrs, .. }) |
410 Expr::Break(ExprBreak { ref mut attrs, .. }) |
411 Expr::Continue(ExprContinue { ref mut attrs, .. }) |
David Tolnayc246cd32017-12-28 23:14:32 -0500412 Expr::Return(ExprReturn { ref mut attrs, .. }) |
David Tolnay8c91b882017-12-28 23:04:32 -0500413 Expr::Macro(ExprMacro { ref mut attrs, .. }) |
414 Expr::Struct(ExprStruct { ref mut attrs, .. }) |
415 Expr::Repeat(ExprRepeat { ref mut attrs, .. }) |
416 Expr::Paren(ExprParen { ref mut attrs, .. }) |
417 Expr::Group(ExprGroup { ref mut attrs, .. }) |
418 Expr::Try(ExprTry { ref mut attrs, .. }) |
419 Expr::Catch(ExprCatch { ref mut attrs, .. }) |
420 Expr::Yield(ExprYield { ref mut attrs, .. }) => attrs,
421 }
422 }
423}
424
David Tolnay85b69a42017-12-27 20:43:10 -0500425ast_enum! {
426 /// A struct or tuple struct field accessed in a struct literal or field
427 /// expression.
428 pub enum Member {
429 /// A named field like `self.x`.
430 Named(Ident),
431 /// An unnamed field like `self.0`.
432 Unnamed(Index),
433 }
434}
435
David Tolnay85b69a42017-12-27 20:43:10 -0500436ast_struct! {
437 /// The index of an unnamed tuple struct field.
438 pub struct Index #manual_extra_traits {
439 pub index: u32,
440 pub span: Span,
441 }
442}
443
David Tolnay14982012017-12-29 00:49:51 -0500444impl From<usize> for Index {
445 fn from(index: usize) -> Index {
446 assert!(index < std::u32::MAX as usize);
447 Index {
448 index: index as u32,
449 span: Span::default(),
450 }
451 }
452}
453
454#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500455impl Eq for Index {}
456
David Tolnay14982012017-12-29 00:49:51 -0500457#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500458impl PartialEq for Index {
459 fn eq(&self, other: &Self) -> bool {
460 self.index == other.index
461 }
462}
463
David Tolnay14982012017-12-29 00:49:51 -0500464#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500465impl Hash for Index {
466 fn hash<H: Hasher>(&self, state: &mut H) {
467 self.index.hash(state);
468 }
469}
470
471#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700472ast_struct! {
David Tolnayd60cfec2017-12-29 00:21:38 -0500473 pub struct MethodTurbofish {
474 pub colon2_token: Token![::],
475 pub lt_token: Token![<],
476 pub args: Delimited<GenericMethodArgument, Token![,]>,
477 pub gt_token: Token![>],
478 }
479}
480
481#[cfg(feature = "full")]
482ast_enum! {
483 /// A individual generic argument like `T`.
484 pub enum GenericMethodArgument {
485 /// The type parameters for this path segment, if present.
486 Type(Type),
487 /// Const expression. Must be inside of a block.
488 ///
489 /// NOTE: Identity expressions are represented as Type arguments, as
490 /// they are indistinguishable syntactically.
491 Const(Expr),
492 }
493}
494
495#[cfg(feature = "full")]
496ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700497 /// A field-value pair in a struct literal.
498 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500499 /// Attributes tagged on the field.
500 pub attrs: Vec<Attribute>,
501
502 /// Name or index of the field.
503 pub member: Member,
504
David Tolnay5d7098a2017-12-29 01:35:24 -0500505 /// The colon in `Struct { x: x }`. If written in shorthand like
506 /// `Struct { x }`, there is no colon.
David Tolnay85b69a42017-12-27 20:43:10 -0500507 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500508
Alex Crichton62a0a592017-05-22 13:58:53 -0700509 /// Value of the field.
510 pub expr: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -0700511 }
David Tolnay055a7042016-10-02 19:23:54 -0700512}
513
Michael Layzell734adb42017-06-07 16:58:31 -0400514#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700515ast_struct! {
516 /// A Block (`{ .. }`).
517 ///
518 /// E.g. `{ .. }` as in `fn foo() { .. }`
519 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500520 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700521 /// Statements in a block
522 pub stmts: Vec<Stmt>,
523 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700524}
525
Michael Layzell734adb42017-06-07 16:58:31 -0400526#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700527ast_enum! {
528 /// A statement, usually ending in a semicolon.
529 pub enum Stmt {
530 /// A local (let) binding.
531 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700532
Alex Crichton62a0a592017-05-22 13:58:53 -0700533 /// An item definition.
534 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700535
Alex Crichton62a0a592017-05-22 13:58:53 -0700536 /// Expr without trailing semicolon.
537 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700538
Alex Crichton62a0a592017-05-22 13:58:53 -0700539 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800540 Semi(Box<Expr>, Token![;]),
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 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
547 pub struct Local {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500548 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800549 pub let_token: Token![let],
Alex Crichton62a0a592017-05-22 13:58:53 -0700550 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500551 pub colon_token: Option<Token![:]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800552 pub ty: Option<Box<Type>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500553 pub eq_token: Option<Token![=]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 /// Initializer expression to set the value, if any
555 pub init: Option<Box<Expr>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500556 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700557 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700558}
559
Michael Layzell734adb42017-06-07 16:58:31 -0400560#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700561ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700562 // Clippy false positive
563 // https://github.com/Manishearth/rust-clippy/issues/1241
564 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
565 pub enum Pat {
566 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700567 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800568 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700569 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700570
Alex Crichton62a0a592017-05-22 13:58:53 -0700571 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
572 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
573 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
574 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 pub Ident(PatIdent {
576 pub mode: BindingMode,
577 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800578 pub at_token: Option<Token![@]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500579 pub subpat: Option<Box<Pat>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700580 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700581
Alex Crichton62a0a592017-05-22 13:58:53 -0700582 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
583 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700584 pub Struct(PatStruct {
585 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500586 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500587 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800588 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700589 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700590
Alex Crichton62a0a592017-05-22 13:58:53 -0700591 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
592 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
593 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700594 pub TupleStruct(PatTupleStruct {
595 pub path: Path,
596 pub pat: PatTuple,
597 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700598
Alex Crichton62a0a592017-05-22 13:58:53 -0700599 /// A possibly qualified path pattern.
600 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
601 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
602 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700603 pub Path(PatPath {
604 pub qself: Option<QSelf>,
605 pub path: Path,
606 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700607
Alex Crichton62a0a592017-05-22 13:58:53 -0700608 /// A tuple pattern `(a, b)`.
609 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
610 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700611 pub Tuple(PatTuple {
David Tolnay32954ef2017-12-26 22:43:16 -0500612 pub paren_token: token::Paren,
David Tolnay41871922017-12-29 01:53:45 -0500613 pub front: Delimited<Pat, Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500614 pub dot2_token: Option<Token![..]>,
David Tolnay41871922017-12-29 01:53:45 -0500615 pub comma_token: Option<Token![,]>,
616 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700617 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700618 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700619 pub Box(PatBox {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800620 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500621 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700622 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700623 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700624 pub Ref(PatRef {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800625 pub and_token: Token![&],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500626 pub mutbl: Mutability,
627 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700628 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700629 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700630 pub Lit(PatLit {
631 pub expr: Box<Expr>,
632 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800633 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700634 pub Range(PatRange {
635 pub lo: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700636 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500637 pub hi: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700638 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400639 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700640 pub Slice(PatSlice {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500641 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800642 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700643 pub middle: Option<Box<Pat>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500644 pub dot2_token: Option<Token![..]>,
David Tolnay41871922017-12-29 01:53:45 -0500645 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500646 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700647 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700648 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800649 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700650 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700651}
652
Michael Layzell734adb42017-06-07 16:58:31 -0400653#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700654ast_struct! {
655 /// An arm of a 'match'.
656 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800657 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700658 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500659 /// ```rust
660 /// # #![feature(dotdoteq_in_patterns)]
661 /// #
662 /// # fn main() {
663 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700664 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500665 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700666 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500667 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700668 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500669 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700670 /// ```
671 pub struct Arm {
672 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800673 pub pats: Delimited<Pat, Token![|]>,
674 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700675 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800676 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700677 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800678 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700679 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700680}
681
Michael Layzell734adb42017-06-07 16:58:31 -0400682#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700683ast_enum! {
684 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700685 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700686 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800687 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700688 Ref,
689 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700690}
691
Michael Layzell734adb42017-06-07 16:58:31 -0400692#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700693ast_enum! {
694 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700695 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700696 pub enum RangeLimits {
697 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800698 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700699 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800700 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700701 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700702}
703
Michael Layzell734adb42017-06-07 16:58:31 -0400704#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700705ast_struct! {
706 /// A single field in a struct pattern
707 ///
708 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
David Tolnay5d7098a2017-12-29 01:35:24 -0500709 /// are treated the same as `x: x, y: ref y, z: ref mut z` but
710 /// there is no colon token.
Alex Crichton62a0a592017-05-22 13:58:53 -0700711 pub struct FieldPat {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500712 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700713 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500714 pub member: Member,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500715 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700716 /// The pattern the field is destructured to
717 pub pat: Box<Pat>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700718 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700719}
720
Michael Layzell734adb42017-06-07 16:58:31 -0400721#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700722ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700723 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700724 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800725 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700726 ByValue(Mutability),
727 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700728}
729
Michael Layzell3936ceb2017-07-08 00:28:36 -0400730#[cfg(any(feature = "parsing", feature = "printing"))]
731#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700732fn arm_expr_requires_comma(expr: &Expr) -> bool {
733 // see https://github.com/rust-lang/rust/blob/eb8f2586e
734 // /src/libsyntax/parse/classify.rs#L17-L37
David Tolnay8c91b882017-12-28 23:04:32 -0500735 match *expr {
736 Expr::Unsafe(..)
737 | Expr::Block(..)
738 | Expr::If(..)
739 | Expr::IfLet(..)
740 | Expr::Match(..)
741 | Expr::While(..)
742 | Expr::WhileLet(..)
743 | Expr::Loop(..)
744 | Expr::ForLoop(..)
745 | Expr::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700746 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400747 }
748}
749
David Tolnayb9c8e322016-09-23 20:48:37 -0700750#[cfg(feature = "parsing")]
751pub mod parsing {
752 use super::*;
David Tolnay2ccf32a2017-12-29 00:34:26 -0500753 use ty::parsing::qpath;
754 #[cfg(feature = "full")]
755 use ty::parsing::ty_no_eq_after;
David Tolnayb9c8e322016-09-23 20:48:37 -0700756
Michael Layzell734adb42017-06-07 16:58:31 -0400757 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500758 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500759 use synom::Synom;
760 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400761 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500762 use parse_error;
David Tolnay203557a2017-12-27 23:59:33 -0500763 use synom::PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700764
David Tolnaybcf26022017-12-25 22:10:52 -0500765 // When we're parsing expressions which occur before blocks, like in an if
766 // statement's condition, we cannot parse a struct literal.
767 //
768 // Struct literals are ambiguous in certain positions
769 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700770 macro_rules! ambiguous_expr {
771 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700772 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700773 };
774 }
775
David Tolnaybcf26022017-12-25 22:10:52 -0500776 // When we are parsing an optional suffix expression, we cannot allow blocks
777 // if structs are not allowed.
778 //
779 // Example:
780 //
781 // if break {} {}
782 //
783 // is ambiguous between:
784 //
785 // if (break {}) {}
786 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400787 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400788 macro_rules! opt_ambiguous_expr {
789 ($i:expr, $allow_struct:ident) => {
790 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
791 };
792 }
793
Alex Crichton954046c2017-05-30 21:49:42 -0700794 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400795 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700796
797 fn description() -> Option<&'static str> {
798 Some("expression")
799 }
800 }
801
Michael Layzell734adb42017-06-07 16:58:31 -0400802 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700803 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
804
David Tolnaybcf26022017-12-25 22:10:52 -0500805 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400806 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500807 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500808 call!(i, assign_expr, allow_struct, allow_block)
Michael Layzellb78f3b52017-06-04 19:03:03 -0400809 }
810
Michael Layzell734adb42017-06-07 16:58:31 -0400811 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500812 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500813 // NOTE: We intentionally skip assign_expr, placement_expr, and
814 // range_expr, as they are not parsed in non-full mode.
815 call!(i, or_expr, allow_struct, allow_block)
Michael Layzell734adb42017-06-07 16:58:31 -0400816 }
817
David Tolnaybcf26022017-12-25 22:10:52 -0500818 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400819 macro_rules! binop {
820 (
821 $name: ident,
822 $next: ident,
823 $submac: ident!( $($args:tt)* )
824 ) => {
David Tolnay8c91b882017-12-28 23:04:32 -0500825 named!($name(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400826 mut e: call!($next, allow_struct, allow_block) >>
827 many0!(do_parse!(
828 op: $submac!($($args)*) >>
829 rhs: call!($next, allow_struct, true) >>
830 ({
831 e = ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -0500832 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400833 left: Box::new(e.into()),
834 op: op,
835 right: Box::new(rhs.into()),
836 }.into();
837 })
838 )) >>
839 (e)
840 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700841 }
David Tolnay54e854d2016-10-24 12:03:30 -0700842 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700843
David Tolnaybcf26022017-12-25 22:10:52 -0500844 // <placement> = <placement> ..
845 // <placement> += <placement> ..
846 // <placement> -= <placement> ..
847 // <placement> *= <placement> ..
848 // <placement> /= <placement> ..
849 // <placement> %= <placement> ..
850 // <placement> ^= <placement> ..
851 // <placement> &= <placement> ..
852 // <placement> |= <placement> ..
853 // <placement> <<= <placement> ..
854 // <placement> >>= <placement> ..
855 //
856 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400857 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500858 named!(assign_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400859 mut e: call!(placement_expr, allow_struct, allow_block) >>
860 alt!(
861 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800862 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400863 // Recurse into self to parse right-associative operator.
864 rhs: call!(assign_expr, allow_struct, true) >>
865 ({
866 e = ExprAssign {
David Tolnay8c91b882017-12-28 23:04:32 -0500867 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400868 left: Box::new(e.into()),
869 eq_token: eq,
870 right: Box::new(rhs.into()),
871 }.into();
872 })
873 )
874 |
875 do_parse!(
876 op: call!(BinOp::parse_assign_op) >>
877 // Recurse into self to parse right-associative operator.
878 rhs: call!(assign_expr, allow_struct, true) >>
879 ({
880 e = ExprAssignOp {
David Tolnay8c91b882017-12-28 23:04:32 -0500881 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400882 left: Box::new(e.into()),
883 op: op,
884 right: Box::new(rhs.into()),
885 }.into();
886 })
887 )
888 |
889 epsilon!()
890 ) >>
891 (e)
892 ));
893
David Tolnaybcf26022017-12-25 22:10:52 -0500894 // <range> <- <range> ..
895 //
896 // NOTE: The `in place { expr }` version of this syntax is parsed in
897 // `atom_expr`, not here.
898 //
899 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400900 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500901 named!(placement_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902 mut e: call!(range_expr, allow_struct, allow_block) >>
903 alt!(
904 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800905 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400906 // Recurse into self to parse right-associative operator.
907 rhs: call!(placement_expr, allow_struct, true) >>
908 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400909 e = ExprInPlace {
David Tolnay8c91b882017-12-28 23:04:32 -0500910 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400911 // op: BinOp::Place(larrow),
912 place: Box::new(e.into()),
David Tolnay8701a5c2017-12-28 23:31:10 -0500913 arrow_token: arrow,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400914 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400915 }.into();
916 })
917 )
918 |
919 epsilon!()
920 ) >>
921 (e)
922 ));
923
David Tolnaybcf26022017-12-25 22:10:52 -0500924 // <or> ... <or> ..
925 // <or> .. <or> ..
926 // <or> ..
927 //
928 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
929 // rules are for parsing these expressions are, but this is not correct.
930 // For example, `a .. b .. c` is not a legal expression. It should not
931 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
932 //
933 // NOTE: The form of ranges which don't include a preceding expression are
934 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400935 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500936 named!(range_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400937 mut e: call!(or_expr, allow_struct, allow_block) >>
938 many0!(do_parse!(
939 limits: syn!(RangeLimits) >>
940 // We don't want to allow blocks here if we don't allow structs. See
941 // the reasoning for `opt_ambiguous_expr!` above.
942 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
943 ({
944 e = ExprRange {
David Tolnay8c91b882017-12-28 23:04:32 -0500945 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400946 from: Some(Box::new(e.into())),
947 limits: limits,
948 to: hi.map(|e| Box::new(e.into())),
949 }.into();
950 })
951 )) >>
952 (e)
953 ));
954
David Tolnaybcf26022017-12-25 22:10:52 -0500955 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800956 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400957
David Tolnaybcf26022017-12-25 22:10:52 -0500958 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800959 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400960
David Tolnaybcf26022017-12-25 22:10:52 -0500961 // <bitor> == <bitor> ...
962 // <bitor> != <bitor> ...
963 // <bitor> >= <bitor> ...
964 // <bitor> <= <bitor> ...
965 // <bitor> > <bitor> ...
966 // <bitor> < <bitor> ...
967 //
968 // NOTE: This operator appears to be parsed as left-associative, but errors
969 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500970 binop!(
971 compare_expr,
972 bitor_expr,
973 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800974 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400975 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800976 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400977 |
978 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800979 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400980 |
981 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800982 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400983 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400984 do_parse!(
985 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800986 not!(punct!(<-)) >>
987 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400988 (BinOp::Lt(t))
989 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400990 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800991 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500992 )
993 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400994
David Tolnaybcf26022017-12-25 22:10:52 -0500995 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500996 binop!(
997 bitor_expr,
998 bitxor_expr,
999 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
1000 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001001
David Tolnaybcf26022017-12-25 22:10:52 -05001002 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -05001003 binop!(
1004 bitxor_expr,
1005 bitand_expr,
1006 do_parse!(
1007 // NOTE: Make sure we aren't looking at ^=.
1008 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
1009 )
1010 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001011
David Tolnaybcf26022017-12-25 22:10:52 -05001012 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -05001013 binop!(
1014 bitand_expr,
1015 shift_expr,
1016 do_parse!(
1017 // NOTE: Make sure we aren't looking at && or &=.
1018 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
1019 )
1020 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001021
David Tolnaybcf26022017-12-25 22:10:52 -05001022 // <arith> << <arith> ...
1023 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -05001024 binop!(
1025 shift_expr,
1026 arith_expr,
1027 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001028 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001029 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001030 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -05001031 )
1032 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001033
David Tolnaybcf26022017-12-25 22:10:52 -05001034 // <term> + <term> ...
1035 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -05001036 binop!(
1037 arith_expr,
1038 term_expr,
1039 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001040 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001041 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001042 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -05001043 )
1044 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001045
David Tolnaybcf26022017-12-25 22:10:52 -05001046 // <cast> * <cast> ...
1047 // <cast> / <cast> ...
1048 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -05001049 binop!(
1050 term_expr,
1051 cast_expr,
1052 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001053 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001054 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001055 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001056 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001057 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -05001058 )
1059 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001060
David Tolnaybcf26022017-12-25 22:10:52 -05001061 // <unary> as <ty>
1062 // <unary> : <ty>
David Tolnay0cf94f22017-12-28 23:46:26 -05001063 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001064 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001065 mut e: call!(unary_expr, allow_struct, allow_block) >>
1066 many0!(alt!(
1067 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001068 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001069 // We can't accept `A + B` in cast expressions, as it's
1070 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001071 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001072 ({
1073 e = ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -05001074 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001075 expr: Box::new(e.into()),
1076 as_token: as_,
1077 ty: Box::new(ty),
1078 }.into();
1079 })
1080 )
1081 |
1082 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001083 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001084 // We can't accept `A + B` in cast expressions, as it's
1085 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001086 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001087 ({
1088 e = ExprType {
David Tolnay8c91b882017-12-28 23:04:32 -05001089 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001090 expr: Box::new(e.into()),
1091 colon_token: colon,
1092 ty: Box::new(ty),
1093 }.into();
1094 })
1095 )
1096 )) >>
1097 (e)
1098 ));
1099
David Tolnay0cf94f22017-12-28 23:46:26 -05001100 // <unary> as <ty>
1101 #[cfg(not(feature = "full"))]
1102 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
1103 mut e: call!(unary_expr, allow_struct, allow_block) >>
1104 many0!(do_parse!(
1105 as_: keyword!(as) >>
1106 // We can't accept `A + B` in cast expressions, as it's
1107 // ambiguous with the + expression.
1108 ty: call!(Type::without_plus) >>
1109 ({
1110 e = ExprCast {
1111 attrs: Vec::new(),
1112 expr: Box::new(e.into()),
1113 as_token: as_,
1114 ty: Box::new(ty),
1115 }.into();
1116 })
1117 )) >>
1118 (e)
1119 ));
1120
David Tolnaybcf26022017-12-25 22:10:52 -05001121 // <UnOp> <trailer>
1122 // & <trailer>
1123 // &mut <trailer>
1124 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001125 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001126 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001127 do_parse!(
1128 op: syn!(UnOp) >>
1129 expr: call!(unary_expr, allow_struct, true) >>
1130 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001131 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001132 op: op,
1133 expr: Box::new(expr.into()),
1134 }.into())
1135 )
1136 |
1137 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001138 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001139 mutability: syn!(Mutability) >>
1140 expr: call!(unary_expr, allow_struct, true) >>
1141 (ExprAddrOf {
David Tolnay8c91b882017-12-28 23:04:32 -05001142 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001143 and_token: and,
1144 mutbl: mutability,
1145 expr: Box::new(expr.into()),
1146 }.into())
1147 )
1148 |
1149 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001150 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001151 expr: call!(unary_expr, allow_struct, true) >>
1152 (ExprBox {
David Tolnay8c91b882017-12-28 23:04:32 -05001153 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001154 box_token: box_,
1155 expr: Box::new(expr.into()),
1156 }.into())
1157 )
1158 |
1159 call!(trailer_expr, allow_struct, allow_block)
1160 ));
1161
Michael Layzell734adb42017-06-07 16:58:31 -04001162 // XXX: This duplication is ugly
1163 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001164 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzell734adb42017-06-07 16:58:31 -04001165 do_parse!(
1166 op: syn!(UnOp) >>
1167 expr: call!(unary_expr, allow_struct, true) >>
1168 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001169 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001170 op: op,
1171 expr: Box::new(expr.into()),
1172 }.into())
1173 )
1174 |
1175 call!(trailer_expr, allow_struct, allow_block)
1176 ));
1177
David Tolnaybcf26022017-12-25 22:10:52 -05001178 // <atom> (..<args>) ...
1179 // <atom> . <ident> (..<args>) ...
1180 // <atom> . <ident> ...
1181 // <atom> . <lit> ...
1182 // <atom> [ <expr> ] ...
1183 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001184 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001185 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001186 mut e: call!(atom_expr, allow_struct, allow_block) >>
1187 many0!(alt!(
1188 tap!(args: and_call => {
1189 let (args, paren) = args;
1190 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001191 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001192 func: Box::new(e.into()),
1193 args: args,
1194 paren_token: paren,
1195 }.into();
1196 })
1197 |
1198 tap!(more: and_method_call => {
1199 let mut call = more;
David Tolnay76418512017-12-28 23:47:47 -05001200 call.receiver = Box::new(e.into());
Michael Layzellb78f3b52017-06-04 19:03:03 -04001201 e = call.into();
1202 })
1203 |
1204 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001205 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001206 e = ExprField {
David Tolnay8c91b882017-12-28 23:04:32 -05001207 attrs: Vec::new(),
David Tolnay85b69a42017-12-27 20:43:10 -05001208 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001209 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001210 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001211 }.into();
1212 })
1213 |
1214 tap!(i: and_index => {
1215 let (i, token) = i;
1216 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001217 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001218 expr: Box::new(e.into()),
1219 bracket_token: token,
1220 index: Box::new(i),
1221 }.into();
1222 })
1223 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001224 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001225 e = ExprTry {
David Tolnay8c91b882017-12-28 23:04:32 -05001226 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001227 expr: Box::new(e.into()),
1228 question_token: question,
1229 }.into();
1230 })
1231 )) >>
1232 (e)
1233 ));
1234
Michael Layzell734adb42017-06-07 16:58:31 -04001235 // XXX: Duplication == ugly
1236 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001237 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzell734adb42017-06-07 16:58:31 -04001238 mut e: call!(atom_expr, allow_struct, allow_block) >>
1239 many0!(alt!(
1240 tap!(args: and_call => {
1241 let (args, paren) = args;
1242 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001243 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001244 func: Box::new(e.into()),
1245 args: args,
1246 paren_token: paren,
1247 }.into();
1248 })
1249 |
1250 tap!(i: and_index => {
1251 let (i, token) = i;
1252 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001253 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001254 expr: Box::new(e.into()),
1255 bracket_token: token,
1256 index: Box::new(i),
1257 }.into();
1258 })
1259 )) >>
1260 (e)
1261 ));
1262
David Tolnaybcf26022017-12-25 22:10:52 -05001263 // Parse all atomic expressions which don't have to worry about precidence
1264 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001265 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001266 named!(atom_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
1267 syn!(ExprGroup) => { Expr::Group } // must be placed first
Michael Layzell93c36282017-06-04 20:43:14 -04001268 |
David Tolnay8c91b882017-12-28 23:04:32 -05001269 syn!(ExprLit) => { Expr::Lit } // must be before expr_struct
Michael Layzellb78f3b52017-06-04 19:03:03 -04001270 |
1271 // must be before expr_path
David Tolnay8c91b882017-12-28 23:04:32 -05001272 cond_reduce!(allow_struct, map!(syn!(ExprStruct), Expr::Struct))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001273 |
David Tolnay8c91b882017-12-28 23:04:32 -05001274 syn!(ExprParen) => { Expr::Paren } // must be before expr_tup
Michael Layzellb78f3b52017-06-04 19:03:03 -04001275 |
David Tolnay8c91b882017-12-28 23:04:32 -05001276 syn!(ExprMacro) => { Expr::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001277 |
1278 call!(expr_break, allow_struct) // must be before expr_path
1279 |
David Tolnay8c91b882017-12-28 23:04:32 -05001280 syn!(ExprContinue) => { Expr::Continue } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001281 |
1282 call!(expr_ret, allow_struct) // must be before expr_path
1283 |
David Tolnay8c91b882017-12-28 23:04:32 -05001284 syn!(ExprArray) => { Expr::Array }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001285 |
David Tolnay8c91b882017-12-28 23:04:32 -05001286 syn!(ExprTuple) => { Expr::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001287 |
David Tolnay8c91b882017-12-28 23:04:32 -05001288 syn!(ExprIf) => { Expr::If }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001289 |
David Tolnay8c91b882017-12-28 23:04:32 -05001290 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001291 |
David Tolnay8c91b882017-12-28 23:04:32 -05001292 syn!(ExprWhile) => { Expr::While }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001293 |
David Tolnay8c91b882017-12-28 23:04:32 -05001294 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001295 |
David Tolnay8c91b882017-12-28 23:04:32 -05001296 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001297 |
David Tolnay8c91b882017-12-28 23:04:32 -05001298 syn!(ExprLoop) => { Expr::Loop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001299 |
David Tolnay8c91b882017-12-28 23:04:32 -05001300 syn!(ExprMatch) => { Expr::Match }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001301 |
David Tolnay8c91b882017-12-28 23:04:32 -05001302 syn!(ExprCatch) => { Expr::Catch }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001303 |
David Tolnay8c91b882017-12-28 23:04:32 -05001304 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001305 |
David Tolnay8c91b882017-12-28 23:04:32 -05001306 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001307 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001308 call!(expr_closure, allow_struct)
1309 |
David Tolnay8c91b882017-12-28 23:04:32 -05001310 cond_reduce!(allow_block, map!(syn!(ExprBlock), Expr::Block))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001311 |
1312 // NOTE: This is the prefix-form of range
1313 call!(expr_range, allow_struct)
1314 |
David Tolnay8c91b882017-12-28 23:04:32 -05001315 syn!(ExprPath) => { Expr::Path }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001316 |
David Tolnay8c91b882017-12-28 23:04:32 -05001317 syn!(ExprRepeat) => { Expr::Repeat }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001318 ));
1319
Michael Layzell734adb42017-06-07 16:58:31 -04001320 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001321 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> Expr, alt!(
David Tolnaye98775f2017-12-28 23:17:00 -05001322 syn!(ExprLit) => { Expr::Lit }
Michael Layzell734adb42017-06-07 16:58:31 -04001323 |
David Tolnay8c91b882017-12-28 23:04:32 -05001324 syn!(ExprPath) => { Expr::Path }
Michael Layzell734adb42017-06-07 16:58:31 -04001325 ));
1326
Michael Layzell734adb42017-06-07 16:58:31 -04001327 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001328 named!(expr_nosemi -> Expr, map!(alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001329 syn!(ExprIf) => { Expr::If }
Michael Layzell35418782017-06-07 09:20:25 -04001330 |
David Tolnay8c91b882017-12-28 23:04:32 -05001331 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzell35418782017-06-07 09:20:25 -04001332 |
David Tolnay8c91b882017-12-28 23:04:32 -05001333 syn!(ExprWhile) => { Expr::While }
Michael Layzell35418782017-06-07 09:20:25 -04001334 |
David Tolnay8c91b882017-12-28 23:04:32 -05001335 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzell35418782017-06-07 09:20:25 -04001336 |
David Tolnay8c91b882017-12-28 23:04:32 -05001337 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzell35418782017-06-07 09:20:25 -04001338 |
David Tolnay8c91b882017-12-28 23:04:32 -05001339 syn!(ExprLoop) => { Expr::Loop }
Michael Layzell35418782017-06-07 09:20:25 -04001340 |
David Tolnay8c91b882017-12-28 23:04:32 -05001341 syn!(ExprMatch) => { Expr::Match }
Michael Layzell35418782017-06-07 09:20:25 -04001342 |
David Tolnay8c91b882017-12-28 23:04:32 -05001343 syn!(ExprCatch) => { Expr::Catch }
Michael Layzell35418782017-06-07 09:20:25 -04001344 |
David Tolnay8c91b882017-12-28 23:04:32 -05001345 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001346 |
David Tolnay8c91b882017-12-28 23:04:32 -05001347 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001348 |
David Tolnay8c91b882017-12-28 23:04:32 -05001349 syn!(ExprBlock) => { Expr::Block }
Michael Layzell35418782017-06-07 09:20:25 -04001350 ), Expr::from));
1351
David Tolnay8c91b882017-12-28 23:04:32 -05001352 impl Synom for ExprLit {
1353 named!(parse -> Self, do_parse!(
1354 lit: syn!(Lit) >>
1355 (ExprLit {
1356 attrs: Vec::new(),
1357 lit: lit,
1358 })
1359 ));
1360 }
1361
1362 #[cfg(feature = "full")]
1363 impl Synom for ExprMacro {
1364 named!(parse -> Self, do_parse!(
1365 mac: syn!(Macro) >>
1366 (ExprMacro {
1367 attrs: Vec::new(),
1368 mac: mac,
1369 })
1370 ));
1371 }
1372
David Tolnaye98775f2017-12-28 23:17:00 -05001373 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04001374 impl Synom for ExprGroup {
1375 named!(parse -> Self, do_parse!(
1376 e: grouped!(syn!(Expr)) >>
1377 (ExprGroup {
David Tolnay8c91b882017-12-28 23:04:32 -05001378 attrs: Vec::new(),
Michael Layzell93c36282017-06-04 20:43:14 -04001379 expr: Box::new(e.0),
1380 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001381 })
Michael Layzell93c36282017-06-04 20:43:14 -04001382 ));
1383 }
1384
David Tolnaye98775f2017-12-28 23:17:00 -05001385 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001386 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001387 named!(parse -> Self, do_parse!(
1388 e: parens!(syn!(Expr)) >>
1389 (ExprParen {
David Tolnay8c91b882017-12-28 23:04:32 -05001390 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001391 expr: Box::new(e.0),
1392 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001393 })
Michael Layzell92639a52017-06-01 00:07:44 -04001394 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001395 }
David Tolnay89e05672016-10-02 14:39:42 -07001396
Michael Layzell734adb42017-06-07 16:58:31 -04001397 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001398 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001399 named!(parse -> Self, do_parse!(
1400 elems: brackets!(call!(Delimited::parse_terminated)) >>
1401 (ExprArray {
David Tolnay8c91b882017-12-28 23:04:32 -05001402 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001403 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001404 bracket_token: elems.1,
1405 })
1406 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001407 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001408
David Tolnay32954ef2017-12-26 22:43:16 -05001409 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001410 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001411
Michael Layzell734adb42017-06-07 16:58:31 -04001412 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001413 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001414 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001415 method: syn!(Ident) >>
David Tolnayd60cfec2017-12-29 00:21:38 -05001416 turbofish: option!(tuple!(
1417 punct!(::),
1418 punct!(<),
1419 call!(Delimited::parse_terminated),
1420 punct!(>)
David Tolnayfa0edf22016-09-23 22:58:24 -07001421 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001422 args: parens!(call!(Delimited::parse_terminated)) >>
1423 ({
Alex Crichton954046c2017-05-30 21:49:42 -07001424 ExprMethodCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001425 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001426 // this expr will get overwritten after being returned
David Tolnay76418512017-12-28 23:47:47 -05001427 receiver: Box::new(Expr::Lit(ExprLit {
David Tolnay8c91b882017-12-28 23:04:32 -05001428 attrs: Vec::new(),
1429 lit: Lit {
1430 span: Span::default(),
1431 value: LitKind::Bool(false),
1432 },
Alex Crichton954046c2017-05-30 21:49:42 -07001433 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001434
Alex Crichton954046c2017-05-30 21:49:42 -07001435 method: method,
David Tolnayd60cfec2017-12-29 00:21:38 -05001436 turbofish: turbofish.map(|fish| MethodTurbofish {
1437 colon2_token: fish.0,
1438 lt_token: fish.1,
1439 args: fish.2,
1440 gt_token: fish.3,
1441 }),
Alex Crichton954046c2017-05-30 21:49:42 -07001442 args: args.0,
1443 paren_token: args.1,
1444 dot_token: dot,
Alex Crichton954046c2017-05-30 21:49:42 -07001445 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001446 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001447 ));
1448
Michael Layzell734adb42017-06-07 16:58:31 -04001449 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05001450 impl Synom for GenericMethodArgument {
1451 // TODO parse const generics as well
1452 named!(parse -> Self, map!(ty_no_eq_after, GenericMethodArgument::Type));
1453 }
1454
1455 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001456 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001457 named!(parse -> Self, do_parse!(
1458 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001459 (ExprTuple {
David Tolnay8c91b882017-12-28 23:04:32 -05001460 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001461 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001462 paren_token: elems.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001463 })
1464 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001465 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001466
Michael Layzell734adb42017-06-07 16:58:31 -04001467 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001468 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001469 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001470 if_: keyword!(if) >>
1471 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001472 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001473 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001474 cond: expr_no_struct >>
1475 then_block: braces!(call!(Block::parse_within)) >>
1476 else_block: option!(else_block) >>
1477 (ExprIfLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001478 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001479 pat: Box::new(pat),
1480 let_token: let_,
1481 eq_token: eq,
1482 expr: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001483 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001484 stmts: then_block.0,
1485 brace_token: then_block.1,
1486 },
1487 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001488 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001489 })
1490 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001491 }
1492
Michael Layzell734adb42017-06-07 16:58:31 -04001493 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001494 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001495 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001496 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001497 cond: expr_no_struct >>
1498 then_block: braces!(call!(Block::parse_within)) >>
1499 else_block: option!(else_block) >>
1500 (ExprIf {
David Tolnay8c91b882017-12-28 23:04:32 -05001501 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001502 cond: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001503 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001504 stmts: then_block.0,
1505 brace_token: then_block.1,
1506 },
1507 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001508 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001509 })
1510 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001511 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001512
Michael Layzell734adb42017-06-07 16:58:31 -04001513 #[cfg(feature = "full")]
David Tolnay2ccf32a2017-12-29 00:34:26 -05001514 named!(else_block -> (Token![else], Box<Expr>), do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001515 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001516 expr: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001517 syn!(ExprIf) => { Expr::If }
Alex Crichton954046c2017-05-30 21:49:42 -07001518 |
David Tolnay8c91b882017-12-28 23:04:32 -05001519 syn!(ExprIfLet) => { Expr::IfLet }
Alex Crichton954046c2017-05-30 21:49:42 -07001520 |
1521 do_parse!(
1522 else_block: braces!(call!(Block::parse_within)) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001523 (Expr::Block(ExprBlock {
1524 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001525 block: Block {
1526 stmts: else_block.0,
1527 brace_token: else_block.1,
1528 },
1529 }))
David Tolnay939766a2016-09-23 23:48:12 -07001530 )
Alex Crichton954046c2017-05-30 21:49:42 -07001531 ) >>
David Tolnay2ccf32a2017-12-29 00:34:26 -05001532 (else_, Box::new(expr))
David Tolnay939766a2016-09-23 23:48:12 -07001533 ));
1534
Michael Layzell734adb42017-06-07 16:58:31 -04001535 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001536 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001537 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001538 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1539 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001540 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001541 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001542 expr: expr_no_struct >>
1543 loop_block: syn!(Block) >>
1544 (ExprForLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001545 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001546 for_token: for_,
1547 in_token: in_,
1548 pat: Box::new(pat),
1549 expr: Box::new(expr),
1550 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001551 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001552 label: lbl.map(|p| p.0),
1553 })
1554 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001555 }
Gregory Katze5f35682016-09-27 14:20:55 -04001556
Michael Layzell734adb42017-06-07 16:58:31 -04001557 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001558 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001559 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001560 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1561 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001562 loop_block: syn!(Block) >>
1563 (ExprLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001564 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001565 loop_token: loop_,
1566 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001567 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001568 label: lbl.map(|p| p.0),
1569 })
1570 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001571 }
1572
Michael Layzell734adb42017-06-07 16:58:31 -04001573 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001574 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001575 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001576 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001577 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001578 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001579 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001580 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001581 ExprMatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001582 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001583 expr: Box::new(obj),
1584 match_token: match_,
1585 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001586 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001587 }
1588 })
1589 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001590 }
David Tolnay1978c672016-10-27 22:05:52 -07001591
Michael Layzell734adb42017-06-07 16:58:31 -04001592 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001593 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001594 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001595 do_: keyword!(do) >>
1596 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001597 catch_block: syn!(Block) >>
1598 (ExprCatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001599 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001600 block: catch_block,
1601 do_token: do_,
1602 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001603 })
Michael Layzell92639a52017-06-01 00:07:44 -04001604 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001605 }
Arnavion02ef13f2017-04-25 00:54:31 -07001606
Michael Layzell734adb42017-06-07 16:58:31 -04001607 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001608 impl Synom for ExprYield {
1609 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001610 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001611 expr: option!(syn!(Expr)) >>
1612 (ExprYield {
David Tolnay8c91b882017-12-28 23:04:32 -05001613 attrs: Vec::new(),
Alex Crichtonfe110462017-06-01 12:49:27 -07001614 yield_token: yield_,
1615 expr: expr.map(Box::new),
1616 })
1617 ));
1618 }
1619
1620 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001621 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001622 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001623 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001624 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001625 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1626 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001627 body: do_parse!(
1628 expr: alt!(expr_nosemi | syn!(Expr)) >>
1629 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1630 map!(input_end!(), |_| None)
1631 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001632 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001633 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001634 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001635 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001636 ) >>
1637 (Arm {
1638 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001639 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001640 attrs: attrs,
1641 pats: pats,
1642 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001643 body: Box::new(body.0),
1644 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001645 })
1646 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001647 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001648
Michael Layzell734adb42017-06-07 16:58:31 -04001649 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001650 named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001651 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001652 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001653 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001654 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001655 ret_and_body: alt!(
1656 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001657 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001658 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001659 body: syn!(Block) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -05001660 (ReturnType::Type(arrow, Box::new(ty)),
David Tolnay8c91b882017-12-28 23:04:32 -05001661 Expr::Block(ExprBlock {
1662 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001663 block: body,
1664 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001665 )
1666 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001667 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001668 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001669 (ExprClosure {
David Tolnay8c91b882017-12-28 23:04:32 -05001670 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001671 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001672 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001673 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001674 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001675 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001676 body: Box::new(ret_and_body.1),
1677 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001678 ));
1679
Michael Layzell734adb42017-06-07 16:58:31 -04001680 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001681 named!(fn_arg -> FnArg, do_parse!(
1682 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001683 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001684 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001685 if let Some((colon, ty)) = ty {
1686 FnArg::Captured(ArgCaptured {
1687 pat: pat,
1688 colon_token: colon,
1689 ty: ty,
1690 })
1691 } else {
1692 FnArg::Inferred(pat)
1693 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001694 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001695 ));
1696
Michael Layzell734adb42017-06-07 16:58:31 -04001697 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001698 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001699 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001700 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1701 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001702 cond: expr_no_struct >>
1703 while_block: syn!(Block) >>
1704 (ExprWhile {
David Tolnay8c91b882017-12-28 23:04:32 -05001705 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001706 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001707 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001708 cond: Box::new(cond),
1709 body: while_block,
1710 label: lbl.map(|p| p.0),
1711 })
1712 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001713 }
1714
Michael Layzell734adb42017-06-07 16:58:31 -04001715 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001716 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001717 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001718 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1719 while_: keyword!(while) >>
1720 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001721 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001722 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001723 value: expr_no_struct >>
1724 while_block: syn!(Block) >>
1725 (ExprWhileLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001726 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001727 eq_token: eq,
1728 let_token: let_,
1729 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001730 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001731 pat: Box::new(pat),
1732 expr: Box::new(value),
1733 body: while_block,
1734 label: lbl.map(|p| p.0),
1735 })
1736 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001737 }
1738
Michael Layzell734adb42017-06-07 16:58:31 -04001739 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001740 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001741 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001742 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001743 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001744 (ExprContinue {
David Tolnay8c91b882017-12-28 23:04:32 -05001745 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001746 continue_token: cont,
1747 label: lbl,
1748 })
1749 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001750 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001751
Michael Layzell734adb42017-06-07 16:58:31 -04001752 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001753 named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001754 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001755 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001756 // We can't allow blocks after a `break` expression when we wouldn't
1757 // allow structs, as this expression is ambiguous.
1758 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001759 (ExprBreak {
David Tolnay8c91b882017-12-28 23:04:32 -05001760 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001761 label: lbl,
1762 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001763 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001764 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001765 ));
1766
Michael Layzell734adb42017-06-07 16:58:31 -04001767 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001768 named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001769 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001770 // NOTE: return is greedy and eats blocks after it even when in a
1771 // position where structs are not allowed, such as in if statement
1772 // conditions. For example:
1773 //
David Tolnaybcf26022017-12-25 22:10:52 -05001774 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001775 ret_value: option!(ambiguous_expr!(allow_struct)) >>
David Tolnayc246cd32017-12-28 23:14:32 -05001776 (ExprReturn {
David Tolnay8c91b882017-12-28 23:04:32 -05001777 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001778 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001779 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001780 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001781 ));
1782
Michael Layzell734adb42017-06-07 16:58:31 -04001783 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001784 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001785 named!(parse -> Self, do_parse!(
1786 path: syn!(Path) >>
1787 data: braces!(do_parse!(
1788 fields: call!(Delimited::parse_terminated) >>
1789 base: option!(
1790 cond!(fields.is_empty() || fields.trailing_delim(),
1791 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001792 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001793 base: syn!(Expr) >>
1794 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001795 )
Michael Layzell92639a52017-06-01 00:07:44 -04001796 )
1797 ) >>
1798 (fields, base)
1799 )) >>
1800 ({
1801 let ((fields, base), brace) = data;
1802 let (dots, rest) = match base.and_then(|b| b) {
1803 Some((dots, base)) => (Some(dots), Some(base)),
1804 None => (None, None),
1805 };
1806 ExprStruct {
David Tolnay8c91b882017-12-28 23:04:32 -05001807 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001808 brace_token: brace,
1809 path: path,
1810 fields: fields,
1811 dot2_token: dots,
1812 rest: rest.map(Box::new),
1813 }
1814 })
1815 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001816 }
1817
Michael Layzell734adb42017-06-07 16:58:31 -04001818 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001819 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001820 named!(parse -> Self, alt!(
1821 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001822 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001823 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001824 value: syn!(Expr) >>
1825 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001826 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001827 expr: value,
Alex Crichton954046c2017-05-30 21:49:42 -07001828 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001829 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001830 })
Michael Layzell92639a52017-06-01 00:07:44 -04001831 )
1832 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001833 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001834 member: Member::Named(name),
David Tolnay8c91b882017-12-28 23:04:32 -05001835 expr: Expr::Path(ExprPath {
1836 attrs: Vec::new(),
1837 qself: None,
1838 path: name.into(),
1839 }).into(),
Michael Layzell92639a52017-06-01 00:07:44 -04001840 attrs: Vec::new(),
1841 colon_token: None,
1842 })
1843 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001844 }
David Tolnay055a7042016-10-02 19:23:54 -07001845
Michael Layzell734adb42017-06-07 16:58:31 -04001846 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001847 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001848 named!(parse -> Self, do_parse!(
1849 data: brackets!(do_parse!(
1850 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001851 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001852 times: syn!(Expr) >>
1853 (value, semi, times)
1854 )) >>
1855 (ExprRepeat {
David Tolnay8c91b882017-12-28 23:04:32 -05001856 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001857 expr: Box::new((data.0).0),
1858 amt: Box::new((data.0).2),
1859 bracket_token: data.1,
1860 semi_token: (data.0).1,
1861 })
1862 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001863 }
David Tolnay055a7042016-10-02 19:23:54 -07001864
Michael Layzell734adb42017-06-07 16:58:31 -04001865 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001866 impl Synom for ExprUnsafe {
1867 named!(parse -> Self, do_parse!(
1868 unsafe_: keyword!(unsafe) >>
1869 b: syn!(Block) >>
1870 (ExprUnsafe {
David Tolnay8c91b882017-12-28 23:04:32 -05001871 attrs: Vec::new(),
Nika Layzell640832a2017-12-04 13:37:09 -05001872 unsafe_token: unsafe_,
1873 block: b,
1874 })
1875 ));
1876 }
1877
1878 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001879 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001880 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001881 b: syn!(Block) >>
1882 (ExprBlock {
David Tolnay8c91b882017-12-28 23:04:32 -05001883 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001884 block: b,
1885 })
1886 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001887 }
David Tolnay89e05672016-10-02 14:39:42 -07001888
Michael Layzell734adb42017-06-07 16:58:31 -04001889 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001890 named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001891 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001892 hi: opt_ambiguous_expr!(allow_struct) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001893 (ExprRange {
1894 attrs: Vec::new(),
1895 from: None,
1896 to: hi.map(Box::new),
1897 limits: limits,
1898 }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001899 ));
1900
Michael Layzell734adb42017-06-07 16:58:31 -04001901 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001902 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001903 named!(parse -> Self, alt!(
1904 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001905 punct!(..=) => { RangeLimits::Closed }
1906 |
1907 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001908 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001909 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001910 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001911 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001912 }
David Tolnay438c9052016-10-07 23:24:48 -07001913
Alex Crichton954046c2017-05-30 21:49:42 -07001914 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001915 named!(parse -> Self, do_parse!(
1916 pair: qpath >>
1917 (ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -05001918 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001919 qself: pair.0,
1920 path: pair.1,
1921 })
1922 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001923 }
David Tolnay42602292016-10-01 22:25:45 -07001924
Michael Layzell734adb42017-06-07 16:58:31 -04001925 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001926 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001927
David Tolnay32954ef2017-12-26 22:43:16 -05001928 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001929
Michael Layzell734adb42017-06-07 16:58:31 -04001930 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001931 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001932 named!(parse -> Self, do_parse!(
1933 stmts: braces!(call!(Block::parse_within)) >>
1934 (Block {
1935 stmts: stmts.0,
1936 brace_token: stmts.1,
1937 })
1938 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001939 }
David Tolnay939766a2016-09-23 23:48:12 -07001940
Michael Layzell734adb42017-06-07 16:58:31 -04001941 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001942 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001943 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001944 many0!(punct!(;)) >>
1945 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001946 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001947 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001948 mut e: syn!(Expr) >>
1949 ({
David Tolnay8c91b882017-12-28 23:04:32 -05001950 *e.attrs_mut() = attrs;
Alex Crichton70bbd592017-08-27 10:40:03 -07001951 Stmt::Expr(Box::new(e))
1952 })
1953 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001954 (match last {
1955 None => standalone,
1956 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001957 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001958 standalone
1959 }
1960 })
1961 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001962 }
1963
Michael Layzell734adb42017-06-07 16:58:31 -04001964 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001965 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001966 named!(parse -> Self, alt!(
1967 stmt_mac
1968 |
1969 stmt_local
1970 |
1971 stmt_item
1972 |
Michael Layzell35418782017-06-07 09:20:25 -04001973 stmt_blockexpr
1974 |
Michael Layzell92639a52017-06-01 00:07:44 -04001975 stmt_expr
1976 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001977 }
David Tolnay939766a2016-09-23 23:48:12 -07001978
Michael Layzell734adb42017-06-07 16:58:31 -04001979 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001980 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001981 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001982 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001983 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001984 // Only parse braces here; paren and bracket will get parsed as
1985 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001986 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001987 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05001988 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
1989 attrs: attrs,
1990 ident: None,
1991 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001992 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001993 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001994 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001995 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001996 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001997 },
David Tolnayeea28d62016-10-25 20:44:08 -07001998 },
David Tolnay57b52bc2017-12-28 18:06:38 -05001999 semi_token: semi,
2000 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07002001 ));
2002
Michael Layzell734adb42017-06-07 16:58:31 -04002003 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002004 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002005 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002006 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002007 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002008 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002009 init: option!(tuple!(punct!(=), syn!(Expr))) >>
2010 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07002011 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07002012 let_token: let_,
2013 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002014 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
2015 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07002016 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002017 ty: ty.map(|p| Box::new(p.1)),
2018 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07002019 attrs: attrs,
2020 })))
2021 ));
2022
Michael Layzell734adb42017-06-07 16:58:31 -04002023 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002024 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07002025
Michael Layzell734adb42017-06-07 16:58:31 -04002026 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04002027 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002028 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04002029 mut e: expr_nosemi >>
2030 // If the next token is a `.` or a `?` it is special-cased to parse as
2031 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08002032 not!(punct!(.)) >>
2033 not!(punct!(?)) >>
2034 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04002035 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002036 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002037 if let Some(semi) = semi {
2038 Stmt::Semi(Box::new(e), semi)
2039 } else {
2040 Stmt::Expr(Box::new(e))
2041 }
2042 })
2043 ));
David Tolnaycfe55022016-10-02 22:02:27 -07002044
Michael Layzell734adb42017-06-07 16:58:31 -04002045 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07002046 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002047 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002048 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002049 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07002050 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002051 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002052 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07002053 })
David Tolnay939766a2016-09-23 23:48:12 -07002054 ));
David Tolnay8b07f372016-09-30 10:28:40 -07002055
Michael Layzell734adb42017-06-07 16:58:31 -04002056 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002057 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04002058 named!(parse -> Self, alt!(
2059 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
2060 |
2061 syn!(PatBox) => { Pat::Box } // must be before pat_ident
2062 |
2063 syn!(PatRange) => { Pat::Range } // must be before pat_lit
2064 |
2065 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
2066 |
2067 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
2068 |
David Tolnaydecf28d2017-11-11 11:56:45 -08002069 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04002070 |
2071 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
2072 |
2073 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
2074 |
2075 syn!(PatPath) => { Pat::Path }
2076 |
2077 syn!(PatTuple) => { Pat::Tuple }
2078 |
2079 syn!(PatRef) => { Pat::Ref }
2080 |
2081 syn!(PatSlice) => { Pat::Slice }
2082 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002083 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002084
Michael Layzell734adb42017-06-07 16:58:31 -04002085 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002086 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04002087 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002088 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04002089 |u| PatWild { underscore_token: u }
2090 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002091 }
David Tolnay84aa0752016-10-02 23:01:13 -07002092
Michael Layzell734adb42017-06-07 16:58:31 -04002093 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002094 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04002095 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002096 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002097 pat: syn!(Pat) >>
2098 (PatBox {
2099 pat: Box::new(pat),
2100 box_token: boxed,
2101 })
2102 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002103 }
2104
Michael Layzell734adb42017-06-07 16:58:31 -04002105 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002106 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04002107 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002108 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002109 mutability: syn!(Mutability) >>
2110 name: alt!(
2111 syn!(Ident)
2112 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08002113 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04002114 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002115 not!(punct!(<)) >>
2116 not!(punct!(::)) >>
2117 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002118 (PatIdent {
2119 mode: match mode {
2120 Some(mode) => BindingMode::ByRef(mode, mutability),
2121 None => BindingMode::ByValue(mutability),
2122 },
2123 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002124 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002125 subpat: subpat.map(|p| Box::new(p.1)),
2126 })
2127 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002128 }
2129
Michael Layzell734adb42017-06-07 16:58:31 -04002130 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002131 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002132 named!(parse -> Self, do_parse!(
2133 path: syn!(Path) >>
2134 tuple: syn!(PatTuple) >>
2135 (PatTupleStruct {
2136 path: path,
2137 pat: tuple,
2138 })
2139 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002140 }
2141
Michael Layzell734adb42017-06-07 16:58:31 -04002142 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002143 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002144 named!(parse -> Self, do_parse!(
2145 path: syn!(Path) >>
2146 data: braces!(do_parse!(
2147 fields: call!(Delimited::parse_terminated) >>
2148 base: option!(
2149 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002150 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002151 ) >>
2152 (fields, base)
2153 )) >>
2154 (PatStruct {
2155 path: path,
2156 fields: (data.0).0,
2157 brace_token: data.1,
2158 dot2_token: (data.0).1.and_then(|m| m),
2159 })
2160 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002161 }
2162
Michael Layzell734adb42017-06-07 16:58:31 -04002163 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002164 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002165 named!(parse -> Self, alt!(
2166 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002167 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002168 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002169 pat: syn!(Pat) >>
2170 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002171 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002172 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002173 attrs: Vec::new(),
2174 colon_token: Some(colon),
2175 })
2176 )
2177 |
2178 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002179 boxed: option!(keyword!(box)) >>
2180 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002181 mutability: syn!(Mutability) >>
2182 ident: syn!(Ident) >>
2183 ({
2184 let mut pat: Pat = PatIdent {
2185 mode: if let Some(mode) = mode {
2186 BindingMode::ByRef(mode, mutability)
2187 } else {
2188 BindingMode::ByValue(mutability)
2189 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002190 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002191 subpat: None,
2192 at_token: None,
2193 }.into();
2194 if let Some(boxed) = boxed {
2195 pat = PatBox {
2196 pat: Box::new(pat),
2197 box_token: boxed,
2198 }.into();
2199 }
2200 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002201 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002202 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002203 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002204 colon_token: None,
2205 }
2206 })
2207 )
2208 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002209 }
2210
Michael Layzell734adb42017-06-07 16:58:31 -04002211 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002212 impl Synom for Member {
2213 named!(parse -> Self, alt!(
2214 syn!(Ident) => { Member::Named }
2215 |
2216 syn!(Index) => { Member::Unnamed }
2217 ));
2218 }
2219
2220 #[cfg(feature = "full")]
2221 impl Synom for Index {
2222 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002223 lit: syn!(Lit) >>
2224 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002225 if let Ok(i) = lit.value.to_string().parse() {
2226 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002227 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002228 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002229 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002230 })
David Tolnay85b69a42017-12-27 20:43:10 -05002231 ));
2232 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002233
Michael Layzell734adb42017-06-07 16:58:31 -04002234 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002235 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002236 named!(parse -> Self, map!(
2237 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002238 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002239 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002240 }
David Tolnay9636c052016-10-02 17:11:17 -07002241
Michael Layzell734adb42017-06-07 16:58:31 -04002242 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002243 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002244 named!(parse -> Self, do_parse!(
2245 data: parens!(do_parse!(
David Tolnay41871922017-12-29 01:53:45 -05002246 front: call!(Delimited::parse_terminated) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002247 dotdot: map!(cond!(
David Tolnay41871922017-12-29 01:53:45 -05002248 front.is_empty() || front.trailing_delim(),
Michael Layzell92639a52017-06-01 00:07:44 -04002249 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002250 dots: punct!(..) >>
2251 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002252 (dots, trailing)
2253 ))
David Tolnay41871922017-12-29 01:53:45 -05002254 ), Option::unwrap_or_default) >>
2255 back: cond!(match dotdot {
Michael Layzell92639a52017-06-01 00:07:44 -04002256 Some((_, Some(_))) => true,
2257 _ => false,
2258 },
2259 call!(Delimited::parse_terminated)) >>
David Tolnay41871922017-12-29 01:53:45 -05002260 (front, dotdot, back)
Michael Layzell92639a52017-06-01 00:07:44 -04002261 )) >>
2262 ({
David Tolnay41871922017-12-29 01:53:45 -05002263 let ((front, dotdot, back), parens) = data;
Michael Layzell92639a52017-06-01 00:07:44 -04002264 let (dotdot, trailing) = match dotdot {
2265 Some((a, b)) => (Some(a), Some(b)),
2266 None => (None, None),
2267 };
2268 PatTuple {
2269 paren_token: parens,
David Tolnay41871922017-12-29 01:53:45 -05002270 front: front,
Michael Layzell92639a52017-06-01 00:07:44 -04002271 dot2_token: dotdot,
David Tolnay41871922017-12-29 01:53:45 -05002272 comma_token: trailing.unwrap_or_default(),
2273 back: back.unwrap_or_default(),
Michael Layzell92639a52017-06-01 00:07:44 -04002274 }
2275 })
2276 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002277 }
David Tolnayfbb73232016-10-03 01:00:06 -07002278
Michael Layzell734adb42017-06-07 16:58:31 -04002279 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002280 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002281 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002282 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002283 mutability: syn!(Mutability) >>
2284 pat: syn!(Pat) >>
2285 (PatRef {
2286 pat: Box::new(pat),
2287 mutbl: mutability,
2288 and_token: and,
2289 })
2290 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002291 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002292
Michael Layzell734adb42017-06-07 16:58:31 -04002293 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002294 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002295 named!(parse -> Self, do_parse!(
2296 lit: pat_lit_expr >>
David Tolnay8c91b882017-12-28 23:04:32 -05002297 (if let Expr::Path(_) = lit {
Michael Layzell92639a52017-06-01 00:07:44 -04002298 return parse_error(); // these need to be parsed by pat_path
2299 } else {
2300 PatLit {
2301 expr: Box::new(lit),
2302 }
2303 })
2304 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002305 }
David Tolnaye1310902016-10-29 23:40:00 -07002306
Michael Layzell734adb42017-06-07 16:58:31 -04002307 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002308 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002309 named!(parse -> Self, do_parse!(
2310 lo: pat_lit_expr >>
2311 limits: syn!(RangeLimits) >>
2312 hi: pat_lit_expr >>
2313 (PatRange {
2314 lo: Box::new(lo),
2315 hi: Box::new(hi),
2316 limits: limits,
2317 })
2318 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002319 }
David Tolnaye1310902016-10-29 23:40:00 -07002320
Michael Layzell734adb42017-06-07 16:58:31 -04002321 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002322 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002323 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002324 v: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05002325 syn!(ExprLit) => { Expr::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002326 |
David Tolnay8c91b882017-12-28 23:04:32 -05002327 syn!(ExprPath) => { Expr::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002328 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002329 (if let Some(neg) = neg {
David Tolnay8c91b882017-12-28 23:04:32 -05002330 Expr::Unary(ExprUnary {
2331 attrs: Vec::new(),
David Tolnayc29b9892017-12-27 22:58:14 -05002332 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002333 expr: Box::new(v.into())
2334 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002335 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002336 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002337 })
2338 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002339
Michael Layzell734adb42017-06-07 16:58:31 -04002340 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002341 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002342 named!(parse -> Self, map!(
2343 brackets!(do_parse!(
2344 before: call!(Delimited::parse_terminated) >>
2345 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002346 dots: punct!(..) >>
2347 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002348 (dots, trailing)
2349 )) >>
2350 after: cond!(
2351 match middle {
2352 Some((_, ref trailing)) => trailing.is_some(),
2353 _ => false,
2354 },
2355 call!(Delimited::parse_terminated)
2356 ) >>
2357 (before, middle, after)
2358 )),
2359 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002360 let mut before: Delimited<Pat, Token![,]> = before;
2361 let after: Option<Delimited<Pat, Token![,]>> = after;
2362 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002363 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002364 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002365 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002366 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002367 }),
2368 bracket_token: brackets,
2369 middle: middle.and_then(|_| {
2370 if !before.is_empty() && !before.trailing_delim() {
2371 Some(Box::new(before.pop().unwrap().into_item()))
2372 } else {
2373 None
2374 }
2375 }),
2376 front: before,
2377 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002378 }
Alex Crichton954046c2017-05-30 21:49:42 -07002379 }
Michael Layzell92639a52017-06-01 00:07:44 -04002380 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002381 }
David Tolnay435a9a82016-10-29 13:47:20 -07002382
Michael Layzell734adb42017-06-07 16:58:31 -04002383 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002384 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002385 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002386 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002387 |
2388 epsilon!() => { |_| CaptureBy::Ref }
2389 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002390 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002391}
2392
David Tolnayf4bbbd92016-09-23 14:41:55 -07002393#[cfg(feature = "printing")]
2394mod printing {
2395 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002396 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002397 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002398 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002399 #[cfg(feature = "full")]
2400 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002401
David Tolnaybcf26022017-12-25 22:10:52 -05002402 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2403 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002404 #[cfg(feature = "full")]
2405 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
David Tolnay8c91b882017-12-28 23:04:32 -05002406 if let Expr::Struct(_) = *e {
David Tolnay32954ef2017-12-26 22:43:16 -05002407 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002408 e.to_tokens(tokens);
2409 });
2410 } else {
2411 e.to_tokens(tokens);
2412 }
2413 }
2414
David Tolnay8c91b882017-12-28 23:04:32 -05002415 #[cfg(feature = "full")]
2416 fn attrs_to_tokens(attrs: &[Attribute], tokens: &mut Tokens) {
2417 tokens.append_all(attrs.outer());
2418 }
Michael Layzell734adb42017-06-07 16:58:31 -04002419
David Tolnay8c91b882017-12-28 23:04:32 -05002420 #[cfg(not(feature = "full"))]
2421 fn attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002422 }
2423
Michael Layzell734adb42017-06-07 16:58:31 -04002424 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002425 impl ToTokens for ExprBox {
2426 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002427 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002428 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002429 self.expr.to_tokens(tokens);
2430 }
2431 }
2432
Michael Layzell734adb42017-06-07 16:58:31 -04002433 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002434 impl ToTokens for ExprInPlace {
2435 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002436 tokens.append_all(self.attrs.outer());
David Tolnay8701a5c2017-12-28 23:31:10 -05002437 self.place.to_tokens(tokens);
2438 self.arrow_token.to_tokens(tokens);
2439 self.value.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002440 }
2441 }
2442
Michael Layzell734adb42017-06-07 16:58:31 -04002443 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002444 impl ToTokens for ExprArray {
2445 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002446 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002447 self.bracket_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002448 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002449 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002450 }
2451 }
2452
2453 impl ToTokens for ExprCall {
2454 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002455 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002456 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002457 self.paren_token.surround(tokens, |tokens| {
2458 self.args.to_tokens(tokens);
2459 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002460 }
2461 }
2462
Michael Layzell734adb42017-06-07 16:58:31 -04002463 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002464 impl ToTokens for ExprMethodCall {
2465 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002466 tokens.append_all(self.attrs.outer());
David Tolnay76418512017-12-28 23:47:47 -05002467 self.receiver.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002468 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 self.method.to_tokens(tokens);
David Tolnayd60cfec2017-12-29 00:21:38 -05002470 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002471 self.paren_token.surround(tokens, |tokens| {
2472 self.args.to_tokens(tokens);
2473 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002474 }
2475 }
2476
Michael Layzell734adb42017-06-07 16:58:31 -04002477 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05002478 impl ToTokens for MethodTurbofish {
2479 fn to_tokens(&self, tokens: &mut Tokens) {
2480 self.colon2_token.to_tokens(tokens);
2481 self.lt_token.to_tokens(tokens);
2482 self.args.to_tokens(tokens);
2483 self.gt_token.to_tokens(tokens);
2484 }
2485 }
2486
2487 #[cfg(feature = "full")]
2488 impl ToTokens for GenericMethodArgument {
2489 fn to_tokens(&self, tokens: &mut Tokens) {
2490 match *self {
2491 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
2492 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
2493 }
2494 }
2495 }
2496
2497 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002498 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002499 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002500 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002501 self.paren_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002502 self.elems.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002503 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002504 // distinguish ExprTuple from ExprParen.
David Tolnay2a86fdd2017-12-28 23:34:28 -05002505 if self.elems.len() == 1 && !self.elems.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002506 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002507 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002508 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002509 }
2510 }
2511
2512 impl ToTokens for ExprBinary {
2513 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002514 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002515 self.left.to_tokens(tokens);
2516 self.op.to_tokens(tokens);
2517 self.right.to_tokens(tokens);
2518 }
2519 }
2520
2521 impl ToTokens for ExprUnary {
2522 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002523 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002524 self.op.to_tokens(tokens);
2525 self.expr.to_tokens(tokens);
2526 }
2527 }
2528
David Tolnay8c91b882017-12-28 23:04:32 -05002529 impl ToTokens for ExprLit {
2530 fn to_tokens(&self, tokens: &mut Tokens) {
2531 attrs_to_tokens(&self.attrs, tokens);
2532 self.lit.to_tokens(tokens);
2533 }
2534 }
2535
Alex Crichton62a0a592017-05-22 13:58:53 -07002536 impl ToTokens for ExprCast {
2537 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002538 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002539 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002540 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002541 self.ty.to_tokens(tokens);
2542 }
2543 }
2544
David Tolnay0cf94f22017-12-28 23:46:26 -05002545 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002546 impl ToTokens for ExprType {
2547 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002548 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002549 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002550 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002551 self.ty.to_tokens(tokens);
2552 }
2553 }
2554
Michael Layzell734adb42017-06-07 16:58:31 -04002555 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002556 fn maybe_wrap_else(
2557 tokens: &mut Tokens,
David Tolnay2ccf32a2017-12-29 00:34:26 -05002558 else_: &Option<(Token![else], Box<Expr>)>,
David Tolnay51382052017-12-27 13:46:21 -05002559 ) {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002560 if let Some((ref else_token, ref else_)) = *else_ {
2561 else_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002562
2563 // If we are not one of the valid expressions to exist in an else
2564 // clause, wrap ourselves in a block.
David Tolnay2ccf32a2017-12-29 00:34:26 -05002565 match **else_ {
David Tolnay8c91b882017-12-28 23:04:32 -05002566 Expr::If(_) | Expr::IfLet(_) | Expr::Block(_) => {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002567 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002568 }
2569 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002570 token::Brace::default().surround(tokens, |tokens| {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002571 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002572 });
2573 }
2574 }
2575 }
2576 }
2577
2578 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002579 impl ToTokens for ExprIf {
2580 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002581 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002582 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002583 wrap_bare_struct(tokens, &self.cond);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002584 self.then_branch.to_tokens(tokens);
2585 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002586 }
2587 }
2588
Michael Layzell734adb42017-06-07 16:58:31 -04002589 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002590 impl ToTokens for ExprIfLet {
2591 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002592 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002593 self.if_token.to_tokens(tokens);
2594 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002595 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002596 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002597 wrap_bare_struct(tokens, &self.expr);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002598 self.then_branch.to_tokens(tokens);
2599 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002600 }
2601 }
2602
Michael Layzell734adb42017-06-07 16:58:31 -04002603 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002604 impl ToTokens for ExprWhile {
2605 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002606 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002607 if self.label.is_some() {
2608 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002609 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002610 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002611 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002612 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002613 self.body.to_tokens(tokens);
2614 }
2615 }
2616
Michael Layzell734adb42017-06-07 16:58:31 -04002617 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002618 impl ToTokens for ExprWhileLet {
2619 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002620 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002621 if self.label.is_some() {
2622 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002623 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002624 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002625 self.while_token.to_tokens(tokens);
2626 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002627 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002628 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002629 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002630 self.body.to_tokens(tokens);
2631 }
2632 }
2633
Michael Layzell734adb42017-06-07 16:58:31 -04002634 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002635 impl ToTokens for ExprForLoop {
2636 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002637 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002638 if self.label.is_some() {
2639 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002640 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002641 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002642 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002643 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002644 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002645 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002646 self.body.to_tokens(tokens);
2647 }
2648 }
2649
Michael Layzell734adb42017-06-07 16:58:31 -04002650 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002651 impl ToTokens for ExprLoop {
2652 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002653 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002654 if self.label.is_some() {
2655 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002656 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002657 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002658 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002659 self.body.to_tokens(tokens);
2660 }
2661 }
2662
Michael Layzell734adb42017-06-07 16:58:31 -04002663 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002664 impl ToTokens for ExprMatch {
2665 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002666 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002667 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002668 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002669 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002670 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002671 arm.to_tokens(tokens);
2672 // Ensure that we have a comma after a non-block arm, except
2673 // for the last one.
2674 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002675 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002676 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002677 }
2678 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002679 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002680 }
2681 }
2682
Michael Layzell734adb42017-06-07 16:58:31 -04002683 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002684 impl ToTokens for ExprCatch {
2685 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002686 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002687 self.do_token.to_tokens(tokens);
2688 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002689 self.block.to_tokens(tokens);
2690 }
2691 }
2692
Michael Layzell734adb42017-06-07 16:58:31 -04002693 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002694 impl ToTokens for ExprYield {
2695 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002696 tokens.append_all(self.attrs.outer());
Alex Crichtonfe110462017-06-01 12:49:27 -07002697 self.yield_token.to_tokens(tokens);
2698 self.expr.to_tokens(tokens);
2699 }
2700 }
2701
2702 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002703 impl ToTokens for ExprClosure {
2704 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002705 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002706 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002707 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002708 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002709 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002710 FnArg::Captured(ArgCaptured {
2711 ref pat,
2712 ty: Type::Infer(_),
2713 ..
2714 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002715 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002716 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002717 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002718 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002719 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002720 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002721 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002722 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002723 self.body.to_tokens(tokens);
2724 }
2725 }
2726
Michael Layzell734adb42017-06-07 16:58:31 -04002727 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002728 impl ToTokens for ExprUnsafe {
2729 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002730 tokens.append_all(self.attrs.outer());
Nika Layzell640832a2017-12-04 13:37:09 -05002731 self.unsafe_token.to_tokens(tokens);
2732 self.block.to_tokens(tokens);
2733 }
2734 }
2735
2736 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002737 impl ToTokens for ExprBlock {
2738 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002739 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002740 self.block.to_tokens(tokens);
2741 }
2742 }
2743
Michael Layzell734adb42017-06-07 16:58:31 -04002744 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002745 impl ToTokens for ExprAssign {
2746 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002747 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002748 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002749 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002750 self.right.to_tokens(tokens);
2751 }
2752 }
2753
Michael Layzell734adb42017-06-07 16:58:31 -04002754 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002755 impl ToTokens for ExprAssignOp {
2756 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002757 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002758 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002759 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002760 self.right.to_tokens(tokens);
2761 }
2762 }
2763
Michael Layzell734adb42017-06-07 16:58:31 -04002764 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002765 impl ToTokens for ExprField {
2766 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002767 tokens.append_all(self.attrs.outer());
David Tolnay85b69a42017-12-27 20:43:10 -05002768 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002769 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002770 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002771 }
2772 }
2773
Michael Layzell734adb42017-06-07 16:58:31 -04002774 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002775 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002776 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002777 match *self {
2778 Member::Named(ident) => ident.to_tokens(tokens),
2779 Member::Unnamed(ref index) => index.to_tokens(tokens),
2780 }
2781 }
2782 }
2783
2784 #[cfg(feature = "full")]
2785 impl ToTokens for Index {
2786 fn to_tokens(&self, tokens: &mut Tokens) {
2787 tokens.append(TokenTree {
2788 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002789 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002790 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002791 }
2792 }
2793
2794 impl ToTokens for ExprIndex {
2795 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002796 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002797 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002798 self.bracket_token.surround(tokens, |tokens| {
2799 self.index.to_tokens(tokens);
2800 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002801 }
2802 }
2803
Michael Layzell734adb42017-06-07 16:58:31 -04002804 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002805 impl ToTokens for ExprRange {
2806 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002807 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002808 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002809 match self.limits {
2810 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2811 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2812 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002813 self.to.to_tokens(tokens);
2814 }
2815 }
2816
2817 impl ToTokens for ExprPath {
2818 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002819 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002820 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002821 }
2822 }
2823
Michael Layzell734adb42017-06-07 16:58:31 -04002824 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002825 impl ToTokens for ExprAddrOf {
2826 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002827 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002828 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002829 self.mutbl.to_tokens(tokens);
2830 self.expr.to_tokens(tokens);
2831 }
2832 }
2833
Michael Layzell734adb42017-06-07 16:58:31 -04002834 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002835 impl ToTokens for ExprBreak {
2836 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002837 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002838 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002839 self.label.to_tokens(tokens);
2840 self.expr.to_tokens(tokens);
2841 }
2842 }
2843
Michael Layzell734adb42017-06-07 16:58:31 -04002844 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002845 impl ToTokens for ExprContinue {
2846 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002847 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002848 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002849 self.label.to_tokens(tokens);
2850 }
2851 }
2852
Michael Layzell734adb42017-06-07 16:58:31 -04002853 #[cfg(feature = "full")]
David Tolnayc246cd32017-12-28 23:14:32 -05002854 impl ToTokens for ExprReturn {
Alex Crichton62a0a592017-05-22 13:58:53 -07002855 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002856 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002857 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002858 self.expr.to_tokens(tokens);
2859 }
2860 }
2861
Michael Layzell734adb42017-06-07 16:58:31 -04002862 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05002863 impl ToTokens for ExprMacro {
2864 fn to_tokens(&self, tokens: &mut Tokens) {
2865 tokens.append_all(self.attrs.outer());
2866 self.mac.to_tokens(tokens);
2867 }
2868 }
2869
2870 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002871 impl ToTokens for ExprStruct {
2872 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002873 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002874 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002875 self.brace_token.surround(tokens, |tokens| {
2876 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002877 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002878 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002879 self.rest.to_tokens(tokens);
2880 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002881 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002882 }
2883 }
2884
Michael Layzell734adb42017-06-07 16:58:31 -04002885 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002886 impl ToTokens for ExprRepeat {
2887 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002888 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002889 self.bracket_token.surround(tokens, |tokens| {
2890 self.expr.to_tokens(tokens);
2891 self.semi_token.to_tokens(tokens);
2892 self.amt.to_tokens(tokens);
2893 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002894 }
2895 }
2896
David Tolnaye98775f2017-12-28 23:17:00 -05002897 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04002898 impl ToTokens for ExprGroup {
2899 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002900 attrs_to_tokens(&self.attrs, tokens);
Michael Layzell93c36282017-06-04 20:43:14 -04002901 self.group_token.surround(tokens, |tokens| {
2902 self.expr.to_tokens(tokens);
2903 });
2904 }
2905 }
2906
David Tolnaye98775f2017-12-28 23:17:00 -05002907 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002908 impl ToTokens for ExprParen {
2909 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002910 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002911 self.paren_token.surround(tokens, |tokens| {
2912 self.expr.to_tokens(tokens);
2913 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002914 }
2915 }
2916
Michael Layzell734adb42017-06-07 16:58:31 -04002917 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002918 impl ToTokens for ExprTry {
2919 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002920 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002921 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002922 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002923 }
2924 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002925
Michael Layzell734adb42017-06-07 16:58:31 -04002926 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002927 impl ToTokens for FieldValue {
2928 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002929 self.member.to_tokens(tokens);
David Tolnay5d7098a2017-12-29 01:35:24 -05002930 if let Some(ref colon_token) = self.colon_token {
2931 colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002932 self.expr.to_tokens(tokens);
2933 }
David Tolnay055a7042016-10-02 19:23:54 -07002934 }
2935 }
2936
Michael Layzell734adb42017-06-07 16:58:31 -04002937 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002938 impl ToTokens for Arm {
2939 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002940 tokens.append_all(&self.attrs);
2941 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002942 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002943 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002944 self.guard.to_tokens(tokens);
2945 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002946 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002947 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002948 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002949 }
2950 }
2951
Michael Layzell734adb42017-06-07 16:58:31 -04002952 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002953 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002954 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002955 self.underscore_token.to_tokens(tokens);
2956 }
2957 }
2958
Michael Layzell734adb42017-06-07 16:58:31 -04002959 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002960 impl ToTokens for PatIdent {
2961 fn to_tokens(&self, tokens: &mut Tokens) {
2962 self.mode.to_tokens(tokens);
2963 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002964 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002965 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002966 self.subpat.to_tokens(tokens);
2967 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002968 }
2969 }
2970
Michael Layzell734adb42017-06-07 16:58:31 -04002971 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002972 impl ToTokens for PatStruct {
2973 fn to_tokens(&self, tokens: &mut Tokens) {
2974 self.path.to_tokens(tokens);
2975 self.brace_token.surround(tokens, |tokens| {
2976 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002977 // NOTE: We need a comma before the dot2 token if it is present.
2978 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002979 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002980 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002981 self.dot2_token.to_tokens(tokens);
2982 });
2983 }
2984 }
2985
Michael Layzell734adb42017-06-07 16:58:31 -04002986 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002987 impl ToTokens for PatTupleStruct {
2988 fn to_tokens(&self, tokens: &mut Tokens) {
2989 self.path.to_tokens(tokens);
2990 self.pat.to_tokens(tokens);
2991 }
2992 }
2993
Michael Layzell734adb42017-06-07 16:58:31 -04002994 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002995 impl ToTokens for PatPath {
2996 fn to_tokens(&self, tokens: &mut Tokens) {
2997 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
2998 }
2999 }
3000
Michael Layzell734adb42017-06-07 16:58:31 -04003001 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003002 impl ToTokens for PatTuple {
3003 fn to_tokens(&self, tokens: &mut Tokens) {
3004 self.paren_token.surround(tokens, |tokens| {
David Tolnay41871922017-12-29 01:53:45 -05003005 self.front.to_tokens(tokens);
3006 if let Some(ref dot2_token) = self.dot2_token {
3007 if !self.front.empty_or_trailing() {
3008 // Ensure there is a comma before the .. token.
David Tolnayf8db7ba2017-11-11 22:52:16 -08003009 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003010 }
David Tolnay41871922017-12-29 01:53:45 -05003011 dot2_token.to_tokens(tokens);
3012 self.comma_token.to_tokens(tokens);
3013 if self.comma_token.is_none() && !self.back.is_empty() {
3014 // Ensure there is a comma after the .. token.
3015 <Token![,]>::default().to_tokens(tokens);
3016 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07003017 }
David Tolnay41871922017-12-29 01:53:45 -05003018 self.back.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003019 });
3020 }
3021 }
3022
Michael Layzell734adb42017-06-07 16:58:31 -04003023 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003024 impl ToTokens for PatBox {
3025 fn to_tokens(&self, tokens: &mut Tokens) {
3026 self.box_token.to_tokens(tokens);
3027 self.pat.to_tokens(tokens);
3028 }
3029 }
3030
Michael Layzell734adb42017-06-07 16:58:31 -04003031 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003032 impl ToTokens for PatRef {
3033 fn to_tokens(&self, tokens: &mut Tokens) {
3034 self.and_token.to_tokens(tokens);
3035 self.mutbl.to_tokens(tokens);
3036 self.pat.to_tokens(tokens);
3037 }
3038 }
3039
Michael Layzell734adb42017-06-07 16:58:31 -04003040 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003041 impl ToTokens for PatLit {
3042 fn to_tokens(&self, tokens: &mut Tokens) {
3043 self.expr.to_tokens(tokens);
3044 }
3045 }
3046
Michael Layzell734adb42017-06-07 16:58:31 -04003047 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003048 impl ToTokens for PatRange {
3049 fn to_tokens(&self, tokens: &mut Tokens) {
3050 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08003051 match self.limits {
3052 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3053 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
3054 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003055 self.hi.to_tokens(tokens);
3056 }
3057 }
3058
Michael Layzell734adb42017-06-07 16:58:31 -04003059 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003060 impl ToTokens for PatSlice {
3061 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003062 // XXX: This is a mess, and it will be so easy to screw it up. How
3063 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003064 self.bracket_token.surround(tokens, |tokens| {
3065 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003066
3067 // If we need a comma before the middle or standalone .. token,
3068 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05003069 if !self.front.empty_or_trailing()
3070 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04003071 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003072 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003073 }
3074
3075 // If we have an identifier, we always need a .. token.
3076 if self.middle.is_some() {
3077 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003078 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003079 } else if self.dot2_token.is_some() {
3080 self.dot2_token.to_tokens(tokens);
3081 }
3082
3083 // Make sure we have a comma before the back half.
3084 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07003085 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003086 self.back.to_tokens(tokens);
3087 } else {
3088 self.comma_token.to_tokens(tokens);
3089 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003090 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07003091 }
3092 }
3093
Michael Layzell734adb42017-06-07 16:58:31 -04003094 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07003095 impl ToTokens for FieldPat {
3096 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay5d7098a2017-12-29 01:35:24 -05003097 if let Some(ref colon_token) = self.colon_token {
David Tolnay85b69a42017-12-27 20:43:10 -05003098 self.member.to_tokens(tokens);
David Tolnay5d7098a2017-12-29 01:35:24 -05003099 colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003100 }
3101 self.pat.to_tokens(tokens);
3102 }
3103 }
3104
Michael Layzell734adb42017-06-07 16:58:31 -04003105 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07003106 impl ToTokens for BindingMode {
3107 fn to_tokens(&self, tokens: &mut Tokens) {
3108 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003109 BindingMode::ByRef(ref t, ref m) => {
3110 t.to_tokens(tokens);
3111 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003112 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003113 BindingMode::ByValue(ref m) => {
3114 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003115 }
3116 }
3117 }
3118 }
David Tolnay42602292016-10-01 22:25:45 -07003119
Michael Layzell734adb42017-06-07 16:58:31 -04003120 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07003121 impl ToTokens for CaptureBy {
3122 fn to_tokens(&self, tokens: &mut Tokens) {
3123 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003124 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003125 CaptureBy::Ref => {
3126 // nothing
3127 }
David Tolnay89e05672016-10-02 14:39:42 -07003128 }
3129 }
3130 }
3131
Michael Layzell734adb42017-06-07 16:58:31 -04003132 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003133 impl ToTokens for Block {
3134 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003135 self.brace_token.surround(tokens, |tokens| {
3136 tokens.append_all(&self.stmts);
3137 });
David Tolnay42602292016-10-01 22:25:45 -07003138 }
3139 }
3140
Michael Layzell734adb42017-06-07 16:58:31 -04003141 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003142 impl ToTokens for Stmt {
3143 fn to_tokens(&self, tokens: &mut Tokens) {
3144 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07003145 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07003146 Stmt::Item(ref item) => item.to_tokens(tokens),
3147 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003148 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003149 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003150 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003151 }
David Tolnay42602292016-10-01 22:25:45 -07003152 }
3153 }
3154 }
David Tolnay191e0582016-10-02 18:31:09 -07003155
Michael Layzell734adb42017-06-07 16:58:31 -04003156 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003157 impl ToTokens for Local {
3158 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003159 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003160 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003161 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003162 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003163 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003164 self.ty.to_tokens(tokens);
3165 }
3166 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003167 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003168 self.init.to_tokens(tokens);
3169 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003170 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003171 }
3172 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003173}