blob: 17834d42aaec4b89885028f5dd22d7f9d1b362e7 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay2ae520a2017-12-29 11:19:50 -05003use proc_macro2::{Span, TokenStream};
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 Tolnay2ae520a2017-12-29 11:19:50 -05006#[cfg(feature = "extra-traits")]
7use mac::TokenStreamHelper;
8#[cfg(feature = "full")]
9use std::mem;
David Tolnayf4bbbd92016-09-23 14:41:55 -070010
Alex Crichton62a0a592017-05-22 13:58:53 -070011ast_enum_of_structs! {
David Tolnay8c91b882017-12-28 23:04:32 -050012 /// An expression.
13 pub enum Expr {
Alex Crichton62a0a592017-05-22 13:58:53 -070014 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040015 pub Box(ExprBox #full {
David Tolnay8c91b882017-12-28 23:04:32 -050016 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080017 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -050018 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070019 }),
Clar Charrd22b5702017-03-10 15:24:56 -050020
David Tolnay8701a5c2017-12-28 23:31:10 -050021 /// E.g. 'place <- value'.
Michael Layzell734adb42017-06-07 16:58:31 -040022 pub InPlace(ExprInPlace #full {
David Tolnay8c91b882017-12-28 23:04:32 -050023 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070024 pub place: Box<Expr>,
David Tolnay8701a5c2017-12-28 23:31:10 -050025 pub arrow_token: Token![<-],
Alex Crichton62a0a592017-05-22 13:58:53 -070026 pub value: Box<Expr>,
27 }),
Clar Charrd22b5702017-03-10 15:24:56 -050028
Alex Crichton62a0a592017-05-22 13:58:53 -070029 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040030 pub Array(ExprArray #full {
David Tolnay8c91b882017-12-28 23:04:32 -050031 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050032 pub bracket_token: token::Bracket,
David Tolnay2a86fdd2017-12-28 23:34:28 -050033 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070034 }),
Clar Charrd22b5702017-03-10 15:24:56 -050035
Alex Crichton62a0a592017-05-22 13:58:53 -070036 /// A function call.
37 pub Call(ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -050038 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070039 pub func: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -050040 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -050041 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070042 }),
Clar Charrd22b5702017-03-10 15:24:56 -050043
Alex Crichton62a0a592017-05-22 13:58:53 -070044 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
45 ///
46 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080047 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070048 /// (within the angle brackets).
Michael Layzell734adb42017-06-07 16:58:31 -040049 pub MethodCall(ExprMethodCall #full {
David Tolnay8c91b882017-12-28 23:04:32 -050050 pub attrs: Vec<Attribute>,
David Tolnay76418512017-12-28 23:47:47 -050051 pub receiver: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080052 pub dot_token: Token![.],
David Tolnay4a3f59a2017-12-28 21:21:12 -050053 pub method: Ident,
David Tolnayd60cfec2017-12-29 00:21:38 -050054 pub turbofish: Option<MethodTurbofish>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050055 pub paren_token: token::Paren,
56 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070057 }),
Clar Charrd22b5702017-03-10 15:24:56 -050058
Alex Crichton62a0a592017-05-22 13:58:53 -070059 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050060 pub Tuple(ExprTuple #full {
David Tolnay8c91b882017-12-28 23:04:32 -050061 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050062 pub paren_token: token::Paren,
David Tolnay2a86fdd2017-12-28 23:34:28 -050063 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070064 }),
Clar Charrd22b5702017-03-10 15:24:56 -050065
Alex Crichton62a0a592017-05-22 13:58:53 -070066 /// A binary operation, e.g. `a + b`, `a * b`.
67 pub Binary(ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -050068 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070069 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050070 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -070071 pub right: Box<Expr>,
72 }),
Clar Charrd22b5702017-03-10 15:24:56 -050073
Alex Crichton62a0a592017-05-22 13:58:53 -070074 /// A unary operation, e.g. `!x`, `*x`.
75 pub Unary(ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -050076 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070077 pub op: UnOp,
78 pub expr: Box<Expr>,
79 }),
Clar Charrd22b5702017-03-10 15:24:56 -050080
Alex Crichton62a0a592017-05-22 13:58:53 -070081 /// A literal, e.g. `1`, `"foo"`.
David Tolnay8c91b882017-12-28 23:04:32 -050082 pub Lit(ExprLit {
83 pub attrs: Vec<Attribute>,
84 pub lit: Lit,
85 }),
Clar Charrd22b5702017-03-10 15:24:56 -050086
Alex Crichton62a0a592017-05-22 13:58:53 -070087 /// A cast, e.g. `foo as f64`.
88 pub Cast(ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -050089 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070090 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080091 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080092 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070093 }),
Clar Charrd22b5702017-03-10 15:24:56 -050094
Alex Crichton62a0a592017-05-22 13:58:53 -070095 /// A type ascription, e.g. `foo: f64`.
David Tolnay0cf94f22017-12-28 23:46:26 -050096 pub Type(ExprType #full {
David Tolnay8c91b882017-12-28 23:04:32 -050097 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070098 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080099 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800100 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700101 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500102
Alex Crichton62a0a592017-05-22 13:58:53 -0700103 /// An `if` block, with an optional else block
104 ///
105 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400106 pub If(ExprIf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500107 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500108 pub if_token: Token![if],
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 pub cond: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500110 pub then_branch: Block,
111 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500113
Alex Crichton62a0a592017-05-22 13:58:53 -0700114 /// An `if let` expression with an optional else block
115 ///
116 /// E.g., `if let pat = expr { block } else { expr }`
117 ///
118 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400119 pub IfLet(ExprIfLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500120 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800121 pub if_token: Token![if],
122 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500123 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800124 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500125 pub expr: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500126 pub then_branch: Block,
127 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700128 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500129
Alex Crichton62a0a592017-05-22 13:58:53 -0700130 /// A while loop, with an optional label
131 ///
132 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400133 pub While(ExprWhile #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500134 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700135 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800136 pub colon_token: Option<Token![:]>,
137 pub while_token: Token![while],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500138 pub cond: Box<Expr>,
139 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700140 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500141
Alex Crichton62a0a592017-05-22 13:58:53 -0700142 /// A while-let loop, with an optional label.
143 ///
144 /// E.g., `'label: while let pat = expr { block }`
145 ///
146 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400147 pub WhileLet(ExprWhileLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500148 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700149 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800150 pub colon_token: Option<Token![:]>,
151 pub while_token: Token![while],
152 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500153 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800154 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500155 pub expr: Box<Expr>,
156 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700157 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500158
Alex Crichton62a0a592017-05-22 13:58:53 -0700159 /// A for loop, with an optional label.
160 ///
161 /// E.g., `'label: for pat in expr { block }`
162 ///
163 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400164 pub ForLoop(ExprForLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500165 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500166 pub label: Option<Lifetime>,
167 pub colon_token: Option<Token![:]>,
168 pub for_token: Token![for],
Alex Crichton62a0a592017-05-22 13:58:53 -0700169 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500170 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700171 pub expr: Box<Expr>,
172 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700173 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500174
Alex Crichton62a0a592017-05-22 13:58:53 -0700175 /// Conditionless loop with an optional label.
176 ///
177 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400178 pub Loop(ExprLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500179 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700180 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800181 pub colon_token: Option<Token![:]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500182 pub loop_token: Token![loop],
183 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700184 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500185
Alex Crichton62a0a592017-05-22 13:58:53 -0700186 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400187 pub Match(ExprMatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500188 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800189 pub match_token: Token![match],
Alex Crichton62a0a592017-05-22 13:58:53 -0700190 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500191 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 pub arms: Vec<Arm>,
193 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500194
Alex Crichton62a0a592017-05-22 13:58:53 -0700195 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400196 pub Closure(ExprClosure #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500197 pub attrs: Vec<Attribute>,
David Tolnayefc96fb2017-12-29 02:03:15 -0500198 pub capture: Option<Token![move]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800199 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500200 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800201 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500202 pub output: ReturnType,
203 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700204 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500205
Nika Layzell640832a2017-12-04 13:37:09 -0500206 /// An unsafe block (`unsafe { ... }`)
207 pub Unsafe(ExprUnsafe #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500208 pub attrs: Vec<Attribute>,
Nika Layzell640832a2017-12-04 13:37:09 -0500209 pub unsafe_token: Token![unsafe],
210 pub block: Block,
211 }),
212
213 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400214 pub Block(ExprBlock #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500215 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 pub block: Block,
217 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700218
Alex Crichton62a0a592017-05-22 13:58:53 -0700219 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400220 pub Assign(ExprAssign #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500221 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 pub left: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800223 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500224 pub right: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700225 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500226
Alex Crichton62a0a592017-05-22 13:58:53 -0700227 /// An assignment with an operator
228 ///
229 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400230 pub AssignOp(ExprAssignOp #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500231 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700232 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500233 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -0700234 pub right: Box<Expr>,
235 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500236
David Tolnay85b69a42017-12-27 20:43:10 -0500237 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
238 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400239 pub Field(ExprField #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500240 pub attrs: Vec<Attribute>,
David Tolnay85b69a42017-12-27 20:43:10 -0500241 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800242 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500243 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700244 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500245
Alex Crichton62a0a592017-05-22 13:58:53 -0700246 /// An indexing operation (`foo[2]`)
247 pub Index(ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -0500248 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500250 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500251 pub index: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700252 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500253
David Tolnaybe55d7b2017-12-17 23:41:20 -0800254 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400255 pub Range(ExprRange #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500256 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 pub from: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700258 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500259 pub to: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700260 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700261
Alex Crichton62a0a592017-05-22 13:58:53 -0700262 /// Variable reference, possibly containing `::` and/or type
263 /// parameters, e.g. foo::bar::<baz>.
264 ///
265 /// Optionally "qualified",
266 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
267 pub Path(ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -0500268 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700269 pub qself: Option<QSelf>,
270 pub path: Path,
271 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700272
Alex Crichton62a0a592017-05-22 13:58:53 -0700273 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400274 pub AddrOf(ExprAddrOf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500275 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800276 pub and_token: Token![&],
David Tolnay24237fb2017-12-29 02:15:26 -0500277 pub mutability: Option<Token![mut]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700278 pub expr: Box<Expr>,
279 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500280
Alex Crichton62a0a592017-05-22 13:58:53 -0700281 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400282 pub Break(ExprBreak #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500283 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500284 pub break_token: Token![break],
David Tolnay63e3dee2017-06-03 20:13:17 -0700285 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 pub expr: Option<Box<Expr>>,
287 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500288
Alex Crichton62a0a592017-05-22 13:58:53 -0700289 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400290 pub Continue(ExprContinue #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500291 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800292 pub continue_token: Token![continue],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500293 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700294 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500295
Alex Crichton62a0a592017-05-22 13:58:53 -0700296 /// A `return`, with an optional value to be returned
David Tolnayc246cd32017-12-28 23:14:32 -0500297 pub Return(ExprReturn #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500298 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800299 pub return_token: Token![return],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500300 pub expr: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700301 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700302
Alex Crichton62a0a592017-05-22 13:58:53 -0700303 /// A macro invocation; pre-expansion
David Tolnay8c91b882017-12-28 23:04:32 -0500304 pub Macro(ExprMacro #full {
305 pub attrs: Vec<Attribute>,
306 pub mac: Macro,
307 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700308
Alex Crichton62a0a592017-05-22 13:58:53 -0700309 /// A struct literal expression.
310 ///
311 /// For example, `Foo {x: 1, y: 2}`, or
312 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400313 pub Struct(ExprStruct #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500314 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700315 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500316 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500317 pub fields: Delimited<FieldValue, Token![,]>,
318 pub dot2_token: Option<Token![..]>,
319 pub rest: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700320 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700321
Alex Crichton62a0a592017-05-22 13:58:53 -0700322 /// An array literal constructed from one repeated element.
323 ///
324 /// For example, `[1; 5]`. The first expression is the element
325 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400326 pub Repeat(ExprRepeat #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500327 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500328 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700329 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500330 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700331 pub amt: Box<Expr>,
332 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700333
Alex Crichton62a0a592017-05-22 13:58:53 -0700334 /// No-op: used solely so we can pretty-print faithfully
David Tolnaye98775f2017-12-28 23:17:00 -0500335 pub Paren(ExprParen #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500336 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500337 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500338 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700339 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700340
Michael Layzell93c36282017-06-04 20:43:14 -0400341 /// No-op: used solely so we can pretty-print faithfully
342 ///
343 /// A `group` represents a `None`-delimited span in the input
344 /// `TokenStream` which affects the precidence of the resulting
345 /// expression. They are used for macro hygiene.
David Tolnaye98775f2017-12-28 23:17:00 -0500346 pub Group(ExprGroup #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500347 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500348 pub group_token: token::Group,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500349 pub expr: Box<Expr>,
Michael Layzell93c36282017-06-04 20:43:14 -0400350 }),
351
Alex Crichton62a0a592017-05-22 13:58:53 -0700352 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400353 pub Try(ExprTry #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500354 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700355 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800356 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700357 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700358
Alex Crichton62a0a592017-05-22 13:58:53 -0700359 /// A catch expression.
360 ///
361 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400362 pub Catch(ExprCatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500363 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800364 pub do_token: Token![do],
365 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700366 pub block: Block,
367 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700368
369 /// A yield expression.
370 ///
371 /// E.g. `yield expr`
372 pub Yield(ExprYield #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500373 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800374 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700375 pub expr: Option<Box<Expr>>,
376 }),
David Tolnay2ae520a2017-12-29 11:19:50 -0500377
378 pub Verbatim(ExprVerbatim #manual_extra_traits {
379 pub tts: TokenStream,
380 }),
381 }
382}
383
384#[cfg(feature = "extra-traits")]
385impl Eq for ExprVerbatim {}
386
387#[cfg(feature = "extra-traits")]
388impl PartialEq for ExprVerbatim {
389 fn eq(&self, other: &Self) -> bool {
390 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
391 }
392}
393
394#[cfg(feature = "extra-traits")]
395impl Hash for ExprVerbatim {
396 fn hash<H>(&self, state: &mut H)
397 where
398 H: Hasher,
399 {
400 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700401 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700402}
403
David Tolnay8c91b882017-12-28 23:04:32 -0500404impl Expr {
405 // Not public API.
406 #[doc(hidden)]
David Tolnay096d4982017-12-28 23:18:18 -0500407 #[cfg(feature = "full")]
David Tolnay2ae520a2017-12-29 11:19:50 -0500408 pub fn replace_attrs(&mut self, new: Vec<Attribute>) -> Vec<Attribute> {
David Tolnay8c91b882017-12-28 23:04:32 -0500409 match *self {
410 Expr::Box(ExprBox { ref mut attrs, .. }) |
411 Expr::InPlace(ExprInPlace { ref mut attrs, .. }) |
412 Expr::Array(ExprArray { ref mut attrs, .. }) |
413 Expr::Call(ExprCall { ref mut attrs, .. }) |
414 Expr::MethodCall(ExprMethodCall { ref mut attrs, .. }) |
415 Expr::Tuple(ExprTuple { ref mut attrs, .. }) |
416 Expr::Binary(ExprBinary { ref mut attrs, .. }) |
417 Expr::Unary(ExprUnary { ref mut attrs, .. }) |
418 Expr::Lit(ExprLit { ref mut attrs, .. }) |
419 Expr::Cast(ExprCast { ref mut attrs, .. }) |
420 Expr::Type(ExprType { ref mut attrs, .. }) |
421 Expr::If(ExprIf { ref mut attrs, .. }) |
422 Expr::IfLet(ExprIfLet { ref mut attrs, .. }) |
423 Expr::While(ExprWhile { ref mut attrs, .. }) |
424 Expr::WhileLet(ExprWhileLet { ref mut attrs, .. }) |
425 Expr::ForLoop(ExprForLoop { ref mut attrs, .. }) |
426 Expr::Loop(ExprLoop { ref mut attrs, .. }) |
427 Expr::Match(ExprMatch { ref mut attrs, .. }) |
428 Expr::Closure(ExprClosure { ref mut attrs, .. }) |
429 Expr::Unsafe(ExprUnsafe { ref mut attrs, .. }) |
430 Expr::Block(ExprBlock { ref mut attrs, .. }) |
431 Expr::Assign(ExprAssign { ref mut attrs, .. }) |
432 Expr::AssignOp(ExprAssignOp { ref mut attrs, .. }) |
433 Expr::Field(ExprField { ref mut attrs, .. }) |
434 Expr::Index(ExprIndex { ref mut attrs, .. }) |
435 Expr::Range(ExprRange { ref mut attrs, .. }) |
436 Expr::Path(ExprPath { ref mut attrs, .. }) |
437 Expr::AddrOf(ExprAddrOf { ref mut attrs, .. }) |
438 Expr::Break(ExprBreak { ref mut attrs, .. }) |
439 Expr::Continue(ExprContinue { ref mut attrs, .. }) |
David Tolnayc246cd32017-12-28 23:14:32 -0500440 Expr::Return(ExprReturn { ref mut attrs, .. }) |
David Tolnay8c91b882017-12-28 23:04:32 -0500441 Expr::Macro(ExprMacro { ref mut attrs, .. }) |
442 Expr::Struct(ExprStruct { ref mut attrs, .. }) |
443 Expr::Repeat(ExprRepeat { ref mut attrs, .. }) |
444 Expr::Paren(ExprParen { ref mut attrs, .. }) |
445 Expr::Group(ExprGroup { ref mut attrs, .. }) |
446 Expr::Try(ExprTry { ref mut attrs, .. }) |
447 Expr::Catch(ExprCatch { ref mut attrs, .. }) |
David Tolnay2ae520a2017-12-29 11:19:50 -0500448 Expr::Yield(ExprYield { ref mut attrs, .. }) => {
449 mem::replace(attrs, new)
450 }
451 Expr::Verbatim(_) => {
452 // TODO
453 Vec::new()
454 }
David Tolnay8c91b882017-12-28 23:04:32 -0500455 }
456 }
457}
458
David Tolnay85b69a42017-12-27 20:43:10 -0500459ast_enum! {
460 /// A struct or tuple struct field accessed in a struct literal or field
461 /// expression.
462 pub enum Member {
463 /// A named field like `self.x`.
464 Named(Ident),
465 /// An unnamed field like `self.0`.
466 Unnamed(Index),
467 }
468}
469
David Tolnay85b69a42017-12-27 20:43:10 -0500470ast_struct! {
471 /// The index of an unnamed tuple struct field.
472 pub struct Index #manual_extra_traits {
473 pub index: u32,
474 pub span: Span,
475 }
476}
477
David Tolnay14982012017-12-29 00:49:51 -0500478impl From<usize> for Index {
479 fn from(index: usize) -> Index {
480 assert!(index < std::u32::MAX as usize);
481 Index {
482 index: index as u32,
483 span: Span::default(),
484 }
485 }
486}
487
488#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500489impl Eq for Index {}
490
David Tolnay14982012017-12-29 00:49:51 -0500491#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500492impl PartialEq for Index {
493 fn eq(&self, other: &Self) -> bool {
494 self.index == other.index
495 }
496}
497
David Tolnay14982012017-12-29 00:49:51 -0500498#[cfg(feature = "extra-traits")]
David Tolnay85b69a42017-12-27 20:43:10 -0500499impl Hash for Index {
500 fn hash<H: Hasher>(&self, state: &mut H) {
501 self.index.hash(state);
502 }
503}
504
505#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700506ast_struct! {
David Tolnayd60cfec2017-12-29 00:21:38 -0500507 pub struct MethodTurbofish {
508 pub colon2_token: Token![::],
509 pub lt_token: Token![<],
510 pub args: Delimited<GenericMethodArgument, Token![,]>,
511 pub gt_token: Token![>],
512 }
513}
514
515#[cfg(feature = "full")]
516ast_enum! {
517 /// A individual generic argument like `T`.
518 pub enum GenericMethodArgument {
519 /// The type parameters for this path segment, if present.
520 Type(Type),
521 /// Const expression. Must be inside of a block.
522 ///
523 /// NOTE: Identity expressions are represented as Type arguments, as
524 /// they are indistinguishable syntactically.
525 Const(Expr),
526 }
527}
528
529#[cfg(feature = "full")]
530ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700531 /// A field-value pair in a struct literal.
532 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500533 /// Attributes tagged on the field.
534 pub attrs: Vec<Attribute>,
535
536 /// Name or index of the field.
537 pub member: Member,
538
David Tolnay5d7098a2017-12-29 01:35:24 -0500539 /// The colon in `Struct { x: x }`. If written in shorthand like
540 /// `Struct { x }`, there is no colon.
David Tolnay85b69a42017-12-27 20:43:10 -0500541 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500542
Alex Crichton62a0a592017-05-22 13:58:53 -0700543 /// Value of the field.
544 pub expr: Expr,
Alex Crichton62a0a592017-05-22 13:58:53 -0700545 }
David Tolnay055a7042016-10-02 19:23:54 -0700546}
547
Michael Layzell734adb42017-06-07 16:58:31 -0400548#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700549ast_struct! {
550 /// A Block (`{ .. }`).
551 ///
552 /// E.g. `{ .. }` as in `fn foo() { .. }`
553 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500554 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700555 /// Statements in a block
556 pub stmts: Vec<Stmt>,
557 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700558}
559
Michael Layzell734adb42017-06-07 16:58:31 -0400560#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700561ast_enum! {
562 /// A statement, usually ending in a semicolon.
563 pub enum Stmt {
564 /// A local (let) binding.
565 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700566
Alex Crichton62a0a592017-05-22 13:58:53 -0700567 /// An item definition.
568 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700569
Alex Crichton62a0a592017-05-22 13:58:53 -0700570 /// Expr without trailing semicolon.
571 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700572
Alex Crichton62a0a592017-05-22 13:58:53 -0700573 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800574 Semi(Box<Expr>, Token![;]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700575 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700576}
577
Michael Layzell734adb42017-06-07 16:58:31 -0400578#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700579ast_struct! {
580 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
581 pub struct Local {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500582 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800583 pub let_token: Token![let],
Alex Crichton62a0a592017-05-22 13:58:53 -0700584 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500585 pub colon_token: Option<Token![:]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800586 pub ty: Option<Box<Type>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500587 pub eq_token: Option<Token![=]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700588 /// Initializer expression to set the value, if any
589 pub init: Option<Box<Expr>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500590 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700591 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700592}
593
Michael Layzell734adb42017-06-07 16:58:31 -0400594#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700595ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700596 // Clippy false positive
597 // https://github.com/Manishearth/rust-clippy/issues/1241
598 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
599 pub enum Pat {
600 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700601 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800602 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700603 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700604
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
606 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
607 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
608 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700609 pub Ident(PatIdent {
David Tolnay24237fb2017-12-29 02:15:26 -0500610 pub by_ref: Option<Token![ref]>,
611 pub mutability: Option<Token![mut]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700612 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800613 pub at_token: Option<Token![@]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500614 pub subpat: Option<Box<Pat>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700615 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700616
Alex Crichton62a0a592017-05-22 13:58:53 -0700617 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
618 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700619 pub Struct(PatStruct {
620 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500621 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500622 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800623 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700624 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700625
Alex Crichton62a0a592017-05-22 13:58:53 -0700626 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
627 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
628 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700629 pub TupleStruct(PatTupleStruct {
630 pub path: Path,
631 pub pat: PatTuple,
632 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700633
Alex Crichton62a0a592017-05-22 13:58:53 -0700634 /// A possibly qualified path pattern.
635 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
636 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
637 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700638 pub Path(PatPath {
639 pub qself: Option<QSelf>,
640 pub path: Path,
641 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700642
Alex Crichton62a0a592017-05-22 13:58:53 -0700643 /// A tuple pattern `(a, b)`.
644 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
645 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700646 pub Tuple(PatTuple {
David Tolnay32954ef2017-12-26 22:43:16 -0500647 pub paren_token: token::Paren,
David Tolnay41871922017-12-29 01:53:45 -0500648 pub front: Delimited<Pat, Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500649 pub dot2_token: Option<Token![..]>,
David Tolnay41871922017-12-29 01:53:45 -0500650 pub comma_token: Option<Token![,]>,
651 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700652 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700653 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700654 pub Box(PatBox {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800655 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500656 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700657 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700658 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700659 pub Ref(PatRef {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800660 pub and_token: Token![&],
David Tolnay24237fb2017-12-29 02:15:26 -0500661 pub mutability: Option<Token![mut]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500662 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700663 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700664 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700665 pub Lit(PatLit {
666 pub expr: Box<Expr>,
667 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800668 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700669 pub Range(PatRange {
670 pub lo: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700671 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500672 pub hi: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700673 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400674 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700675 pub Slice(PatSlice {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500676 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800677 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700678 pub middle: Option<Box<Pat>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500679 pub dot2_token: Option<Token![..]>,
David Tolnay41871922017-12-29 01:53:45 -0500680 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500681 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700682 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700683 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800684 pub Macro(Macro),
David Tolnay2ae520a2017-12-29 11:19:50 -0500685 pub Verbatim(PatVerbatim #manual_extra_traits {
686 pub tts: TokenStream,
687 }),
688 }
689}
690
691#[cfg(feature = "extra-traits")]
692impl Eq for PatVerbatim {}
693
694#[cfg(feature = "extra-traits")]
695impl PartialEq for PatVerbatim {
696 fn eq(&self, other: &Self) -> bool {
697 TokenStreamHelper(&self.tts) == TokenStreamHelper(&other.tts)
698 }
699}
700
701#[cfg(feature = "extra-traits")]
702impl Hash for PatVerbatim {
703 fn hash<H>(&self, state: &mut H)
704 where
705 H: Hasher,
706 {
707 TokenStreamHelper(&self.tts).hash(state);
Alex Crichton62a0a592017-05-22 13:58:53 -0700708 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700709}
710
Michael Layzell734adb42017-06-07 16:58:31 -0400711#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700712ast_struct! {
713 /// An arm of a 'match'.
714 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800715 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700716 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500717 /// ```rust
718 /// # #![feature(dotdoteq_in_patterns)]
719 /// #
720 /// # fn main() {
721 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700722 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500723 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700724 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500725 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700726 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500727 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700728 /// ```
729 pub struct Arm {
730 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800731 pub pats: Delimited<Pat, Token![|]>,
732 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700733 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800734 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700735 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800736 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700737 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700738}
739
Michael Layzell734adb42017-06-07 16:58:31 -0400740#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700741ast_enum! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700742 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700743 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700744 pub enum RangeLimits {
745 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800746 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700747 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800748 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700749 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700750}
751
Michael Layzell734adb42017-06-07 16:58:31 -0400752#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700753ast_struct! {
754 /// A single field in a struct pattern
755 ///
756 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
David Tolnay5d7098a2017-12-29 01:35:24 -0500757 /// are treated the same as `x: x, y: ref y, z: ref mut z` but
758 /// there is no colon token.
Alex Crichton62a0a592017-05-22 13:58:53 -0700759 pub struct FieldPat {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500760 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700761 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500762 pub member: Member,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500763 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700764 /// The pattern the field is destructured to
765 pub pat: Box<Pat>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700766 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700767}
768
Michael Layzell3936ceb2017-07-08 00:28:36 -0400769#[cfg(any(feature = "parsing", feature = "printing"))]
770#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700771fn arm_expr_requires_comma(expr: &Expr) -> bool {
772 // see https://github.com/rust-lang/rust/blob/eb8f2586e
773 // /src/libsyntax/parse/classify.rs#L17-L37
David Tolnay8c91b882017-12-28 23:04:32 -0500774 match *expr {
775 Expr::Unsafe(..)
776 | Expr::Block(..)
777 | Expr::If(..)
778 | Expr::IfLet(..)
779 | Expr::Match(..)
780 | Expr::While(..)
781 | Expr::WhileLet(..)
782 | Expr::Loop(..)
783 | Expr::ForLoop(..)
784 | Expr::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700785 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400786 }
787}
788
David Tolnayb9c8e322016-09-23 20:48:37 -0700789#[cfg(feature = "parsing")]
790pub mod parsing {
791 use super::*;
David Tolnay2ccf32a2017-12-29 00:34:26 -0500792 use ty::parsing::qpath;
793 #[cfg(feature = "full")]
794 use ty::parsing::ty_no_eq_after;
David Tolnayb9c8e322016-09-23 20:48:37 -0700795
Michael Layzell734adb42017-06-07 16:58:31 -0400796 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500797 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500798 use synom::Synom;
799 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400800 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500801 use parse_error;
David Tolnay203557a2017-12-27 23:59:33 -0500802 use synom::PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700803
David Tolnaybcf26022017-12-25 22:10:52 -0500804 // When we're parsing expressions which occur before blocks, like in an if
805 // statement's condition, we cannot parse a struct literal.
806 //
807 // Struct literals are ambiguous in certain positions
808 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700809 macro_rules! ambiguous_expr {
810 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700811 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700812 };
813 }
814
David Tolnaybcf26022017-12-25 22:10:52 -0500815 // When we are parsing an optional suffix expression, we cannot allow blocks
816 // if structs are not allowed.
817 //
818 // Example:
819 //
820 // if break {} {}
821 //
822 // is ambiguous between:
823 //
824 // if (break {}) {}
825 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400826 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400827 macro_rules! opt_ambiguous_expr {
828 ($i:expr, $allow_struct:ident) => {
829 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
830 };
831 }
832
Alex Crichton954046c2017-05-30 21:49:42 -0700833 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400834 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700835
836 fn description() -> Option<&'static str> {
837 Some("expression")
838 }
839 }
840
Michael Layzell734adb42017-06-07 16:58:31 -0400841 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700842 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
843
David Tolnaybcf26022017-12-25 22:10:52 -0500844 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400845 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500846 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500847 call!(i, assign_expr, allow_struct, allow_block)
Michael Layzellb78f3b52017-06-04 19:03:03 -0400848 }
849
Michael Layzell734adb42017-06-07 16:58:31 -0400850 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500851 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500852 // NOTE: We intentionally skip assign_expr, placement_expr, and
853 // range_expr, as they are not parsed in non-full mode.
854 call!(i, or_expr, allow_struct, allow_block)
Michael Layzell734adb42017-06-07 16:58:31 -0400855 }
856
David Tolnaybcf26022017-12-25 22:10:52 -0500857 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400858 macro_rules! binop {
859 (
860 $name: ident,
861 $next: ident,
862 $submac: ident!( $($args:tt)* )
863 ) => {
David Tolnay8c91b882017-12-28 23:04:32 -0500864 named!($name(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400865 mut e: call!($next, allow_struct, allow_block) >>
866 many0!(do_parse!(
867 op: $submac!($($args)*) >>
868 rhs: call!($next, allow_struct, true) >>
869 ({
870 e = ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -0500871 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400872 left: Box::new(e.into()),
873 op: op,
874 right: Box::new(rhs.into()),
875 }.into();
876 })
877 )) >>
878 (e)
879 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700880 }
David Tolnay54e854d2016-10-24 12:03:30 -0700881 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700882
David Tolnaybcf26022017-12-25 22:10:52 -0500883 // <placement> = <placement> ..
884 // <placement> += <placement> ..
885 // <placement> -= <placement> ..
886 // <placement> *= <placement> ..
887 // <placement> /= <placement> ..
888 // <placement> %= <placement> ..
889 // <placement> ^= <placement> ..
890 // <placement> &= <placement> ..
891 // <placement> |= <placement> ..
892 // <placement> <<= <placement> ..
893 // <placement> >>= <placement> ..
894 //
895 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400896 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500897 named!(assign_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400898 mut e: call!(placement_expr, allow_struct, allow_block) >>
899 alt!(
900 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800901 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902 // Recurse into self to parse right-associative operator.
903 rhs: call!(assign_expr, allow_struct, true) >>
904 ({
905 e = ExprAssign {
David Tolnay8c91b882017-12-28 23:04:32 -0500906 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400907 left: Box::new(e.into()),
908 eq_token: eq,
909 right: Box::new(rhs.into()),
910 }.into();
911 })
912 )
913 |
914 do_parse!(
915 op: call!(BinOp::parse_assign_op) >>
916 // Recurse into self to parse right-associative operator.
917 rhs: call!(assign_expr, allow_struct, true) >>
918 ({
919 e = ExprAssignOp {
David Tolnay8c91b882017-12-28 23:04:32 -0500920 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400921 left: Box::new(e.into()),
922 op: op,
923 right: Box::new(rhs.into()),
924 }.into();
925 })
926 )
927 |
928 epsilon!()
929 ) >>
930 (e)
931 ));
932
David Tolnaybcf26022017-12-25 22:10:52 -0500933 // <range> <- <range> ..
934 //
935 // NOTE: The `in place { expr }` version of this syntax is parsed in
936 // `atom_expr`, not here.
937 //
938 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400939 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500940 named!(placement_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400941 mut e: call!(range_expr, allow_struct, allow_block) >>
942 alt!(
943 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800944 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400945 // Recurse into self to parse right-associative operator.
946 rhs: call!(placement_expr, allow_struct, true) >>
947 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400948 e = ExprInPlace {
David Tolnay8c91b882017-12-28 23:04:32 -0500949 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400950 // op: BinOp::Place(larrow),
951 place: Box::new(e.into()),
David Tolnay8701a5c2017-12-28 23:31:10 -0500952 arrow_token: arrow,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400953 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400954 }.into();
955 })
956 )
957 |
958 epsilon!()
959 ) >>
960 (e)
961 ));
962
David Tolnaybcf26022017-12-25 22:10:52 -0500963 // <or> ... <or> ..
964 // <or> .. <or> ..
965 // <or> ..
966 //
967 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
968 // rules are for parsing these expressions are, but this is not correct.
969 // For example, `a .. b .. c` is not a legal expression. It should not
970 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
971 //
972 // NOTE: The form of ranges which don't include a preceding expression are
973 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400974 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500975 named!(range_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400976 mut e: call!(or_expr, allow_struct, allow_block) >>
977 many0!(do_parse!(
978 limits: syn!(RangeLimits) >>
979 // We don't want to allow blocks here if we don't allow structs. See
980 // the reasoning for `opt_ambiguous_expr!` above.
981 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
982 ({
983 e = ExprRange {
David Tolnay8c91b882017-12-28 23:04:32 -0500984 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400985 from: Some(Box::new(e.into())),
986 limits: limits,
987 to: hi.map(|e| Box::new(e.into())),
988 }.into();
989 })
990 )) >>
991 (e)
992 ));
993
David Tolnaybcf26022017-12-25 22:10:52 -0500994 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800995 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400996
David Tolnaybcf26022017-12-25 22:10:52 -0500997 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800998 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400999
David Tolnaybcf26022017-12-25 22:10:52 -05001000 // <bitor> == <bitor> ...
1001 // <bitor> != <bitor> ...
1002 // <bitor> >= <bitor> ...
1003 // <bitor> <= <bitor> ...
1004 // <bitor> > <bitor> ...
1005 // <bitor> < <bitor> ...
1006 //
1007 // NOTE: This operator appears to be parsed as left-associative, but errors
1008 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -05001009 binop!(
1010 compare_expr,
1011 bitor_expr,
1012 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001013 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001014 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001015 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001016 |
1017 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -08001018 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001019 |
1020 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -08001021 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001022 |
Michael Layzell6a5a1642017-06-04 19:35:15 -04001023 do_parse!(
1024 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -08001025 not!(punct!(<-)) >>
1026 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -04001027 (BinOp::Lt(t))
1028 )
Michael Layzellb78f3b52017-06-04 19:03:03 -04001029 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001030 punct!(>) => { BinOp::Gt }
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 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -05001035 binop!(
1036 bitor_expr,
1037 bitxor_expr,
1038 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
1039 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001040
David Tolnaybcf26022017-12-25 22:10:52 -05001041 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -05001042 binop!(
1043 bitxor_expr,
1044 bitand_expr,
1045 do_parse!(
1046 // NOTE: Make sure we aren't looking at ^=.
1047 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
1048 )
1049 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001050
David Tolnaybcf26022017-12-25 22:10:52 -05001051 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -05001052 binop!(
1053 bitand_expr,
1054 shift_expr,
1055 do_parse!(
1056 // NOTE: Make sure we aren't looking at && or &=.
1057 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
1058 )
1059 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001060
David Tolnaybcf26022017-12-25 22:10:52 -05001061 // <arith> << <arith> ...
1062 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -05001063 binop!(
1064 shift_expr,
1065 arith_expr,
1066 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001067 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001068 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001069 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -05001070 )
1071 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001072
David Tolnaybcf26022017-12-25 22:10:52 -05001073 // <term> + <term> ...
1074 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -05001075 binop!(
1076 arith_expr,
1077 term_expr,
1078 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001079 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001080 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001081 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -05001082 )
1083 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001084
David Tolnaybcf26022017-12-25 22:10:52 -05001085 // <cast> * <cast> ...
1086 // <cast> / <cast> ...
1087 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -05001088 binop!(
1089 term_expr,
1090 cast_expr,
1091 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001092 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001093 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001094 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001095 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001096 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -05001097 )
1098 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001099
David Tolnaybcf26022017-12-25 22:10:52 -05001100 // <unary> as <ty>
1101 // <unary> : <ty>
David Tolnay0cf94f22017-12-28 23:46:26 -05001102 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001103 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001104 mut e: call!(unary_expr, allow_struct, allow_block) >>
1105 many0!(alt!(
1106 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001107 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001108 // We can't accept `A + B` in cast expressions, as it's
1109 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001110 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001111 ({
1112 e = ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -05001113 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001114 expr: Box::new(e.into()),
1115 as_token: as_,
1116 ty: Box::new(ty),
1117 }.into();
1118 })
1119 )
1120 |
1121 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001122 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001123 // We can't accept `A + B` in cast expressions, as it's
1124 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001125 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001126 ({
1127 e = ExprType {
David Tolnay8c91b882017-12-28 23:04:32 -05001128 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001129 expr: Box::new(e.into()),
1130 colon_token: colon,
1131 ty: Box::new(ty),
1132 }.into();
1133 })
1134 )
1135 )) >>
1136 (e)
1137 ));
1138
David Tolnay0cf94f22017-12-28 23:46:26 -05001139 // <unary> as <ty>
1140 #[cfg(not(feature = "full"))]
1141 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
1142 mut e: call!(unary_expr, allow_struct, allow_block) >>
1143 many0!(do_parse!(
1144 as_: keyword!(as) >>
1145 // We can't accept `A + B` in cast expressions, as it's
1146 // ambiguous with the + expression.
1147 ty: call!(Type::without_plus) >>
1148 ({
1149 e = ExprCast {
1150 attrs: Vec::new(),
1151 expr: Box::new(e.into()),
1152 as_token: as_,
1153 ty: Box::new(ty),
1154 }.into();
1155 })
1156 )) >>
1157 (e)
1158 ));
1159
David Tolnaybcf26022017-12-25 22:10:52 -05001160 // <UnOp> <trailer>
1161 // & <trailer>
1162 // &mut <trailer>
1163 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001164 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001165 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001166 do_parse!(
1167 op: syn!(UnOp) >>
1168 expr: call!(unary_expr, allow_struct, true) >>
1169 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001170 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001171 op: op,
1172 expr: Box::new(expr.into()),
1173 }.into())
1174 )
1175 |
1176 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001177 and: punct!(&) >>
David Tolnay24237fb2017-12-29 02:15:26 -05001178 mutability: option!(keyword!(mut)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001179 expr: call!(unary_expr, allow_struct, true) >>
1180 (ExprAddrOf {
David Tolnay8c91b882017-12-28 23:04:32 -05001181 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001182 and_token: and,
David Tolnay24237fb2017-12-29 02:15:26 -05001183 mutability: mutability,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001184 expr: Box::new(expr.into()),
1185 }.into())
1186 )
1187 |
1188 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001189 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001190 expr: call!(unary_expr, allow_struct, true) >>
1191 (ExprBox {
David Tolnay8c91b882017-12-28 23:04:32 -05001192 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001193 box_token: box_,
1194 expr: Box::new(expr.into()),
1195 }.into())
1196 )
1197 |
1198 call!(trailer_expr, allow_struct, allow_block)
1199 ));
1200
Michael Layzell734adb42017-06-07 16:58:31 -04001201 // XXX: This duplication is ugly
1202 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001203 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzell734adb42017-06-07 16:58:31 -04001204 do_parse!(
1205 op: syn!(UnOp) >>
1206 expr: call!(unary_expr, allow_struct, true) >>
1207 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001208 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001209 op: op,
1210 expr: Box::new(expr.into()),
1211 }.into())
1212 )
1213 |
1214 call!(trailer_expr, allow_struct, allow_block)
1215 ));
1216
David Tolnaybcf26022017-12-25 22:10:52 -05001217 // <atom> (..<args>) ...
1218 // <atom> . <ident> (..<args>) ...
1219 // <atom> . <ident> ...
1220 // <atom> . <lit> ...
1221 // <atom> [ <expr> ] ...
1222 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001223 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001224 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001225 mut e: call!(atom_expr, allow_struct, allow_block) >>
1226 many0!(alt!(
1227 tap!(args: and_call => {
1228 let (args, paren) = args;
1229 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001230 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001231 func: Box::new(e.into()),
1232 args: args,
1233 paren_token: paren,
1234 }.into();
1235 })
1236 |
1237 tap!(more: and_method_call => {
1238 let mut call = more;
David Tolnay76418512017-12-28 23:47:47 -05001239 call.receiver = Box::new(e.into());
Michael Layzellb78f3b52017-06-04 19:03:03 -04001240 e = call.into();
1241 })
1242 |
1243 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001244 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001245 e = ExprField {
David Tolnay8c91b882017-12-28 23:04:32 -05001246 attrs: Vec::new(),
David Tolnay85b69a42017-12-27 20:43:10 -05001247 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001248 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001249 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001250 }.into();
1251 })
1252 |
1253 tap!(i: and_index => {
1254 let (i, token) = i;
1255 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001256 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001257 expr: Box::new(e.into()),
1258 bracket_token: token,
1259 index: Box::new(i),
1260 }.into();
1261 })
1262 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001263 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001264 e = ExprTry {
David Tolnay8c91b882017-12-28 23:04:32 -05001265 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001266 expr: Box::new(e.into()),
1267 question_token: question,
1268 }.into();
1269 })
1270 )) >>
1271 (e)
1272 ));
1273
Michael Layzell734adb42017-06-07 16:58:31 -04001274 // XXX: Duplication == ugly
1275 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001276 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzell734adb42017-06-07 16:58:31 -04001277 mut e: call!(atom_expr, allow_struct, allow_block) >>
1278 many0!(alt!(
1279 tap!(args: and_call => {
1280 let (args, paren) = args;
1281 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001282 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001283 func: Box::new(e.into()),
1284 args: args,
1285 paren_token: paren,
1286 }.into();
1287 })
1288 |
1289 tap!(i: and_index => {
1290 let (i, token) = i;
1291 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001292 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001293 expr: Box::new(e.into()),
1294 bracket_token: token,
1295 index: Box::new(i),
1296 }.into();
1297 })
1298 )) >>
1299 (e)
1300 ));
1301
David Tolnaybcf26022017-12-25 22:10:52 -05001302 // Parse all atomic expressions which don't have to worry about precidence
1303 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001304 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001305 named!(atom_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
1306 syn!(ExprGroup) => { Expr::Group } // must be placed first
Michael Layzell93c36282017-06-04 20:43:14 -04001307 |
David Tolnay8c91b882017-12-28 23:04:32 -05001308 syn!(ExprLit) => { Expr::Lit } // must be before expr_struct
Michael Layzellb78f3b52017-06-04 19:03:03 -04001309 |
1310 // must be before expr_path
David Tolnay8c91b882017-12-28 23:04:32 -05001311 cond_reduce!(allow_struct, map!(syn!(ExprStruct), Expr::Struct))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001312 |
David Tolnay8c91b882017-12-28 23:04:32 -05001313 syn!(ExprParen) => { Expr::Paren } // must be before expr_tup
Michael Layzellb78f3b52017-06-04 19:03:03 -04001314 |
David Tolnay8c91b882017-12-28 23:04:32 -05001315 syn!(ExprMacro) => { Expr::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001316 |
1317 call!(expr_break, allow_struct) // must be before expr_path
1318 |
David Tolnay8c91b882017-12-28 23:04:32 -05001319 syn!(ExprContinue) => { Expr::Continue } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001320 |
1321 call!(expr_ret, allow_struct) // must be before expr_path
1322 |
David Tolnay8c91b882017-12-28 23:04:32 -05001323 syn!(ExprArray) => { Expr::Array }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001324 |
David Tolnay8c91b882017-12-28 23:04:32 -05001325 syn!(ExprTuple) => { Expr::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001326 |
David Tolnay8c91b882017-12-28 23:04:32 -05001327 syn!(ExprIf) => { Expr::If }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001328 |
David Tolnay8c91b882017-12-28 23:04:32 -05001329 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001330 |
David Tolnay8c91b882017-12-28 23:04:32 -05001331 syn!(ExprWhile) => { Expr::While }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001332 |
David Tolnay8c91b882017-12-28 23:04:32 -05001333 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001334 |
David Tolnay8c91b882017-12-28 23:04:32 -05001335 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001336 |
David Tolnay8c91b882017-12-28 23:04:32 -05001337 syn!(ExprLoop) => { Expr::Loop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001338 |
David Tolnay8c91b882017-12-28 23:04:32 -05001339 syn!(ExprMatch) => { Expr::Match }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001340 |
David Tolnay8c91b882017-12-28 23:04:32 -05001341 syn!(ExprCatch) => { Expr::Catch }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001342 |
David Tolnay8c91b882017-12-28 23:04:32 -05001343 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001344 |
David Tolnay8c91b882017-12-28 23:04:32 -05001345 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001346 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001347 call!(expr_closure, allow_struct)
1348 |
David Tolnay8c91b882017-12-28 23:04:32 -05001349 cond_reduce!(allow_block, map!(syn!(ExprBlock), Expr::Block))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001350 |
1351 // NOTE: This is the prefix-form of range
1352 call!(expr_range, allow_struct)
1353 |
David Tolnay8c91b882017-12-28 23:04:32 -05001354 syn!(ExprPath) => { Expr::Path }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001355 |
David Tolnay8c91b882017-12-28 23:04:32 -05001356 syn!(ExprRepeat) => { Expr::Repeat }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001357 ));
1358
Michael Layzell734adb42017-06-07 16:58:31 -04001359 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001360 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> Expr, alt!(
David Tolnaye98775f2017-12-28 23:17:00 -05001361 syn!(ExprLit) => { Expr::Lit }
Michael Layzell734adb42017-06-07 16:58:31 -04001362 |
David Tolnay8c91b882017-12-28 23:04:32 -05001363 syn!(ExprPath) => { Expr::Path }
Michael Layzell734adb42017-06-07 16:58:31 -04001364 ));
1365
Michael Layzell734adb42017-06-07 16:58:31 -04001366 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001367 named!(expr_nosemi -> Expr, map!(alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001368 syn!(ExprIf) => { Expr::If }
Michael Layzell35418782017-06-07 09:20:25 -04001369 |
David Tolnay8c91b882017-12-28 23:04:32 -05001370 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzell35418782017-06-07 09:20:25 -04001371 |
David Tolnay8c91b882017-12-28 23:04:32 -05001372 syn!(ExprWhile) => { Expr::While }
Michael Layzell35418782017-06-07 09:20:25 -04001373 |
David Tolnay8c91b882017-12-28 23:04:32 -05001374 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzell35418782017-06-07 09:20:25 -04001375 |
David Tolnay8c91b882017-12-28 23:04:32 -05001376 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzell35418782017-06-07 09:20:25 -04001377 |
David Tolnay8c91b882017-12-28 23:04:32 -05001378 syn!(ExprLoop) => { Expr::Loop }
Michael Layzell35418782017-06-07 09:20:25 -04001379 |
David Tolnay8c91b882017-12-28 23:04:32 -05001380 syn!(ExprMatch) => { Expr::Match }
Michael Layzell35418782017-06-07 09:20:25 -04001381 |
David Tolnay8c91b882017-12-28 23:04:32 -05001382 syn!(ExprCatch) => { Expr::Catch }
Michael Layzell35418782017-06-07 09:20:25 -04001383 |
David Tolnay8c91b882017-12-28 23:04:32 -05001384 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001385 |
David Tolnay8c91b882017-12-28 23:04:32 -05001386 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001387 |
David Tolnay8c91b882017-12-28 23:04:32 -05001388 syn!(ExprBlock) => { Expr::Block }
Michael Layzell35418782017-06-07 09:20:25 -04001389 ), Expr::from));
1390
David Tolnay8c91b882017-12-28 23:04:32 -05001391 impl Synom for ExprLit {
1392 named!(parse -> Self, do_parse!(
1393 lit: syn!(Lit) >>
1394 (ExprLit {
1395 attrs: Vec::new(),
1396 lit: lit,
1397 })
1398 ));
1399 }
1400
1401 #[cfg(feature = "full")]
1402 impl Synom for ExprMacro {
1403 named!(parse -> Self, do_parse!(
1404 mac: syn!(Macro) >>
1405 (ExprMacro {
1406 attrs: Vec::new(),
1407 mac: mac,
1408 })
1409 ));
1410 }
1411
David Tolnaye98775f2017-12-28 23:17:00 -05001412 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04001413 impl Synom for ExprGroup {
1414 named!(parse -> Self, do_parse!(
1415 e: grouped!(syn!(Expr)) >>
1416 (ExprGroup {
David Tolnay8c91b882017-12-28 23:04:32 -05001417 attrs: Vec::new(),
Michael Layzell93c36282017-06-04 20:43:14 -04001418 expr: Box::new(e.0),
1419 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001420 })
Michael Layzell93c36282017-06-04 20:43:14 -04001421 ));
1422 }
1423
David Tolnaye98775f2017-12-28 23:17:00 -05001424 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001425 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001426 named!(parse -> Self, do_parse!(
1427 e: parens!(syn!(Expr)) >>
1428 (ExprParen {
David Tolnay8c91b882017-12-28 23:04:32 -05001429 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001430 expr: Box::new(e.0),
1431 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001432 })
Michael Layzell92639a52017-06-01 00:07:44 -04001433 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001434 }
David Tolnay89e05672016-10-02 14:39:42 -07001435
Michael Layzell734adb42017-06-07 16:58:31 -04001436 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001437 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001438 named!(parse -> Self, do_parse!(
1439 elems: brackets!(call!(Delimited::parse_terminated)) >>
1440 (ExprArray {
David Tolnay8c91b882017-12-28 23:04:32 -05001441 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001442 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001443 bracket_token: elems.1,
1444 })
1445 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001446 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001447
David Tolnay32954ef2017-12-26 22:43:16 -05001448 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001449 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001450
Michael Layzell734adb42017-06-07 16:58:31 -04001451 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001452 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001453 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001454 method: syn!(Ident) >>
David Tolnayd60cfec2017-12-29 00:21:38 -05001455 turbofish: option!(tuple!(
1456 punct!(::),
1457 punct!(<),
1458 call!(Delimited::parse_terminated),
1459 punct!(>)
David Tolnayfa0edf22016-09-23 22:58:24 -07001460 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001461 args: parens!(call!(Delimited::parse_terminated)) >>
1462 ({
Alex Crichton954046c2017-05-30 21:49:42 -07001463 ExprMethodCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001464 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001465 // this expr will get overwritten after being returned
David Tolnay76418512017-12-28 23:47:47 -05001466 receiver: Box::new(Expr::Lit(ExprLit {
David Tolnay8c91b882017-12-28 23:04:32 -05001467 attrs: Vec::new(),
1468 lit: Lit {
1469 span: Span::default(),
1470 value: LitKind::Bool(false),
1471 },
Alex Crichton954046c2017-05-30 21:49:42 -07001472 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001473
Alex Crichton954046c2017-05-30 21:49:42 -07001474 method: method,
David Tolnayd60cfec2017-12-29 00:21:38 -05001475 turbofish: turbofish.map(|fish| MethodTurbofish {
1476 colon2_token: fish.0,
1477 lt_token: fish.1,
1478 args: fish.2,
1479 gt_token: fish.3,
1480 }),
Alex Crichton954046c2017-05-30 21:49:42 -07001481 args: args.0,
1482 paren_token: args.1,
1483 dot_token: dot,
Alex Crichton954046c2017-05-30 21:49:42 -07001484 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001485 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001486 ));
1487
Michael Layzell734adb42017-06-07 16:58:31 -04001488 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05001489 impl Synom for GenericMethodArgument {
1490 // TODO parse const generics as well
1491 named!(parse -> Self, map!(ty_no_eq_after, GenericMethodArgument::Type));
1492 }
1493
1494 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001495 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001496 named!(parse -> Self, do_parse!(
1497 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001498 (ExprTuple {
David Tolnay8c91b882017-12-28 23:04:32 -05001499 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001500 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001501 paren_token: elems.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001502 })
1503 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001504 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001505
Michael Layzell734adb42017-06-07 16:58:31 -04001506 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001507 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001508 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001509 if_: keyword!(if) >>
1510 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001511 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001512 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001513 cond: expr_no_struct >>
1514 then_block: braces!(call!(Block::parse_within)) >>
1515 else_block: option!(else_block) >>
1516 (ExprIfLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001517 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001518 pat: Box::new(pat),
1519 let_token: let_,
1520 eq_token: eq,
1521 expr: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001522 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001523 stmts: then_block.0,
1524 brace_token: then_block.1,
1525 },
1526 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001527 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001528 })
1529 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001530 }
1531
Michael Layzell734adb42017-06-07 16:58:31 -04001532 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001533 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001534 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001535 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001536 cond: expr_no_struct >>
1537 then_block: braces!(call!(Block::parse_within)) >>
1538 else_block: option!(else_block) >>
1539 (ExprIf {
David Tolnay8c91b882017-12-28 23:04:32 -05001540 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001541 cond: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001542 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001543 stmts: then_block.0,
1544 brace_token: then_block.1,
1545 },
1546 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001547 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001548 })
1549 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001550 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001551
Michael Layzell734adb42017-06-07 16:58:31 -04001552 #[cfg(feature = "full")]
David Tolnay2ccf32a2017-12-29 00:34:26 -05001553 named!(else_block -> (Token![else], Box<Expr>), do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001554 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001555 expr: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001556 syn!(ExprIf) => { Expr::If }
Alex Crichton954046c2017-05-30 21:49:42 -07001557 |
David Tolnay8c91b882017-12-28 23:04:32 -05001558 syn!(ExprIfLet) => { Expr::IfLet }
Alex Crichton954046c2017-05-30 21:49:42 -07001559 |
1560 do_parse!(
1561 else_block: braces!(call!(Block::parse_within)) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001562 (Expr::Block(ExprBlock {
1563 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001564 block: Block {
1565 stmts: else_block.0,
1566 brace_token: else_block.1,
1567 },
1568 }))
David Tolnay939766a2016-09-23 23:48:12 -07001569 )
Alex Crichton954046c2017-05-30 21:49:42 -07001570 ) >>
David Tolnay2ccf32a2017-12-29 00:34:26 -05001571 (else_, Box::new(expr))
David Tolnay939766a2016-09-23 23:48:12 -07001572 ));
1573
Michael Layzell734adb42017-06-07 16:58:31 -04001574 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001575 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001576 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001577 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1578 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001579 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001580 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001581 expr: expr_no_struct >>
1582 loop_block: syn!(Block) >>
1583 (ExprForLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001584 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001585 for_token: for_,
1586 in_token: in_,
1587 pat: Box::new(pat),
1588 expr: Box::new(expr),
1589 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001590 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001591 label: lbl.map(|p| p.0),
1592 })
1593 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001594 }
Gregory Katze5f35682016-09-27 14:20:55 -04001595
Michael Layzell734adb42017-06-07 16:58:31 -04001596 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001597 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001598 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001599 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1600 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001601 loop_block: syn!(Block) >>
1602 (ExprLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001603 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001604 loop_token: loop_,
1605 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001606 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001607 label: lbl.map(|p| p.0),
1608 })
1609 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001610 }
1611
Michael Layzell734adb42017-06-07 16:58:31 -04001612 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001613 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001614 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001615 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001616 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001617 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001618 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001619 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001620 ExprMatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001621 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001622 expr: Box::new(obj),
1623 match_token: match_,
1624 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001625 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001626 }
1627 })
1628 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001629 }
David Tolnay1978c672016-10-27 22:05:52 -07001630
Michael Layzell734adb42017-06-07 16:58:31 -04001631 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001632 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001633 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001634 do_: keyword!(do) >>
1635 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001636 catch_block: syn!(Block) >>
1637 (ExprCatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001638 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001639 block: catch_block,
1640 do_token: do_,
1641 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001642 })
Michael Layzell92639a52017-06-01 00:07:44 -04001643 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001644 }
Arnavion02ef13f2017-04-25 00:54:31 -07001645
Michael Layzell734adb42017-06-07 16:58:31 -04001646 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001647 impl Synom for ExprYield {
1648 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001649 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001650 expr: option!(syn!(Expr)) >>
1651 (ExprYield {
David Tolnay8c91b882017-12-28 23:04:32 -05001652 attrs: Vec::new(),
Alex Crichtonfe110462017-06-01 12:49:27 -07001653 yield_token: yield_,
1654 expr: expr.map(Box::new),
1655 })
1656 ));
1657 }
1658
1659 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001660 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001661 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001662 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001663 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001664 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1665 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001666 body: do_parse!(
1667 expr: alt!(expr_nosemi | syn!(Expr)) >>
1668 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1669 map!(input_end!(), |_| None)
1670 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001671 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001672 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001673 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001674 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001675 ) >>
1676 (Arm {
1677 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001678 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001679 attrs: attrs,
1680 pats: pats,
1681 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001682 body: Box::new(body.0),
1683 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001684 })
1685 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001686 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001687
Michael Layzell734adb42017-06-07 16:58:31 -04001688 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001689 named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
David Tolnayefc96fb2017-12-29 02:03:15 -05001690 capture: option!(keyword!(move)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001691 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001692 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001693 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001694 ret_and_body: alt!(
1695 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001696 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001697 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001698 body: syn!(Block) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -05001699 (ReturnType::Type(arrow, Box::new(ty)),
David Tolnay8c91b882017-12-28 23:04:32 -05001700 Expr::Block(ExprBlock {
1701 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001702 block: body,
1703 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001704 )
1705 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001706 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001707 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001708 (ExprClosure {
David Tolnay8c91b882017-12-28 23:04:32 -05001709 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001710 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001711 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001712 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001713 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001714 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001715 body: Box::new(ret_and_body.1),
1716 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001717 ));
1718
Michael Layzell734adb42017-06-07 16:58:31 -04001719 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001720 named!(fn_arg -> FnArg, do_parse!(
1721 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001722 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001723 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001724 if let Some((colon, ty)) = ty {
1725 FnArg::Captured(ArgCaptured {
1726 pat: pat,
1727 colon_token: colon,
1728 ty: ty,
1729 })
1730 } else {
1731 FnArg::Inferred(pat)
1732 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001733 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001734 ));
1735
Michael Layzell734adb42017-06-07 16:58:31 -04001736 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001737 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001738 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001739 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1740 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001741 cond: expr_no_struct >>
1742 while_block: syn!(Block) >>
1743 (ExprWhile {
David Tolnay8c91b882017-12-28 23:04:32 -05001744 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001745 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001746 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001747 cond: Box::new(cond),
1748 body: while_block,
1749 label: lbl.map(|p| p.0),
1750 })
1751 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001752 }
1753
Michael Layzell734adb42017-06-07 16:58:31 -04001754 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001755 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001756 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001757 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1758 while_: keyword!(while) >>
1759 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001760 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001761 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001762 value: expr_no_struct >>
1763 while_block: syn!(Block) >>
1764 (ExprWhileLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001765 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001766 eq_token: eq,
1767 let_token: let_,
1768 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001769 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001770 pat: Box::new(pat),
1771 expr: Box::new(value),
1772 body: while_block,
1773 label: lbl.map(|p| p.0),
1774 })
1775 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001776 }
1777
Michael Layzell734adb42017-06-07 16:58:31 -04001778 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001779 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001780 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001781 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001782 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001783 (ExprContinue {
David Tolnay8c91b882017-12-28 23:04:32 -05001784 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001785 continue_token: cont,
1786 label: lbl,
1787 })
1788 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001789 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001790
Michael Layzell734adb42017-06-07 16:58:31 -04001791 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001792 named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001793 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001794 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001795 // We can't allow blocks after a `break` expression when we wouldn't
1796 // allow structs, as this expression is ambiguous.
1797 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001798 (ExprBreak {
David Tolnay8c91b882017-12-28 23:04:32 -05001799 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001800 label: lbl,
1801 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001802 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001803 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001804 ));
1805
Michael Layzell734adb42017-06-07 16:58:31 -04001806 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001807 named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001808 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001809 // NOTE: return is greedy and eats blocks after it even when in a
1810 // position where structs are not allowed, such as in if statement
1811 // conditions. For example:
1812 //
David Tolnaybcf26022017-12-25 22:10:52 -05001813 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001814 ret_value: option!(ambiguous_expr!(allow_struct)) >>
David Tolnayc246cd32017-12-28 23:14:32 -05001815 (ExprReturn {
David Tolnay8c91b882017-12-28 23:04:32 -05001816 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001817 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001818 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001819 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001820 ));
1821
Michael Layzell734adb42017-06-07 16:58:31 -04001822 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001823 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001824 named!(parse -> Self, do_parse!(
1825 path: syn!(Path) >>
1826 data: braces!(do_parse!(
1827 fields: call!(Delimited::parse_terminated) >>
1828 base: option!(
1829 cond!(fields.is_empty() || fields.trailing_delim(),
1830 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001831 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001832 base: syn!(Expr) >>
1833 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001834 )
Michael Layzell92639a52017-06-01 00:07:44 -04001835 )
1836 ) >>
1837 (fields, base)
1838 )) >>
1839 ({
1840 let ((fields, base), brace) = data;
1841 let (dots, rest) = match base.and_then(|b| b) {
1842 Some((dots, base)) => (Some(dots), Some(base)),
1843 None => (None, None),
1844 };
1845 ExprStruct {
David Tolnay8c91b882017-12-28 23:04:32 -05001846 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001847 brace_token: brace,
1848 path: path,
1849 fields: fields,
1850 dot2_token: dots,
1851 rest: rest.map(Box::new),
1852 }
1853 })
1854 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001855 }
1856
Michael Layzell734adb42017-06-07 16:58:31 -04001857 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001858 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001859 named!(parse -> Self, alt!(
1860 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001861 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001862 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001863 value: syn!(Expr) >>
1864 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001865 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001866 expr: value,
Alex Crichton954046c2017-05-30 21:49:42 -07001867 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001868 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001869 })
Michael Layzell92639a52017-06-01 00:07:44 -04001870 )
1871 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001872 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001873 member: Member::Named(name),
David Tolnay8c91b882017-12-28 23:04:32 -05001874 expr: Expr::Path(ExprPath {
1875 attrs: Vec::new(),
1876 qself: None,
1877 path: name.into(),
1878 }).into(),
Michael Layzell92639a52017-06-01 00:07:44 -04001879 attrs: Vec::new(),
1880 colon_token: None,
1881 })
1882 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001883 }
David Tolnay055a7042016-10-02 19:23:54 -07001884
Michael Layzell734adb42017-06-07 16:58:31 -04001885 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001886 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001887 named!(parse -> Self, do_parse!(
1888 data: brackets!(do_parse!(
1889 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001890 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001891 times: syn!(Expr) >>
1892 (value, semi, times)
1893 )) >>
1894 (ExprRepeat {
David Tolnay8c91b882017-12-28 23:04:32 -05001895 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001896 expr: Box::new((data.0).0),
1897 amt: Box::new((data.0).2),
1898 bracket_token: data.1,
1899 semi_token: (data.0).1,
1900 })
1901 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001902 }
David Tolnay055a7042016-10-02 19:23:54 -07001903
Michael Layzell734adb42017-06-07 16:58:31 -04001904 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001905 impl Synom for ExprUnsafe {
1906 named!(parse -> Self, do_parse!(
1907 unsafe_: keyword!(unsafe) >>
1908 b: syn!(Block) >>
1909 (ExprUnsafe {
David Tolnay8c91b882017-12-28 23:04:32 -05001910 attrs: Vec::new(),
Nika Layzell640832a2017-12-04 13:37:09 -05001911 unsafe_token: unsafe_,
1912 block: b,
1913 })
1914 ));
1915 }
1916
1917 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001918 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001919 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001920 b: syn!(Block) >>
1921 (ExprBlock {
David Tolnay8c91b882017-12-28 23:04:32 -05001922 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001923 block: b,
1924 })
1925 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001926 }
David Tolnay89e05672016-10-02 14:39:42 -07001927
Michael Layzell734adb42017-06-07 16:58:31 -04001928 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001929 named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001930 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001931 hi: opt_ambiguous_expr!(allow_struct) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001932 (ExprRange {
1933 attrs: Vec::new(),
1934 from: None,
1935 to: hi.map(Box::new),
1936 limits: limits,
1937 }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001938 ));
1939
Michael Layzell734adb42017-06-07 16:58:31 -04001940 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001941 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001942 named!(parse -> Self, alt!(
1943 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001944 punct!(..=) => { RangeLimits::Closed }
1945 |
1946 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001947 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001948 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001949 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001950 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001951 }
David Tolnay438c9052016-10-07 23:24:48 -07001952
Alex Crichton954046c2017-05-30 21:49:42 -07001953 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001954 named!(parse -> Self, do_parse!(
1955 pair: qpath >>
1956 (ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -05001957 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001958 qself: pair.0,
1959 path: pair.1,
1960 })
1961 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001962 }
David Tolnay42602292016-10-01 22:25:45 -07001963
Michael Layzell734adb42017-06-07 16:58:31 -04001964 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001965 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001966
David Tolnay32954ef2017-12-26 22:43:16 -05001967 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001968
Michael Layzell734adb42017-06-07 16:58:31 -04001969 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001970 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001971 named!(parse -> Self, do_parse!(
1972 stmts: braces!(call!(Block::parse_within)) >>
1973 (Block {
1974 stmts: stmts.0,
1975 brace_token: stmts.1,
1976 })
1977 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001978 }
David Tolnay939766a2016-09-23 23:48:12 -07001979
Michael Layzell734adb42017-06-07 16:58:31 -04001980 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001981 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001982 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001983 many0!(punct!(;)) >>
1984 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001985 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001986 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001987 mut e: syn!(Expr) >>
1988 ({
David Tolnay2ae520a2017-12-29 11:19:50 -05001989 e.replace_attrs(attrs);
Alex Crichton70bbd592017-08-27 10:40:03 -07001990 Stmt::Expr(Box::new(e))
1991 })
1992 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001993 (match last {
1994 None => standalone,
1995 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001996 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001997 standalone
1998 }
1999 })
2000 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002001 }
2002
Michael Layzell734adb42017-06-07 16:58:31 -04002003 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002004 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04002005 named!(parse -> Self, alt!(
2006 stmt_mac
2007 |
2008 stmt_local
2009 |
2010 stmt_item
2011 |
Michael Layzell35418782017-06-07 09:20:25 -04002012 stmt_blockexpr
2013 |
Michael Layzell92639a52017-06-01 00:07:44 -04002014 stmt_expr
2015 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002016 }
David Tolnay939766a2016-09-23 23:48:12 -07002017
Michael Layzell734adb42017-06-07 16:58:31 -04002018 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002019 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002020 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002021 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002022 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07002023 // Only parse braces here; paren and bracket will get parsed as
2024 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07002025 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002026 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05002027 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
2028 attrs: attrs,
2029 ident: None,
2030 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05002031 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07002032 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05002033 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05002034 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07002035 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05002036 },
David Tolnayeea28d62016-10-25 20:44:08 -07002037 },
David Tolnay57b52bc2017-12-28 18:06:38 -05002038 semi_token: semi,
2039 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07002040 ));
2041
Michael Layzell734adb42017-06-07 16:58:31 -04002042 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002043 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002044 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002045 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002046 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002047 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002048 init: option!(tuple!(punct!(=), syn!(Expr))) >>
2049 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07002050 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07002051 let_token: let_,
2052 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002053 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
2054 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07002055 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002056 ty: ty.map(|p| Box::new(p.1)),
2057 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07002058 attrs: attrs,
2059 })))
2060 ));
2061
Michael Layzell734adb42017-06-07 16:58:31 -04002062 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002063 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07002064
Michael Layzell734adb42017-06-07 16:58:31 -04002065 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04002066 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002067 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04002068 mut e: expr_nosemi >>
2069 // If the next token is a `.` or a `?` it is special-cased to parse as
2070 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08002071 not!(punct!(.)) >>
2072 not!(punct!(?)) >>
2073 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04002074 ({
David Tolnay2ae520a2017-12-29 11:19:50 -05002075 e.replace_attrs(attrs);
Michael Layzell35418782017-06-07 09:20:25 -04002076 if let Some(semi) = semi {
2077 Stmt::Semi(Box::new(e), semi)
2078 } else {
2079 Stmt::Expr(Box::new(e))
2080 }
2081 })
2082 ));
David Tolnaycfe55022016-10-02 22:02:27 -07002083
Michael Layzell734adb42017-06-07 16:58:31 -04002084 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07002085 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002086 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002087 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002088 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07002089 ({
David Tolnay2ae520a2017-12-29 11:19:50 -05002090 e.replace_attrs(attrs);
Michael Layzell35418782017-06-07 09:20:25 -04002091 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07002092 })
David Tolnay939766a2016-09-23 23:48:12 -07002093 ));
David Tolnay8b07f372016-09-30 10:28:40 -07002094
Michael Layzell734adb42017-06-07 16:58:31 -04002095 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002096 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04002097 named!(parse -> Self, alt!(
2098 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
2099 |
2100 syn!(PatBox) => { Pat::Box } // must be before pat_ident
2101 |
2102 syn!(PatRange) => { Pat::Range } // must be before pat_lit
2103 |
2104 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
2105 |
2106 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
2107 |
David Tolnaydecf28d2017-11-11 11:56:45 -08002108 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04002109 |
2110 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
2111 |
2112 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
2113 |
2114 syn!(PatPath) => { Pat::Path }
2115 |
2116 syn!(PatTuple) => { Pat::Tuple }
2117 |
2118 syn!(PatRef) => { Pat::Ref }
2119 |
2120 syn!(PatSlice) => { Pat::Slice }
2121 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002122 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002123
Michael Layzell734adb42017-06-07 16:58:31 -04002124 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002125 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04002126 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002127 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04002128 |u| PatWild { underscore_token: u }
2129 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002130 }
David Tolnay84aa0752016-10-02 23:01:13 -07002131
Michael Layzell734adb42017-06-07 16:58:31 -04002132 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002133 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04002134 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002135 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002136 pat: syn!(Pat) >>
2137 (PatBox {
2138 pat: Box::new(pat),
2139 box_token: boxed,
2140 })
2141 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002142 }
2143
Michael Layzell734adb42017-06-07 16:58:31 -04002144 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002145 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04002146 named!(parse -> Self, do_parse!(
David Tolnay24237fb2017-12-29 02:15:26 -05002147 by_ref: option!(keyword!(ref)) >>
2148 mutability: option!(keyword!(mut)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002149 name: alt!(
2150 syn!(Ident)
2151 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08002152 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04002153 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002154 not!(punct!(<)) >>
2155 not!(punct!(::)) >>
2156 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002157 (PatIdent {
David Tolnay24237fb2017-12-29 02:15:26 -05002158 by_ref: by_ref,
David Tolnayefc96fb2017-12-29 02:03:15 -05002159 mutability: mutability,
Michael Layzell92639a52017-06-01 00:07:44 -04002160 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002161 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002162 subpat: subpat.map(|p| Box::new(p.1)),
2163 })
2164 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002165 }
2166
Michael Layzell734adb42017-06-07 16:58:31 -04002167 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002168 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002169 named!(parse -> Self, do_parse!(
2170 path: syn!(Path) >>
2171 tuple: syn!(PatTuple) >>
2172 (PatTupleStruct {
2173 path: path,
2174 pat: tuple,
2175 })
2176 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002177 }
2178
Michael Layzell734adb42017-06-07 16:58:31 -04002179 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002180 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002181 named!(parse -> Self, do_parse!(
2182 path: syn!(Path) >>
2183 data: braces!(do_parse!(
2184 fields: call!(Delimited::parse_terminated) >>
2185 base: option!(
2186 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002187 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002188 ) >>
2189 (fields, base)
2190 )) >>
2191 (PatStruct {
2192 path: path,
2193 fields: (data.0).0,
2194 brace_token: data.1,
2195 dot2_token: (data.0).1.and_then(|m| m),
2196 })
2197 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002198 }
2199
Michael Layzell734adb42017-06-07 16:58:31 -04002200 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002201 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002202 named!(parse -> Self, alt!(
2203 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002204 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002205 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002206 pat: syn!(Pat) >>
2207 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002208 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002209 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002210 attrs: Vec::new(),
2211 colon_token: Some(colon),
2212 })
2213 )
2214 |
2215 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002216 boxed: option!(keyword!(box)) >>
David Tolnay24237fb2017-12-29 02:15:26 -05002217 by_ref: option!(keyword!(ref)) >>
2218 mutability: option!(keyword!(mut)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002219 ident: syn!(Ident) >>
2220 ({
2221 let mut pat: Pat = PatIdent {
David Tolnay24237fb2017-12-29 02:15:26 -05002222 by_ref: by_ref,
David Tolnayefc96fb2017-12-29 02:03:15 -05002223 mutability: mutability,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002224 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002225 subpat: None,
2226 at_token: None,
2227 }.into();
2228 if let Some(boxed) = boxed {
2229 pat = PatBox {
2230 pat: Box::new(pat),
2231 box_token: boxed,
2232 }.into();
2233 }
2234 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002235 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002236 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002237 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002238 colon_token: None,
2239 }
2240 })
2241 )
2242 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002243 }
2244
Michael Layzell734adb42017-06-07 16:58:31 -04002245 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002246 impl Synom for Member {
2247 named!(parse -> Self, alt!(
2248 syn!(Ident) => { Member::Named }
2249 |
2250 syn!(Index) => { Member::Unnamed }
2251 ));
2252 }
2253
2254 #[cfg(feature = "full")]
2255 impl Synom for Index {
2256 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002257 lit: syn!(Lit) >>
2258 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002259 if let Ok(i) = lit.value.to_string().parse() {
2260 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002261 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002262 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002263 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002264 })
David Tolnay85b69a42017-12-27 20:43:10 -05002265 ));
2266 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002267
Michael Layzell734adb42017-06-07 16:58:31 -04002268 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002269 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002270 named!(parse -> Self, map!(
2271 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002272 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002273 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002274 }
David Tolnay9636c052016-10-02 17:11:17 -07002275
Michael Layzell734adb42017-06-07 16:58:31 -04002276 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002277 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002278 named!(parse -> Self, do_parse!(
2279 data: parens!(do_parse!(
David Tolnay41871922017-12-29 01:53:45 -05002280 front: call!(Delimited::parse_terminated) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002281 dotdot: map!(cond!(
David Tolnay41871922017-12-29 01:53:45 -05002282 front.is_empty() || front.trailing_delim(),
Michael Layzell92639a52017-06-01 00:07:44 -04002283 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002284 dots: punct!(..) >>
2285 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002286 (dots, trailing)
2287 ))
David Tolnay41871922017-12-29 01:53:45 -05002288 ), Option::unwrap_or_default) >>
2289 back: cond!(match dotdot {
Michael Layzell92639a52017-06-01 00:07:44 -04002290 Some((_, Some(_))) => true,
2291 _ => false,
2292 },
2293 call!(Delimited::parse_terminated)) >>
David Tolnay41871922017-12-29 01:53:45 -05002294 (front, dotdot, back)
Michael Layzell92639a52017-06-01 00:07:44 -04002295 )) >>
2296 ({
David Tolnay41871922017-12-29 01:53:45 -05002297 let ((front, dotdot, back), parens) = data;
Michael Layzell92639a52017-06-01 00:07:44 -04002298 let (dotdot, trailing) = match dotdot {
2299 Some((a, b)) => (Some(a), Some(b)),
2300 None => (None, None),
2301 };
2302 PatTuple {
2303 paren_token: parens,
David Tolnay41871922017-12-29 01:53:45 -05002304 front: front,
Michael Layzell92639a52017-06-01 00:07:44 -04002305 dot2_token: dotdot,
David Tolnay41871922017-12-29 01:53:45 -05002306 comma_token: trailing.unwrap_or_default(),
2307 back: back.unwrap_or_default(),
Michael Layzell92639a52017-06-01 00:07:44 -04002308 }
2309 })
2310 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002311 }
David Tolnayfbb73232016-10-03 01:00:06 -07002312
Michael Layzell734adb42017-06-07 16:58:31 -04002313 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002314 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002315 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002316 and: punct!(&) >>
David Tolnay24237fb2017-12-29 02:15:26 -05002317 mutability: option!(keyword!(mut)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002318 pat: syn!(Pat) >>
2319 (PatRef {
2320 pat: Box::new(pat),
David Tolnay24237fb2017-12-29 02:15:26 -05002321 mutability: mutability,
Michael Layzell92639a52017-06-01 00:07:44 -04002322 and_token: and,
2323 })
2324 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002325 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002326
Michael Layzell734adb42017-06-07 16:58:31 -04002327 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002328 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002329 named!(parse -> Self, do_parse!(
2330 lit: pat_lit_expr >>
David Tolnay8c91b882017-12-28 23:04:32 -05002331 (if let Expr::Path(_) = lit {
Michael Layzell92639a52017-06-01 00:07:44 -04002332 return parse_error(); // these need to be parsed by pat_path
2333 } else {
2334 PatLit {
2335 expr: Box::new(lit),
2336 }
2337 })
2338 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002339 }
David Tolnaye1310902016-10-29 23:40:00 -07002340
Michael Layzell734adb42017-06-07 16:58:31 -04002341 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002342 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002343 named!(parse -> Self, do_parse!(
2344 lo: pat_lit_expr >>
2345 limits: syn!(RangeLimits) >>
2346 hi: pat_lit_expr >>
2347 (PatRange {
2348 lo: Box::new(lo),
2349 hi: Box::new(hi),
2350 limits: limits,
2351 })
2352 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002353 }
David Tolnaye1310902016-10-29 23:40:00 -07002354
Michael Layzell734adb42017-06-07 16:58:31 -04002355 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002356 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002357 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002358 v: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05002359 syn!(ExprLit) => { Expr::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002360 |
David Tolnay8c91b882017-12-28 23:04:32 -05002361 syn!(ExprPath) => { Expr::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002362 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002363 (if let Some(neg) = neg {
David Tolnay8c91b882017-12-28 23:04:32 -05002364 Expr::Unary(ExprUnary {
2365 attrs: Vec::new(),
David Tolnayc29b9892017-12-27 22:58:14 -05002366 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002367 expr: Box::new(v.into())
2368 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002369 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002370 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002371 })
2372 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002373
Michael Layzell734adb42017-06-07 16:58:31 -04002374 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002375 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002376 named!(parse -> Self, map!(
2377 brackets!(do_parse!(
2378 before: call!(Delimited::parse_terminated) >>
2379 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002380 dots: punct!(..) >>
2381 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002382 (dots, trailing)
2383 )) >>
2384 after: cond!(
2385 match middle {
2386 Some((_, ref trailing)) => trailing.is_some(),
2387 _ => false,
2388 },
2389 call!(Delimited::parse_terminated)
2390 ) >>
2391 (before, middle, after)
2392 )),
2393 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002394 let mut before: Delimited<Pat, Token![,]> = before;
2395 let after: Option<Delimited<Pat, Token![,]>> = after;
2396 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002397 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002398 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002399 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002400 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002401 }),
2402 bracket_token: brackets,
2403 middle: middle.and_then(|_| {
2404 if !before.is_empty() && !before.trailing_delim() {
2405 Some(Box::new(before.pop().unwrap().into_item()))
2406 } else {
2407 None
2408 }
2409 }),
2410 front: before,
2411 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002412 }
Alex Crichton954046c2017-05-30 21:49:42 -07002413 }
Michael Layzell92639a52017-06-01 00:07:44 -04002414 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002415 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002416}
2417
David Tolnayf4bbbd92016-09-23 14:41:55 -07002418#[cfg(feature = "printing")]
2419mod printing {
2420 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002421 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002422 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002423 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002424 #[cfg(feature = "full")]
2425 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002426
David Tolnaybcf26022017-12-25 22:10:52 -05002427 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2428 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002429 #[cfg(feature = "full")]
2430 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
David Tolnay8c91b882017-12-28 23:04:32 -05002431 if let Expr::Struct(_) = *e {
David Tolnay32954ef2017-12-26 22:43:16 -05002432 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002433 e.to_tokens(tokens);
2434 });
2435 } else {
2436 e.to_tokens(tokens);
2437 }
2438 }
2439
David Tolnay8c91b882017-12-28 23:04:32 -05002440 #[cfg(feature = "full")]
2441 fn attrs_to_tokens(attrs: &[Attribute], tokens: &mut Tokens) {
2442 tokens.append_all(attrs.outer());
2443 }
Michael Layzell734adb42017-06-07 16:58:31 -04002444
David Tolnay8c91b882017-12-28 23:04:32 -05002445 #[cfg(not(feature = "full"))]
2446 fn attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002447 }
2448
Michael Layzell734adb42017-06-07 16:58:31 -04002449 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002450 impl ToTokens for ExprBox {
2451 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002452 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002453 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002454 self.expr.to_tokens(tokens);
2455 }
2456 }
2457
Michael Layzell734adb42017-06-07 16:58:31 -04002458 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002459 impl ToTokens for ExprInPlace {
2460 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002461 tokens.append_all(self.attrs.outer());
David Tolnay8701a5c2017-12-28 23:31:10 -05002462 self.place.to_tokens(tokens);
2463 self.arrow_token.to_tokens(tokens);
2464 self.value.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002465 }
2466 }
2467
Michael Layzell734adb42017-06-07 16:58:31 -04002468 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 impl ToTokens for ExprArray {
2470 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002471 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002472 self.bracket_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002473 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002474 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002475 }
2476 }
2477
2478 impl ToTokens for ExprCall {
2479 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002480 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002481 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002482 self.paren_token.surround(tokens, |tokens| {
2483 self.args.to_tokens(tokens);
2484 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002485 }
2486 }
2487
Michael Layzell734adb42017-06-07 16:58:31 -04002488 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002489 impl ToTokens for ExprMethodCall {
2490 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002491 tokens.append_all(self.attrs.outer());
David Tolnay76418512017-12-28 23:47:47 -05002492 self.receiver.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002493 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002494 self.method.to_tokens(tokens);
David Tolnayd60cfec2017-12-29 00:21:38 -05002495 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002496 self.paren_token.surround(tokens, |tokens| {
2497 self.args.to_tokens(tokens);
2498 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002499 }
2500 }
2501
Michael Layzell734adb42017-06-07 16:58:31 -04002502 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05002503 impl ToTokens for MethodTurbofish {
2504 fn to_tokens(&self, tokens: &mut Tokens) {
2505 self.colon2_token.to_tokens(tokens);
2506 self.lt_token.to_tokens(tokens);
2507 self.args.to_tokens(tokens);
2508 self.gt_token.to_tokens(tokens);
2509 }
2510 }
2511
2512 #[cfg(feature = "full")]
2513 impl ToTokens for GenericMethodArgument {
2514 fn to_tokens(&self, tokens: &mut Tokens) {
2515 match *self {
2516 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
2517 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
2518 }
2519 }
2520 }
2521
2522 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002523 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002524 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002525 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002526 self.paren_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002527 self.elems.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002528 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002529 // distinguish ExprTuple from ExprParen.
David Tolnay2a86fdd2017-12-28 23:34:28 -05002530 if self.elems.len() == 1 && !self.elems.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002531 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002532 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002533 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002534 }
2535 }
2536
2537 impl ToTokens for ExprBinary {
2538 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002539 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002540 self.left.to_tokens(tokens);
2541 self.op.to_tokens(tokens);
2542 self.right.to_tokens(tokens);
2543 }
2544 }
2545
2546 impl ToTokens for ExprUnary {
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.op.to_tokens(tokens);
2550 self.expr.to_tokens(tokens);
2551 }
2552 }
2553
David Tolnay8c91b882017-12-28 23:04:32 -05002554 impl ToTokens for ExprLit {
2555 fn to_tokens(&self, tokens: &mut Tokens) {
2556 attrs_to_tokens(&self.attrs, tokens);
2557 self.lit.to_tokens(tokens);
2558 }
2559 }
2560
Alex Crichton62a0a592017-05-22 13:58:53 -07002561 impl ToTokens for ExprCast {
2562 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002563 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002564 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002565 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002566 self.ty.to_tokens(tokens);
2567 }
2568 }
2569
David Tolnay0cf94f22017-12-28 23:46:26 -05002570 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002571 impl ToTokens for ExprType {
2572 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002573 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002574 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002575 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002576 self.ty.to_tokens(tokens);
2577 }
2578 }
2579
Michael Layzell734adb42017-06-07 16:58:31 -04002580 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002581 fn maybe_wrap_else(
2582 tokens: &mut Tokens,
David Tolnay2ccf32a2017-12-29 00:34:26 -05002583 else_: &Option<(Token![else], Box<Expr>)>,
David Tolnay51382052017-12-27 13:46:21 -05002584 ) {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002585 if let Some((ref else_token, ref else_)) = *else_ {
2586 else_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002587
2588 // If we are not one of the valid expressions to exist in an else
2589 // clause, wrap ourselves in a block.
David Tolnay2ccf32a2017-12-29 00:34:26 -05002590 match **else_ {
David Tolnay8c91b882017-12-28 23:04:32 -05002591 Expr::If(_) | Expr::IfLet(_) | Expr::Block(_) => {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002592 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002593 }
2594 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002595 token::Brace::default().surround(tokens, |tokens| {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002596 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002597 });
2598 }
2599 }
2600 }
2601 }
2602
2603 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002604 impl ToTokens for ExprIf {
2605 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002606 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002607 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002608 wrap_bare_struct(tokens, &self.cond);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002609 self.then_branch.to_tokens(tokens);
2610 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002611 }
2612 }
2613
Michael Layzell734adb42017-06-07 16:58:31 -04002614 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002615 impl ToTokens for ExprIfLet {
2616 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002617 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002618 self.if_token.to_tokens(tokens);
2619 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002620 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002621 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002622 wrap_bare_struct(tokens, &self.expr);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002623 self.then_branch.to_tokens(tokens);
2624 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002625 }
2626 }
2627
Michael Layzell734adb42017-06-07 16:58:31 -04002628 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002629 impl ToTokens for ExprWhile {
2630 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002631 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002632 if self.label.is_some() {
2633 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002634 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002635 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002636 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002637 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002638 self.body.to_tokens(tokens);
2639 }
2640 }
2641
Michael Layzell734adb42017-06-07 16:58:31 -04002642 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002643 impl ToTokens for ExprWhileLet {
2644 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002645 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002646 if self.label.is_some() {
2647 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002648 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002649 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002650 self.while_token.to_tokens(tokens);
2651 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002652 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002653 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002654 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002655 self.body.to_tokens(tokens);
2656 }
2657 }
2658
Michael Layzell734adb42017-06-07 16:58:31 -04002659 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002660 impl ToTokens for ExprForLoop {
2661 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002662 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002663 if self.label.is_some() {
2664 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002665 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002666 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002667 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002668 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002669 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002670 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 self.body.to_tokens(tokens);
2672 }
2673 }
2674
Michael Layzell734adb42017-06-07 16:58:31 -04002675 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002676 impl ToTokens for ExprLoop {
2677 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002678 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002679 if self.label.is_some() {
2680 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002681 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002682 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002683 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002684 self.body.to_tokens(tokens);
2685 }
2686 }
2687
Michael Layzell734adb42017-06-07 16:58:31 -04002688 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002689 impl ToTokens for ExprMatch {
2690 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002691 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002692 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002693 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002694 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002695 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002696 arm.to_tokens(tokens);
2697 // Ensure that we have a comma after a non-block arm, except
2698 // for the last one.
2699 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002700 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002701 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002702 }
2703 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002704 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002705 }
2706 }
2707
Michael Layzell734adb42017-06-07 16:58:31 -04002708 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002709 impl ToTokens for ExprCatch {
2710 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002711 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002712 self.do_token.to_tokens(tokens);
2713 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002714 self.block.to_tokens(tokens);
2715 }
2716 }
2717
Michael Layzell734adb42017-06-07 16:58:31 -04002718 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002719 impl ToTokens for ExprYield {
2720 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002721 tokens.append_all(self.attrs.outer());
Alex Crichtonfe110462017-06-01 12:49:27 -07002722 self.yield_token.to_tokens(tokens);
2723 self.expr.to_tokens(tokens);
2724 }
2725 }
2726
2727 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002728 impl ToTokens for ExprClosure {
2729 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002730 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002731 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002732 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002733 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002734 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002735 FnArg::Captured(ArgCaptured {
2736 ref pat,
2737 ty: Type::Infer(_),
2738 ..
2739 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002740 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002741 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002742 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002743 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002744 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002745 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002746 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002747 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002748 self.body.to_tokens(tokens);
2749 }
2750 }
2751
Michael Layzell734adb42017-06-07 16:58:31 -04002752 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002753 impl ToTokens for ExprUnsafe {
2754 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002755 tokens.append_all(self.attrs.outer());
Nika Layzell640832a2017-12-04 13:37:09 -05002756 self.unsafe_token.to_tokens(tokens);
2757 self.block.to_tokens(tokens);
2758 }
2759 }
2760
2761 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002762 impl ToTokens for ExprBlock {
2763 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002764 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002765 self.block.to_tokens(tokens);
2766 }
2767 }
2768
Michael Layzell734adb42017-06-07 16:58:31 -04002769 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002770 impl ToTokens for ExprAssign {
2771 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002772 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002773 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002774 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002775 self.right.to_tokens(tokens);
2776 }
2777 }
2778
Michael Layzell734adb42017-06-07 16:58:31 -04002779 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002780 impl ToTokens for ExprAssignOp {
2781 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002782 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002783 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002784 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002785 self.right.to_tokens(tokens);
2786 }
2787 }
2788
Michael Layzell734adb42017-06-07 16:58:31 -04002789 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002790 impl ToTokens for ExprField {
2791 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002792 tokens.append_all(self.attrs.outer());
David Tolnay85b69a42017-12-27 20:43:10 -05002793 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002794 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002795 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002796 }
2797 }
2798
Michael Layzell734adb42017-06-07 16:58:31 -04002799 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002800 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002801 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002802 match *self {
2803 Member::Named(ident) => ident.to_tokens(tokens),
2804 Member::Unnamed(ref index) => index.to_tokens(tokens),
2805 }
2806 }
2807 }
2808
2809 #[cfg(feature = "full")]
2810 impl ToTokens for Index {
2811 fn to_tokens(&self, tokens: &mut Tokens) {
2812 tokens.append(TokenTree {
2813 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002814 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002815 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002816 }
2817 }
2818
2819 impl ToTokens for ExprIndex {
2820 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002821 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002822 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002823 self.bracket_token.surround(tokens, |tokens| {
2824 self.index.to_tokens(tokens);
2825 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002826 }
2827 }
2828
Michael Layzell734adb42017-06-07 16:58:31 -04002829 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002830 impl ToTokens for ExprRange {
2831 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002832 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002833 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002834 match self.limits {
2835 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2836 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2837 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002838 self.to.to_tokens(tokens);
2839 }
2840 }
2841
2842 impl ToTokens for ExprPath {
2843 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002844 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002845 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002846 }
2847 }
2848
Michael Layzell734adb42017-06-07 16:58:31 -04002849 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002850 impl ToTokens for ExprAddrOf {
2851 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002852 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002853 self.and_token.to_tokens(tokens);
David Tolnay24237fb2017-12-29 02:15:26 -05002854 self.mutability.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002855 self.expr.to_tokens(tokens);
2856 }
2857 }
2858
Michael Layzell734adb42017-06-07 16:58:31 -04002859 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002860 impl ToTokens for ExprBreak {
2861 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002862 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002863 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002864 self.label.to_tokens(tokens);
2865 self.expr.to_tokens(tokens);
2866 }
2867 }
2868
Michael Layzell734adb42017-06-07 16:58:31 -04002869 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002870 impl ToTokens for ExprContinue {
2871 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002872 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002873 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002874 self.label.to_tokens(tokens);
2875 }
2876 }
2877
Michael Layzell734adb42017-06-07 16:58:31 -04002878 #[cfg(feature = "full")]
David Tolnayc246cd32017-12-28 23:14:32 -05002879 impl ToTokens for ExprReturn {
Alex Crichton62a0a592017-05-22 13:58:53 -07002880 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002881 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002882 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002883 self.expr.to_tokens(tokens);
2884 }
2885 }
2886
Michael Layzell734adb42017-06-07 16:58:31 -04002887 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05002888 impl ToTokens for ExprMacro {
2889 fn to_tokens(&self, tokens: &mut Tokens) {
2890 tokens.append_all(self.attrs.outer());
2891 self.mac.to_tokens(tokens);
2892 }
2893 }
2894
2895 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002896 impl ToTokens for ExprStruct {
2897 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002898 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002899 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002900 self.brace_token.surround(tokens, |tokens| {
2901 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002902 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002903 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002904 self.rest.to_tokens(tokens);
2905 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002906 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002907 }
2908 }
2909
Michael Layzell734adb42017-06-07 16:58:31 -04002910 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002911 impl ToTokens for ExprRepeat {
2912 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002913 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002914 self.bracket_token.surround(tokens, |tokens| {
2915 self.expr.to_tokens(tokens);
2916 self.semi_token.to_tokens(tokens);
2917 self.amt.to_tokens(tokens);
2918 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002919 }
2920 }
2921
David Tolnaye98775f2017-12-28 23:17:00 -05002922 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04002923 impl ToTokens for ExprGroup {
2924 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002925 attrs_to_tokens(&self.attrs, tokens);
Michael Layzell93c36282017-06-04 20:43:14 -04002926 self.group_token.surround(tokens, |tokens| {
2927 self.expr.to_tokens(tokens);
2928 });
2929 }
2930 }
2931
David Tolnaye98775f2017-12-28 23:17:00 -05002932 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002933 impl ToTokens for ExprParen {
2934 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002935 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002936 self.paren_token.surround(tokens, |tokens| {
2937 self.expr.to_tokens(tokens);
2938 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002939 }
2940 }
2941
Michael Layzell734adb42017-06-07 16:58:31 -04002942 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002943 impl ToTokens for ExprTry {
2944 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002945 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002946 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002947 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002948 }
2949 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002950
David Tolnay2ae520a2017-12-29 11:19:50 -05002951 impl ToTokens for ExprVerbatim {
2952 fn to_tokens(&self, tokens: &mut Tokens) {
2953 self.tts.to_tokens(tokens);
2954 }
2955 }
2956
Michael Layzell734adb42017-06-07 16:58:31 -04002957 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002958 impl ToTokens for FieldValue {
2959 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002960 self.member.to_tokens(tokens);
David Tolnay5d7098a2017-12-29 01:35:24 -05002961 if let Some(ref colon_token) = self.colon_token {
2962 colon_token.to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002963 self.expr.to_tokens(tokens);
2964 }
David Tolnay055a7042016-10-02 19:23:54 -07002965 }
2966 }
2967
Michael Layzell734adb42017-06-07 16:58:31 -04002968 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002969 impl ToTokens for Arm {
2970 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002971 tokens.append_all(&self.attrs);
2972 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002973 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002974 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002975 self.guard.to_tokens(tokens);
2976 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002977 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002978 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002979 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002980 }
2981 }
2982
Michael Layzell734adb42017-06-07 16:58:31 -04002983 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002984 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002985 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002986 self.underscore_token.to_tokens(tokens);
2987 }
2988 }
2989
Michael Layzell734adb42017-06-07 16:58:31 -04002990 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002991 impl ToTokens for PatIdent {
2992 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay24237fb2017-12-29 02:15:26 -05002993 self.by_ref.to_tokens(tokens);
David Tolnayefc96fb2017-12-29 02:03:15 -05002994 self.mutability.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002995 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002996 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002997 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002998 self.subpat.to_tokens(tokens);
2999 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003000 }
3001 }
3002
Michael Layzell734adb42017-06-07 16:58:31 -04003003 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003004 impl ToTokens for PatStruct {
3005 fn to_tokens(&self, tokens: &mut Tokens) {
3006 self.path.to_tokens(tokens);
3007 self.brace_token.surround(tokens, |tokens| {
3008 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003009 // NOTE: We need a comma before the dot2 token if it is present.
3010 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003011 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003012 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003013 self.dot2_token.to_tokens(tokens);
3014 });
3015 }
3016 }
3017
Michael Layzell734adb42017-06-07 16:58:31 -04003018 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003019 impl ToTokens for PatTupleStruct {
3020 fn to_tokens(&self, tokens: &mut Tokens) {
3021 self.path.to_tokens(tokens);
3022 self.pat.to_tokens(tokens);
3023 }
3024 }
3025
Michael Layzell734adb42017-06-07 16:58:31 -04003026 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003027 impl ToTokens for PatPath {
3028 fn to_tokens(&self, tokens: &mut Tokens) {
3029 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
3030 }
3031 }
3032
Michael Layzell734adb42017-06-07 16:58:31 -04003033 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003034 impl ToTokens for PatTuple {
3035 fn to_tokens(&self, tokens: &mut Tokens) {
3036 self.paren_token.surround(tokens, |tokens| {
David Tolnay41871922017-12-29 01:53:45 -05003037 self.front.to_tokens(tokens);
3038 if let Some(ref dot2_token) = self.dot2_token {
3039 if !self.front.empty_or_trailing() {
3040 // Ensure there is a comma before the .. token.
David Tolnayf8db7ba2017-11-11 22:52:16 -08003041 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003042 }
David Tolnay41871922017-12-29 01:53:45 -05003043 dot2_token.to_tokens(tokens);
3044 self.comma_token.to_tokens(tokens);
3045 if self.comma_token.is_none() && !self.back.is_empty() {
3046 // Ensure there is a comma after the .. token.
3047 <Token![,]>::default().to_tokens(tokens);
3048 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07003049 }
David Tolnay41871922017-12-29 01:53:45 -05003050 self.back.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003051 });
3052 }
3053 }
3054
Michael Layzell734adb42017-06-07 16:58:31 -04003055 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003056 impl ToTokens for PatBox {
3057 fn to_tokens(&self, tokens: &mut Tokens) {
3058 self.box_token.to_tokens(tokens);
3059 self.pat.to_tokens(tokens);
3060 }
3061 }
3062
Michael Layzell734adb42017-06-07 16:58:31 -04003063 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003064 impl ToTokens for PatRef {
3065 fn to_tokens(&self, tokens: &mut Tokens) {
3066 self.and_token.to_tokens(tokens);
David Tolnay24237fb2017-12-29 02:15:26 -05003067 self.mutability.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003068 self.pat.to_tokens(tokens);
3069 }
3070 }
3071
Michael Layzell734adb42017-06-07 16:58:31 -04003072 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003073 impl ToTokens for PatLit {
3074 fn to_tokens(&self, tokens: &mut Tokens) {
3075 self.expr.to_tokens(tokens);
3076 }
3077 }
3078
Michael Layzell734adb42017-06-07 16:58:31 -04003079 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003080 impl ToTokens for PatRange {
3081 fn to_tokens(&self, tokens: &mut Tokens) {
3082 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08003083 match self.limits {
3084 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3085 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
3086 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003087 self.hi.to_tokens(tokens);
3088 }
3089 }
3090
Michael Layzell734adb42017-06-07 16:58:31 -04003091 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003092 impl ToTokens for PatSlice {
3093 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003094 // XXX: This is a mess, and it will be so easy to screw it up. How
3095 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003096 self.bracket_token.surround(tokens, |tokens| {
3097 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003098
3099 // If we need a comma before the middle or standalone .. token,
3100 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05003101 if !self.front.empty_or_trailing()
3102 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04003103 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003104 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003105 }
3106
3107 // If we have an identifier, we always need a .. token.
3108 if self.middle.is_some() {
3109 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003110 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003111 } else if self.dot2_token.is_some() {
3112 self.dot2_token.to_tokens(tokens);
3113 }
3114
3115 // Make sure we have a comma before the back half.
3116 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07003117 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003118 self.back.to_tokens(tokens);
3119 } else {
3120 self.comma_token.to_tokens(tokens);
3121 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003122 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07003123 }
3124 }
3125
Michael Layzell734adb42017-06-07 16:58:31 -04003126 #[cfg(feature = "full")]
David Tolnay2ae520a2017-12-29 11:19:50 -05003127 impl ToTokens for PatVerbatim {
3128 fn to_tokens(&self, tokens: &mut Tokens) {
3129 self.tts.to_tokens(tokens);
3130 }
3131 }
3132
3133 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07003134 impl ToTokens for FieldPat {
3135 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay5d7098a2017-12-29 01:35:24 -05003136 if let Some(ref colon_token) = self.colon_token {
David Tolnay85b69a42017-12-27 20:43:10 -05003137 self.member.to_tokens(tokens);
David Tolnay5d7098a2017-12-29 01:35:24 -05003138 colon_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003139 }
3140 self.pat.to_tokens(tokens);
3141 }
3142 }
3143
Michael Layzell734adb42017-06-07 16:58:31 -04003144 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003145 impl ToTokens for Block {
3146 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003147 self.brace_token.surround(tokens, |tokens| {
3148 tokens.append_all(&self.stmts);
3149 });
David Tolnay42602292016-10-01 22:25:45 -07003150 }
3151 }
3152
Michael Layzell734adb42017-06-07 16:58:31 -04003153 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003154 impl ToTokens for Stmt {
3155 fn to_tokens(&self, tokens: &mut Tokens) {
3156 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07003157 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07003158 Stmt::Item(ref item) => item.to_tokens(tokens),
3159 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003160 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003161 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003162 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003163 }
David Tolnay42602292016-10-01 22:25:45 -07003164 }
3165 }
3166 }
David Tolnay191e0582016-10-02 18:31:09 -07003167
Michael Layzell734adb42017-06-07 16:58:31 -04003168 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003169 impl ToTokens for Local {
3170 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003171 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003172 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003173 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003174 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003175 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003176 self.ty.to_tokens(tokens);
3177 }
3178 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003179 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003180 self.init.to_tokens(tokens);
3181 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003182 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003183 }
3184 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003185}