blob: e50cf3a8d6ac770a43d3b890e811f6e95f8d3211 [file] [log] [blame]
David Tolnayf4bbbd92016-09-23 14:41:55 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnay85b69a42017-12-27 20:43:10 -05003#[cfg(feature = "full")]
4use proc_macro2::Span;
5#[cfg(feature = "full")]
6use std::hash::{Hash, Hasher};
David Tolnayf4bbbd92016-09-23 14:41:55 -07007
Alex Crichton62a0a592017-05-22 13:58:53 -07008ast_enum_of_structs! {
David Tolnay8c91b882017-12-28 23:04:32 -05009 /// An expression.
10 pub enum Expr {
Alex Crichton62a0a592017-05-22 13:58:53 -070011 /// A `box x` expression.
Michael Layzell734adb42017-06-07 16:58:31 -040012 pub Box(ExprBox #full {
David Tolnay8c91b882017-12-28 23:04:32 -050013 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080014 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -050015 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -070016 }),
Clar Charrd22b5702017-03-10 15:24:56 -050017
David Tolnay8701a5c2017-12-28 23:31:10 -050018 /// E.g. 'place <- value'.
Michael Layzell734adb42017-06-07 16:58:31 -040019 pub InPlace(ExprInPlace #full {
David Tolnay8c91b882017-12-28 23:04:32 -050020 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070021 pub place: Box<Expr>,
David Tolnay8701a5c2017-12-28 23:31:10 -050022 pub arrow_token: Token![<-],
Alex Crichton62a0a592017-05-22 13:58:53 -070023 pub value: Box<Expr>,
24 }),
Clar Charrd22b5702017-03-10 15:24:56 -050025
Alex Crichton62a0a592017-05-22 13:58:53 -070026 /// An array, e.g. `[a, b, c, d]`.
Michael Layzell734adb42017-06-07 16:58:31 -040027 pub Array(ExprArray #full {
David Tolnay8c91b882017-12-28 23:04:32 -050028 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050029 pub bracket_token: token::Bracket,
David Tolnay2a86fdd2017-12-28 23:34:28 -050030 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070031 }),
Clar Charrd22b5702017-03-10 15:24:56 -050032
Alex Crichton62a0a592017-05-22 13:58:53 -070033 /// A function call.
34 pub Call(ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -050035 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070036 pub func: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -050037 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -050038 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070039 }),
Clar Charrd22b5702017-03-10 15:24:56 -050040
Alex Crichton62a0a592017-05-22 13:58:53 -070041 /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`)
42 ///
43 /// The `Ident` is the identifier for the method name.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080044 /// The vector of `Type`s are the ascripted type parameters for the method
Alex Crichton62a0a592017-05-22 13:58:53 -070045 /// (within the angle brackets).
Michael Layzell734adb42017-06-07 16:58:31 -040046 pub MethodCall(ExprMethodCall #full {
David Tolnay8c91b882017-12-28 23:04:32 -050047 pub attrs: Vec<Attribute>,
David Tolnay76418512017-12-28 23:47:47 -050048 pub receiver: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080049 pub dot_token: Token![.],
David Tolnay4a3f59a2017-12-28 21:21:12 -050050 pub method: Ident,
David Tolnayd60cfec2017-12-29 00:21:38 -050051 pub turbofish: Option<MethodTurbofish>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050052 pub paren_token: token::Paren,
53 pub args: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070054 }),
Clar Charrd22b5702017-03-10 15:24:56 -050055
Alex Crichton62a0a592017-05-22 13:58:53 -070056 /// A tuple, e.g. `(a, b, c, d)`.
David Tolnay05362582017-12-26 01:33:57 -050057 pub Tuple(ExprTuple #full {
David Tolnay8c91b882017-12-28 23:04:32 -050058 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -050059 pub paren_token: token::Paren,
David Tolnay2a86fdd2017-12-28 23:34:28 -050060 pub elems: Delimited<Expr, Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -070061 }),
Clar Charrd22b5702017-03-10 15:24:56 -050062
Alex Crichton62a0a592017-05-22 13:58:53 -070063 /// A binary operation, e.g. `a + b`, `a * b`.
64 pub Binary(ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -050065 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070066 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -050067 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -070068 pub right: Box<Expr>,
69 }),
Clar Charrd22b5702017-03-10 15:24:56 -050070
Alex Crichton62a0a592017-05-22 13:58:53 -070071 /// A unary operation, e.g. `!x`, `*x`.
72 pub Unary(ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -050073 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 pub op: UnOp,
75 pub expr: Box<Expr>,
76 }),
Clar Charrd22b5702017-03-10 15:24:56 -050077
Alex Crichton62a0a592017-05-22 13:58:53 -070078 /// A literal, e.g. `1`, `"foo"`.
David Tolnay8c91b882017-12-28 23:04:32 -050079 pub Lit(ExprLit {
80 pub attrs: Vec<Attribute>,
81 pub lit: Lit,
82 }),
Clar Charrd22b5702017-03-10 15:24:56 -050083
Alex Crichton62a0a592017-05-22 13:58:53 -070084 /// A cast, e.g. `foo as f64`.
85 pub Cast(ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -050086 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070087 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080088 pub as_token: Token![as],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080089 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070090 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// A type ascription, e.g. `foo: f64`.
David Tolnay0cf94f22017-12-28 23:46:26 -050093 pub Type(ExprType #full {
David Tolnay8c91b882017-12-28 23:04:32 -050094 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -070095 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -080096 pub colon_token: Token![:],
David Tolnayfd6bf5c2017-11-12 09:41:14 -080097 pub ty: Box<Type>,
Alex Crichton62a0a592017-05-22 13:58:53 -070098 }),
Clar Charrd22b5702017-03-10 15:24:56 -050099
Alex Crichton62a0a592017-05-22 13:58:53 -0700100 /// An `if` block, with an optional else block
101 ///
102 /// E.g., `if expr { block } else { expr }`
Michael Layzell734adb42017-06-07 16:58:31 -0400103 pub If(ExprIf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500104 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500105 pub if_token: Token![if],
Alex Crichton62a0a592017-05-22 13:58:53 -0700106 pub cond: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500107 pub then_branch: Block,
108 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700109 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500110
Alex Crichton62a0a592017-05-22 13:58:53 -0700111 /// An `if let` expression with an optional else block
112 ///
113 /// E.g., `if let pat = expr { block } else { expr }`
114 ///
115 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400116 pub IfLet(ExprIfLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500117 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800118 pub if_token: Token![if],
119 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500120 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800121 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500122 pub expr: Box<Expr>,
David Tolnay2ccf32a2017-12-29 00:34:26 -0500123 pub then_branch: Block,
124 pub else_branch: Option<(Token![else], Box<Expr>)>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700125 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500126
Alex Crichton62a0a592017-05-22 13:58:53 -0700127 /// A while loop, with an optional label
128 ///
129 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400130 pub While(ExprWhile #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500131 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700132 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800133 pub colon_token: Option<Token![:]>,
134 pub while_token: Token![while],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500135 pub cond: Box<Expr>,
136 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700137 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500138
Alex Crichton62a0a592017-05-22 13:58:53 -0700139 /// A while-let loop, with an optional label.
140 ///
141 /// E.g., `'label: while let pat = expr { block }`
142 ///
143 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400144 pub WhileLet(ExprWhileLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500145 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700146 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800147 pub colon_token: Option<Token![:]>,
148 pub while_token: Token![while],
149 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500150 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800151 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500152 pub expr: Box<Expr>,
153 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700154 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500155
Alex Crichton62a0a592017-05-22 13:58:53 -0700156 /// A for loop, with an optional label.
157 ///
158 /// E.g., `'label: for pat in expr { block }`
159 ///
160 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400161 pub ForLoop(ExprForLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500162 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500163 pub label: Option<Lifetime>,
164 pub colon_token: Option<Token![:]>,
165 pub for_token: Token![for],
Alex Crichton62a0a592017-05-22 13:58:53 -0700166 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500167 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700168 pub expr: Box<Expr>,
169 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700170 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500171
Alex Crichton62a0a592017-05-22 13:58:53 -0700172 /// Conditionless loop with an optional label.
173 ///
174 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400175 pub Loop(ExprLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500176 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700177 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800178 pub colon_token: Option<Token![:]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500179 pub loop_token: Token![loop],
180 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700181 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500182
Alex Crichton62a0a592017-05-22 13:58:53 -0700183 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400184 pub Match(ExprMatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500185 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800186 pub match_token: Token![match],
Alex Crichton62a0a592017-05-22 13:58:53 -0700187 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500188 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700189 pub arms: Vec<Arm>,
190 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500191
Alex Crichton62a0a592017-05-22 13:58:53 -0700192 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400193 pub Closure(ExprClosure #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500194 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700195 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800196 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500197 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800198 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500199 pub output: ReturnType,
200 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700201 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500202
Nika Layzell640832a2017-12-04 13:37:09 -0500203 /// An unsafe block (`unsafe { ... }`)
204 pub Unsafe(ExprUnsafe #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500205 pub attrs: Vec<Attribute>,
Nika Layzell640832a2017-12-04 13:37:09 -0500206 pub unsafe_token: Token![unsafe],
207 pub block: Block,
208 }),
209
210 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400211 pub Block(ExprBlock #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500212 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700213 pub block: Block,
214 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700215
Alex Crichton62a0a592017-05-22 13:58:53 -0700216 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400217 pub Assign(ExprAssign #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500218 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700219 pub left: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800220 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500221 pub right: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700222 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500223
Alex Crichton62a0a592017-05-22 13:58:53 -0700224 /// An assignment with an operator
225 ///
226 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400227 pub AssignOp(ExprAssignOp #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500228 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700229 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500230 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 pub right: Box<Expr>,
232 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500233
David Tolnay85b69a42017-12-27 20:43:10 -0500234 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
235 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400236 pub Field(ExprField #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500237 pub attrs: Vec<Attribute>,
David Tolnay85b69a42017-12-27 20:43:10 -0500238 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800239 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500240 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700241 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500242
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 /// An indexing operation (`foo[2]`)
244 pub Index(ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -0500245 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700246 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500247 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500248 pub index: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700249 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500250
David Tolnaybe55d7b2017-12-17 23:41:20 -0800251 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400252 pub Range(ExprRange #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500253 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700254 pub from: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700255 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500256 pub to: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700258
Alex Crichton62a0a592017-05-22 13:58:53 -0700259 /// Variable reference, possibly containing `::` and/or type
260 /// parameters, e.g. foo::bar::<baz>.
261 ///
262 /// Optionally "qualified",
263 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
264 pub Path(ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -0500265 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700266 pub qself: Option<QSelf>,
267 pub path: Path,
268 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700269
Alex Crichton62a0a592017-05-22 13:58:53 -0700270 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400271 pub AddrOf(ExprAddrOf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500272 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800273 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700274 pub mutbl: Mutability,
275 pub expr: Box<Expr>,
276 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500277
Alex Crichton62a0a592017-05-22 13:58:53 -0700278 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400279 pub Break(ExprBreak #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500280 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500281 pub break_token: Token![break],
David Tolnay63e3dee2017-06-03 20:13:17 -0700282 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700283 pub expr: Option<Box<Expr>>,
284 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500285
Alex Crichton62a0a592017-05-22 13:58:53 -0700286 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400287 pub Continue(ExprContinue #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500288 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800289 pub continue_token: Token![continue],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500290 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700291 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500292
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 /// A `return`, with an optional value to be returned
David Tolnayc246cd32017-12-28 23:14:32 -0500294 pub Return(ExprReturn #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500295 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800296 pub return_token: Token![return],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500297 pub expr: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700298 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700299
Alex Crichton62a0a592017-05-22 13:58:53 -0700300 /// A macro invocation; pre-expansion
David Tolnay8c91b882017-12-28 23:04:32 -0500301 pub Macro(ExprMacro #full {
302 pub attrs: Vec<Attribute>,
303 pub mac: Macro,
304 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700305
Alex Crichton62a0a592017-05-22 13:58:53 -0700306 /// A struct literal expression.
307 ///
308 /// For example, `Foo {x: 1, y: 2}`, or
309 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400310 pub Struct(ExprStruct #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500311 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700312 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500313 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500314 pub fields: Delimited<FieldValue, Token![,]>,
315 pub dot2_token: Option<Token![..]>,
316 pub rest: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700317 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700318
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 /// An array literal constructed from one repeated element.
320 ///
321 /// For example, `[1; 5]`. The first expression is the element
322 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400323 pub Repeat(ExprRepeat #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500324 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500325 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700326 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500327 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700328 pub amt: Box<Expr>,
329 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700330
Alex Crichton62a0a592017-05-22 13:58:53 -0700331 /// No-op: used solely so we can pretty-print faithfully
David Tolnaye98775f2017-12-28 23:17:00 -0500332 pub Paren(ExprParen #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500333 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500334 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500335 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700336 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700337
Michael Layzell93c36282017-06-04 20:43:14 -0400338 /// No-op: used solely so we can pretty-print faithfully
339 ///
340 /// A `group` represents a `None`-delimited span in the input
341 /// `TokenStream` which affects the precidence of the resulting
342 /// expression. They are used for macro hygiene.
David Tolnaye98775f2017-12-28 23:17:00 -0500343 pub Group(ExprGroup #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500344 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500345 pub group_token: token::Group,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500346 pub expr: Box<Expr>,
Michael Layzell93c36282017-06-04 20:43:14 -0400347 }),
348
Alex Crichton62a0a592017-05-22 13:58:53 -0700349 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400350 pub Try(ExprTry #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500351 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700352 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800353 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700354 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700355
Alex Crichton62a0a592017-05-22 13:58:53 -0700356 /// A catch expression.
357 ///
358 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400359 pub Catch(ExprCatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500360 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800361 pub do_token: Token![do],
362 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700363 pub block: Block,
364 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700365
366 /// A yield expression.
367 ///
368 /// E.g. `yield expr`
369 pub Yield(ExprYield #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500370 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800371 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700372 pub expr: Option<Box<Expr>>,
373 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700374 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700375}
376
David Tolnay8c91b882017-12-28 23:04:32 -0500377impl Expr {
378 // Not public API.
379 #[doc(hidden)]
David Tolnay096d4982017-12-28 23:18:18 -0500380 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500381 pub fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
382 match *self {
383 Expr::Box(ExprBox { ref mut attrs, .. }) |
384 Expr::InPlace(ExprInPlace { ref mut attrs, .. }) |
385 Expr::Array(ExprArray { ref mut attrs, .. }) |
386 Expr::Call(ExprCall { ref mut attrs, .. }) |
387 Expr::MethodCall(ExprMethodCall { ref mut attrs, .. }) |
388 Expr::Tuple(ExprTuple { ref mut attrs, .. }) |
389 Expr::Binary(ExprBinary { ref mut attrs, .. }) |
390 Expr::Unary(ExprUnary { ref mut attrs, .. }) |
391 Expr::Lit(ExprLit { ref mut attrs, .. }) |
392 Expr::Cast(ExprCast { ref mut attrs, .. }) |
393 Expr::Type(ExprType { ref mut attrs, .. }) |
394 Expr::If(ExprIf { ref mut attrs, .. }) |
395 Expr::IfLet(ExprIfLet { ref mut attrs, .. }) |
396 Expr::While(ExprWhile { ref mut attrs, .. }) |
397 Expr::WhileLet(ExprWhileLet { ref mut attrs, .. }) |
398 Expr::ForLoop(ExprForLoop { ref mut attrs, .. }) |
399 Expr::Loop(ExprLoop { ref mut attrs, .. }) |
400 Expr::Match(ExprMatch { ref mut attrs, .. }) |
401 Expr::Closure(ExprClosure { ref mut attrs, .. }) |
402 Expr::Unsafe(ExprUnsafe { ref mut attrs, .. }) |
403 Expr::Block(ExprBlock { ref mut attrs, .. }) |
404 Expr::Assign(ExprAssign { ref mut attrs, .. }) |
405 Expr::AssignOp(ExprAssignOp { ref mut attrs, .. }) |
406 Expr::Field(ExprField { ref mut attrs, .. }) |
407 Expr::Index(ExprIndex { ref mut attrs, .. }) |
408 Expr::Range(ExprRange { ref mut attrs, .. }) |
409 Expr::Path(ExprPath { ref mut attrs, .. }) |
410 Expr::AddrOf(ExprAddrOf { ref mut attrs, .. }) |
411 Expr::Break(ExprBreak { ref mut attrs, .. }) |
412 Expr::Continue(ExprContinue { ref mut attrs, .. }) |
David Tolnayc246cd32017-12-28 23:14:32 -0500413 Expr::Return(ExprReturn { ref mut attrs, .. }) |
David Tolnay8c91b882017-12-28 23:04:32 -0500414 Expr::Macro(ExprMacro { ref mut attrs, .. }) |
415 Expr::Struct(ExprStruct { ref mut attrs, .. }) |
416 Expr::Repeat(ExprRepeat { ref mut attrs, .. }) |
417 Expr::Paren(ExprParen { ref mut attrs, .. }) |
418 Expr::Group(ExprGroup { ref mut attrs, .. }) |
419 Expr::Try(ExprTry { ref mut attrs, .. }) |
420 Expr::Catch(ExprCatch { ref mut attrs, .. }) |
421 Expr::Yield(ExprYield { ref mut attrs, .. }) => attrs,
422 }
423 }
424}
425
Michael Layzell734adb42017-06-07 16:58:31 -0400426#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500427ast_enum! {
428 /// A struct or tuple struct field accessed in a struct literal or field
429 /// expression.
430 pub enum Member {
431 /// A named field like `self.x`.
432 Named(Ident),
433 /// An unnamed field like `self.0`.
434 Unnamed(Index),
435 }
436}
437
438#[cfg(feature = "full")]
439ast_struct! {
440 /// The index of an unnamed tuple struct field.
441 pub struct Index #manual_extra_traits {
442 pub index: u32,
443 pub span: Span,
444 }
445}
446
447#[cfg(feature = "full")]
448impl Eq for Index {}
449
450#[cfg(feature = "full")]
451impl PartialEq for Index {
452 fn eq(&self, other: &Self) -> bool {
453 self.index == other.index
454 }
455}
456
457#[cfg(feature = "full")]
458impl Hash for Index {
459 fn hash<H: Hasher>(&self, state: &mut H) {
460 self.index.hash(state);
461 }
462}
463
464#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700465ast_struct! {
David Tolnayd60cfec2017-12-29 00:21:38 -0500466 pub struct MethodTurbofish {
467 pub colon2_token: Token![::],
468 pub lt_token: Token![<],
469 pub args: Delimited<GenericMethodArgument, Token![,]>,
470 pub gt_token: Token![>],
471 }
472}
473
474#[cfg(feature = "full")]
475ast_enum! {
476 /// A individual generic argument like `T`.
477 pub enum GenericMethodArgument {
478 /// The type parameters for this path segment, if present.
479 Type(Type),
480 /// Const expression. Must be inside of a block.
481 ///
482 /// NOTE: Identity expressions are represented as Type arguments, as
483 /// they are indistinguishable syntactically.
484 Const(Expr),
485 }
486}
487
488#[cfg(feature = "full")]
489ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700490 /// A field-value pair in a struct literal.
491 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500492 /// Attributes tagged on the field.
493 pub attrs: Vec<Attribute>,
494
495 /// Name or index of the field.
496 pub member: Member,
497
498 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500499
Alex Crichton62a0a592017-05-22 13:58:53 -0700500 /// Value of the field.
501 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500502
Alex Crichton62a0a592017-05-22 13:58:53 -0700503 /// Whether this is a shorthand field, e.g. `Struct { x }`
504 /// instead of `Struct { x: x }`.
505 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700506 }
David Tolnay055a7042016-10-02 19:23:54 -0700507}
508
Michael Layzell734adb42017-06-07 16:58:31 -0400509#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700510ast_struct! {
511 /// A Block (`{ .. }`).
512 ///
513 /// E.g. `{ .. }` as in `fn foo() { .. }`
514 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500515 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700516 /// Statements in a block
517 pub stmts: Vec<Stmt>,
518 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700519}
520
Michael Layzell734adb42017-06-07 16:58:31 -0400521#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700522ast_enum! {
523 /// A statement, usually ending in a semicolon.
524 pub enum Stmt {
525 /// A local (let) binding.
526 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700527
Alex Crichton62a0a592017-05-22 13:58:53 -0700528 /// An item definition.
529 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700530
Alex Crichton62a0a592017-05-22 13:58:53 -0700531 /// Expr without trailing semicolon.
532 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700533
Alex Crichton62a0a592017-05-22 13:58:53 -0700534 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800535 Semi(Box<Expr>, Token![;]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700536 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700537}
538
Michael Layzell734adb42017-06-07 16:58:31 -0400539#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700540ast_struct! {
541 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
542 pub struct Local {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500543 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800544 pub let_token: Token![let],
Alex Crichton62a0a592017-05-22 13:58:53 -0700545 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500546 pub colon_token: Option<Token![:]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800547 pub ty: Option<Box<Type>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500548 pub eq_token: Option<Token![=]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700549 /// Initializer expression to set the value, if any
550 pub init: Option<Box<Expr>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500551 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700552 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700553}
554
Michael Layzell734adb42017-06-07 16:58:31 -0400555#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700556ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700557 // Clippy false positive
558 // https://github.com/Manishearth/rust-clippy/issues/1241
559 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
560 pub enum Pat {
561 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700562 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800563 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700564 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700565
Alex Crichton62a0a592017-05-22 13:58:53 -0700566 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
567 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
568 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
569 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700570 pub Ident(PatIdent {
571 pub mode: BindingMode,
572 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800573 pub at_token: Option<Token![@]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500574 pub subpat: Option<Box<Pat>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700575 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700576
Alex Crichton62a0a592017-05-22 13:58:53 -0700577 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
578 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700579 pub Struct(PatStruct {
580 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500581 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500582 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800583 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700584 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700585
Alex Crichton62a0a592017-05-22 13:58:53 -0700586 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
587 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
588 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700589 pub TupleStruct(PatTupleStruct {
590 pub path: Path,
591 pub pat: PatTuple,
592 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700593
Alex Crichton62a0a592017-05-22 13:58:53 -0700594 /// A possibly qualified path pattern.
595 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
596 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
597 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700598 pub Path(PatPath {
599 pub qself: Option<QSelf>,
600 pub path: Path,
601 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700602
Alex Crichton62a0a592017-05-22 13:58:53 -0700603 /// A tuple pattern `(a, b)`.
604 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
605 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700606 pub Tuple(PatTuple {
David Tolnay32954ef2017-12-26 22:43:16 -0500607 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500608 pub pats: Delimited<Pat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800609 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500610 pub dots_pos: Option<usize>,
611 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700612 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700613 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700614 pub Box(PatBox {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800615 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500616 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700617 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700618 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700619 pub Ref(PatRef {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800620 pub and_token: Token![&],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500621 pub mutbl: Mutability,
622 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700623 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700624 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700625 pub Lit(PatLit {
626 pub expr: Box<Expr>,
627 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800628 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700629 pub Range(PatRange {
630 pub lo: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700631 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500632 pub hi: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700633 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400634 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700635 pub Slice(PatSlice {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500636 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800637 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700638 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800639 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500640 pub dot2_token: Option<Token![..]>,
641 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700642 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700643 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800644 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700645 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700646}
647
Michael Layzell734adb42017-06-07 16:58:31 -0400648#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700649ast_struct! {
650 /// An arm of a 'match'.
651 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800652 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700653 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500654 /// ```rust
655 /// # #![feature(dotdoteq_in_patterns)]
656 /// #
657 /// # fn main() {
658 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700659 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500660 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700661 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500662 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700663 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500664 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700665 /// ```
666 pub struct Arm {
667 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800668 pub pats: Delimited<Pat, Token![|]>,
669 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700670 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800671 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700672 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800673 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700674 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700675}
676
Michael Layzell734adb42017-06-07 16:58:31 -0400677#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700678ast_enum! {
679 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700680 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700681 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800682 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700683 Ref,
684 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700685}
686
Michael Layzell734adb42017-06-07 16:58:31 -0400687#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700688ast_enum! {
689 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700690 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700691 pub enum RangeLimits {
692 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800693 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700694 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800695 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700696 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700697}
698
Michael Layzell734adb42017-06-07 16:58:31 -0400699#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700700ast_struct! {
701 /// A single field in a struct pattern
702 ///
703 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
704 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
705 /// except `is_shorthand` is true
706 pub struct FieldPat {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500707 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700708 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500709 pub member: Member,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500710 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700711 /// The pattern the field is destructured to
712 pub pat: Box<Pat>,
713 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700714 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700715}
716
Michael Layzell734adb42017-06-07 16:58:31 -0400717#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700718ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700719 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700720 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800721 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700722 ByValue(Mutability),
723 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700724}
725
Michael Layzell3936ceb2017-07-08 00:28:36 -0400726#[cfg(any(feature = "parsing", feature = "printing"))]
727#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700728fn arm_expr_requires_comma(expr: &Expr) -> bool {
729 // see https://github.com/rust-lang/rust/blob/eb8f2586e
730 // /src/libsyntax/parse/classify.rs#L17-L37
David Tolnay8c91b882017-12-28 23:04:32 -0500731 match *expr {
732 Expr::Unsafe(..)
733 | Expr::Block(..)
734 | Expr::If(..)
735 | Expr::IfLet(..)
736 | Expr::Match(..)
737 | Expr::While(..)
738 | Expr::WhileLet(..)
739 | Expr::Loop(..)
740 | Expr::ForLoop(..)
741 | Expr::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700742 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400743 }
744}
745
David Tolnayb9c8e322016-09-23 20:48:37 -0700746#[cfg(feature = "parsing")]
747pub mod parsing {
748 use super::*;
David Tolnay2ccf32a2017-12-29 00:34:26 -0500749 use ty::parsing::qpath;
750 #[cfg(feature = "full")]
751 use ty::parsing::ty_no_eq_after;
David Tolnayb9c8e322016-09-23 20:48:37 -0700752
Michael Layzell734adb42017-06-07 16:58:31 -0400753 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500754 use proc_macro2::{Delimiter, Span, TokenNode, TokenStream};
David Tolnayc5ab8c62017-12-26 16:43:39 -0500755 use synom::Synom;
756 use cursor::Cursor;
Michael Layzell734adb42017-06-07 16:58:31 -0400757 #[cfg(feature = "full")]
David Tolnayc5ab8c62017-12-26 16:43:39 -0500758 use parse_error;
David Tolnay203557a2017-12-27 23:59:33 -0500759 use synom::PResult;
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700760
David Tolnaybcf26022017-12-25 22:10:52 -0500761 // When we're parsing expressions which occur before blocks, like in an if
762 // statement's condition, we cannot parse a struct literal.
763 //
764 // Struct literals are ambiguous in certain positions
765 // https://github.com/rust-lang/rfcs/pull/92
David Tolnayaf2557e2016-10-24 11:52:21 -0700766 macro_rules! ambiguous_expr {
767 ($i:expr, $allow_struct:ident) => {
David Tolnay54e854d2016-10-24 12:03:30 -0700768 ambiguous_expr($i, $allow_struct, true)
David Tolnayaf2557e2016-10-24 11:52:21 -0700769 };
770 }
771
David Tolnaybcf26022017-12-25 22:10:52 -0500772 // When we are parsing an optional suffix expression, we cannot allow blocks
773 // if structs are not allowed.
774 //
775 // Example:
776 //
777 // if break {} {}
778 //
779 // is ambiguous between:
780 //
781 // if (break {}) {}
782 // if (break) {} {}
Michael Layzell734adb42017-06-07 16:58:31 -0400783 #[cfg(feature = "full")]
Michael Layzellb78f3b52017-06-04 19:03:03 -0400784 macro_rules! opt_ambiguous_expr {
785 ($i:expr, $allow_struct:ident) => {
786 option!($i, call!(ambiguous_expr, $allow_struct, $allow_struct))
787 };
788 }
789
Alex Crichton954046c2017-05-30 21:49:42 -0700790 impl Synom for Expr {
Michael Layzell92639a52017-06-01 00:07:44 -0400791 named!(parse -> Self, ambiguous_expr!(true));
Alex Crichton954046c2017-05-30 21:49:42 -0700792
793 fn description() -> Option<&'static str> {
794 Some("expression")
795 }
796 }
797
Michael Layzell734adb42017-06-07 16:58:31 -0400798 #[cfg(feature = "full")]
David Tolnayaf2557e2016-10-24 11:52:21 -0700799 named!(expr_no_struct -> Expr, ambiguous_expr!(false));
800
David Tolnaybcf26022017-12-25 22:10:52 -0500801 // Parse an arbitrary expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400802 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -0500803 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500804 call!(i, assign_expr, allow_struct, allow_block)
Michael Layzellb78f3b52017-06-04 19:03:03 -0400805 }
806
Michael Layzell734adb42017-06-07 16:58:31 -0400807 #[cfg(not(feature = "full"))]
David Tolnay51382052017-12-27 13:46:21 -0500808 fn ambiguous_expr(i: Cursor, allow_struct: bool, allow_block: bool) -> PResult<Expr> {
David Tolnay8c91b882017-12-28 23:04:32 -0500809 // NOTE: We intentionally skip assign_expr, placement_expr, and
810 // range_expr, as they are not parsed in non-full mode.
811 call!(i, or_expr, allow_struct, allow_block)
Michael Layzell734adb42017-06-07 16:58:31 -0400812 }
813
David Tolnaybcf26022017-12-25 22:10:52 -0500814 // Parse a left-associative binary operator.
Michael Layzellb78f3b52017-06-04 19:03:03 -0400815 macro_rules! binop {
816 (
817 $name: ident,
818 $next: ident,
819 $submac: ident!( $($args:tt)* )
820 ) => {
David Tolnay8c91b882017-12-28 23:04:32 -0500821 named!($name(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400822 mut e: call!($next, allow_struct, allow_block) >>
823 many0!(do_parse!(
824 op: $submac!($($args)*) >>
825 rhs: call!($next, allow_struct, true) >>
826 ({
827 e = ExprBinary {
David Tolnay8c91b882017-12-28 23:04:32 -0500828 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400829 left: Box::new(e.into()),
830 op: op,
831 right: Box::new(rhs.into()),
832 }.into();
833 })
834 )) >>
835 (e)
836 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700837 }
David Tolnay54e854d2016-10-24 12:03:30 -0700838 }
David Tolnayb9c8e322016-09-23 20:48:37 -0700839
David Tolnaybcf26022017-12-25 22:10:52 -0500840 // <placement> = <placement> ..
841 // <placement> += <placement> ..
842 // <placement> -= <placement> ..
843 // <placement> *= <placement> ..
844 // <placement> /= <placement> ..
845 // <placement> %= <placement> ..
846 // <placement> ^= <placement> ..
847 // <placement> &= <placement> ..
848 // <placement> |= <placement> ..
849 // <placement> <<= <placement> ..
850 // <placement> >>= <placement> ..
851 //
852 // NOTE: This operator is right-associative.
Michael Layzell734adb42017-06-07 16:58:31 -0400853 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500854 named!(assign_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400855 mut e: call!(placement_expr, allow_struct, allow_block) >>
856 alt!(
857 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800858 eq: punct!(=) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400859 // Recurse into self to parse right-associative operator.
860 rhs: call!(assign_expr, allow_struct, true) >>
861 ({
862 e = ExprAssign {
David Tolnay8c91b882017-12-28 23:04:32 -0500863 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400864 left: Box::new(e.into()),
865 eq_token: eq,
866 right: Box::new(rhs.into()),
867 }.into();
868 })
869 )
870 |
871 do_parse!(
872 op: call!(BinOp::parse_assign_op) >>
873 // Recurse into self to parse right-associative operator.
874 rhs: call!(assign_expr, allow_struct, true) >>
875 ({
876 e = ExprAssignOp {
David Tolnay8c91b882017-12-28 23:04:32 -0500877 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400878 left: Box::new(e.into()),
879 op: op,
880 right: Box::new(rhs.into()),
881 }.into();
882 })
883 )
884 |
885 epsilon!()
886 ) >>
887 (e)
888 ));
889
David Tolnaybcf26022017-12-25 22:10:52 -0500890 // <range> <- <range> ..
891 //
892 // NOTE: The `in place { expr }` version of this syntax is parsed in
893 // `atom_expr`, not here.
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!(placement_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400898 mut e: call!(range_expr, allow_struct, allow_block) >>
899 alt!(
900 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800901 arrow: punct!(<-) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -0400902 // Recurse into self to parse right-associative operator.
903 rhs: call!(placement_expr, allow_struct, true) >>
904 ({
Michael Layzellb78f3b52017-06-04 19:03:03 -0400905 e = ExprInPlace {
David Tolnay8c91b882017-12-28 23:04:32 -0500906 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400907 // op: BinOp::Place(larrow),
908 place: Box::new(e.into()),
David Tolnay8701a5c2017-12-28 23:31:10 -0500909 arrow_token: arrow,
Michael Layzellb78f3b52017-06-04 19:03:03 -0400910 value: Box::new(rhs.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400911 }.into();
912 })
913 )
914 |
915 epsilon!()
916 ) >>
917 (e)
918 ));
919
David Tolnaybcf26022017-12-25 22:10:52 -0500920 // <or> ... <or> ..
921 // <or> .. <or> ..
922 // <or> ..
923 //
924 // NOTE: This is currently parsed oddly - I'm not sure of what the exact
925 // rules are for parsing these expressions are, but this is not correct.
926 // For example, `a .. b .. c` is not a legal expression. It should not
927 // be parsed as either `(a .. b) .. c` or `a .. (b .. c)` apparently.
928 //
929 // NOTE: The form of ranges which don't include a preceding expression are
930 // parsed by `atom_expr`, rather than by this function.
Michael Layzell734adb42017-06-07 16:58:31 -0400931 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500932 named!(range_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -0400933 mut e: call!(or_expr, allow_struct, allow_block) >>
934 many0!(do_parse!(
935 limits: syn!(RangeLimits) >>
936 // We don't want to allow blocks here if we don't allow structs. See
937 // the reasoning for `opt_ambiguous_expr!` above.
938 hi: option!(call!(or_expr, allow_struct, allow_struct)) >>
939 ({
940 e = ExprRange {
David Tolnay8c91b882017-12-28 23:04:32 -0500941 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -0400942 from: Some(Box::new(e.into())),
943 limits: limits,
944 to: hi.map(|e| Box::new(e.into())),
945 }.into();
946 })
947 )) >>
948 (e)
949 ));
950
David Tolnaybcf26022017-12-25 22:10:52 -0500951 // <and> || <and> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800952 binop!(or_expr, and_expr, map!(punct!(||), BinOp::Or));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400953
David Tolnaybcf26022017-12-25 22:10:52 -0500954 // <compare> && <compare> ...
David Tolnayf8db7ba2017-11-11 22:52:16 -0800955 binop!(and_expr, compare_expr, map!(punct!(&&), BinOp::And));
Michael Layzellb78f3b52017-06-04 19:03:03 -0400956
David Tolnaybcf26022017-12-25 22:10:52 -0500957 // <bitor> == <bitor> ...
958 // <bitor> != <bitor> ...
959 // <bitor> >= <bitor> ...
960 // <bitor> <= <bitor> ...
961 // <bitor> > <bitor> ...
962 // <bitor> < <bitor> ...
963 //
964 // NOTE: This operator appears to be parsed as left-associative, but errors
965 // if it is used in a non-associative manner.
David Tolnay51382052017-12-27 13:46:21 -0500966 binop!(
967 compare_expr,
968 bitor_expr,
969 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800970 punct!(==) => { BinOp::Eq }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400971 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800972 punct!(!=) => { BinOp::Ne }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400973 |
974 // must be above Lt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800975 punct!(<=) => { BinOp::Le }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400976 |
977 // must be above Gt
David Tolnayf8db7ba2017-11-11 22:52:16 -0800978 punct!(>=) => { BinOp::Ge }
Michael Layzellb78f3b52017-06-04 19:03:03 -0400979 |
Michael Layzell6a5a1642017-06-04 19:35:15 -0400980 do_parse!(
981 // Make sure that we don't eat the < part of a <- operator
David Tolnayf8db7ba2017-11-11 22:52:16 -0800982 not!(punct!(<-)) >>
983 t: punct!(<) >>
Michael Layzell6a5a1642017-06-04 19:35:15 -0400984 (BinOp::Lt(t))
985 )
Michael Layzellb78f3b52017-06-04 19:03:03 -0400986 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800987 punct!(>) => { BinOp::Gt }
David Tolnay51382052017-12-27 13:46:21 -0500988 )
989 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400990
David Tolnaybcf26022017-12-25 22:10:52 -0500991 // <bitxor> | <bitxor> ...
David Tolnay51382052017-12-27 13:46:21 -0500992 binop!(
993 bitor_expr,
994 bitxor_expr,
995 do_parse!(not!(punct!(||)) >> not!(punct!(|=)) >> t: punct!(|) >> (BinOp::BitOr(t)))
996 );
Michael Layzellb78f3b52017-06-04 19:03:03 -0400997
David Tolnaybcf26022017-12-25 22:10:52 -0500998 // <bitand> ^ <bitand> ...
David Tolnay51382052017-12-27 13:46:21 -0500999 binop!(
1000 bitxor_expr,
1001 bitand_expr,
1002 do_parse!(
1003 // NOTE: Make sure we aren't looking at ^=.
1004 not!(punct!(^=)) >> t: punct!(^) >> (BinOp::BitXor(t))
1005 )
1006 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001007
David Tolnaybcf26022017-12-25 22:10:52 -05001008 // <shift> & <shift> ...
David Tolnay51382052017-12-27 13:46:21 -05001009 binop!(
1010 bitand_expr,
1011 shift_expr,
1012 do_parse!(
1013 // NOTE: Make sure we aren't looking at && or &=.
1014 not!(punct!(&&)) >> not!(punct!(&=)) >> t: punct!(&) >> (BinOp::BitAnd(t))
1015 )
1016 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001017
David Tolnaybcf26022017-12-25 22:10:52 -05001018 // <arith> << <arith> ...
1019 // <arith> >> <arith> ...
David Tolnay51382052017-12-27 13:46:21 -05001020 binop!(
1021 shift_expr,
1022 arith_expr,
1023 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001024 punct!(<<) => { BinOp::Shl }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001025 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001026 punct!(>>) => { BinOp::Shr }
David Tolnay51382052017-12-27 13:46:21 -05001027 )
1028 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001029
David Tolnaybcf26022017-12-25 22:10:52 -05001030 // <term> + <term> ...
1031 // <term> - <term> ...
David Tolnay51382052017-12-27 13:46:21 -05001032 binop!(
1033 arith_expr,
1034 term_expr,
1035 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001036 punct!(+) => { BinOp::Add }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001037 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001038 punct!(-) => { BinOp::Sub }
David Tolnay51382052017-12-27 13:46:21 -05001039 )
1040 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001041
David Tolnaybcf26022017-12-25 22:10:52 -05001042 // <cast> * <cast> ...
1043 // <cast> / <cast> ...
1044 // <cast> % <cast> ...
David Tolnay51382052017-12-27 13:46:21 -05001045 binop!(
1046 term_expr,
1047 cast_expr,
1048 alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001049 punct!(*) => { BinOp::Mul }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001050 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001051 punct!(/) => { BinOp::Div }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001052 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001053 punct!(%) => { BinOp::Rem }
David Tolnay51382052017-12-27 13:46:21 -05001054 )
1055 );
Michael Layzellb78f3b52017-06-04 19:03:03 -04001056
David Tolnaybcf26022017-12-25 22:10:52 -05001057 // <unary> as <ty>
1058 // <unary> : <ty>
David Tolnay0cf94f22017-12-28 23:46:26 -05001059 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001060 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001061 mut e: call!(unary_expr, allow_struct, allow_block) >>
1062 many0!(alt!(
1063 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001064 as_: keyword!(as) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001065 // We can't accept `A + B` in cast expressions, as it's
1066 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001067 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001068 ({
1069 e = ExprCast {
David Tolnay8c91b882017-12-28 23:04:32 -05001070 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001071 expr: Box::new(e.into()),
1072 as_token: as_,
1073 ty: Box::new(ty),
1074 }.into();
1075 })
1076 )
1077 |
1078 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001079 colon: punct!(:) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001080 // We can't accept `A + B` in cast expressions, as it's
1081 // ambiguous with the + expression.
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001082 ty: call!(Type::without_plus) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001083 ({
1084 e = ExprType {
David Tolnay8c91b882017-12-28 23:04:32 -05001085 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001086 expr: Box::new(e.into()),
1087 colon_token: colon,
1088 ty: Box::new(ty),
1089 }.into();
1090 })
1091 )
1092 )) >>
1093 (e)
1094 ));
1095
David Tolnay0cf94f22017-12-28 23:46:26 -05001096 // <unary> as <ty>
1097 #[cfg(not(feature = "full"))]
1098 named!(cast_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
1099 mut e: call!(unary_expr, allow_struct, allow_block) >>
1100 many0!(do_parse!(
1101 as_: keyword!(as) >>
1102 // We can't accept `A + B` in cast expressions, as it's
1103 // ambiguous with the + expression.
1104 ty: call!(Type::without_plus) >>
1105 ({
1106 e = ExprCast {
1107 attrs: Vec::new(),
1108 expr: Box::new(e.into()),
1109 as_token: as_,
1110 ty: Box::new(ty),
1111 }.into();
1112 })
1113 )) >>
1114 (e)
1115 ));
1116
David Tolnaybcf26022017-12-25 22:10:52 -05001117 // <UnOp> <trailer>
1118 // & <trailer>
1119 // &mut <trailer>
1120 // box <trailer>
Michael Layzell734adb42017-06-07 16:58:31 -04001121 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001122 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001123 do_parse!(
1124 op: syn!(UnOp) >>
1125 expr: call!(unary_expr, allow_struct, true) >>
1126 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001127 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001128 op: op,
1129 expr: Box::new(expr.into()),
1130 }.into())
1131 )
1132 |
1133 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001134 and: punct!(&) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001135 mutability: syn!(Mutability) >>
1136 expr: call!(unary_expr, allow_struct, true) >>
1137 (ExprAddrOf {
David Tolnay8c91b882017-12-28 23:04:32 -05001138 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001139 and_token: and,
1140 mutbl: mutability,
1141 expr: Box::new(expr.into()),
1142 }.into())
1143 )
1144 |
1145 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001146 box_: keyword!(box) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001147 expr: call!(unary_expr, allow_struct, true) >>
1148 (ExprBox {
David Tolnay8c91b882017-12-28 23:04:32 -05001149 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001150 box_token: box_,
1151 expr: Box::new(expr.into()),
1152 }.into())
1153 )
1154 |
1155 call!(trailer_expr, allow_struct, allow_block)
1156 ));
1157
Michael Layzell734adb42017-06-07 16:58:31 -04001158 // XXX: This duplication is ugly
1159 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001160 named!(unary_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
Michael Layzell734adb42017-06-07 16:58:31 -04001161 do_parse!(
1162 op: syn!(UnOp) >>
1163 expr: call!(unary_expr, allow_struct, true) >>
1164 (ExprUnary {
David Tolnay8c91b882017-12-28 23:04:32 -05001165 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001166 op: op,
1167 expr: Box::new(expr.into()),
1168 }.into())
1169 )
1170 |
1171 call!(trailer_expr, allow_struct, allow_block)
1172 ));
1173
David Tolnaybcf26022017-12-25 22:10:52 -05001174 // <atom> (..<args>) ...
1175 // <atom> . <ident> (..<args>) ...
1176 // <atom> . <ident> ...
1177 // <atom> . <lit> ...
1178 // <atom> [ <expr> ] ...
1179 // <atom> ? ...
Michael Layzell734adb42017-06-07 16:58:31 -04001180 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001181 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzellb78f3b52017-06-04 19:03:03 -04001182 mut e: call!(atom_expr, allow_struct, allow_block) >>
1183 many0!(alt!(
1184 tap!(args: and_call => {
1185 let (args, paren) = args;
1186 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001187 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001188 func: Box::new(e.into()),
1189 args: args,
1190 paren_token: paren,
1191 }.into();
1192 })
1193 |
1194 tap!(more: and_method_call => {
1195 let mut call = more;
David Tolnay76418512017-12-28 23:47:47 -05001196 call.receiver = Box::new(e.into());
Michael Layzellb78f3b52017-06-04 19:03:03 -04001197 e = call.into();
1198 })
1199 |
1200 tap!(field: and_field => {
David Tolnay85b69a42017-12-27 20:43:10 -05001201 let (token, member) = field;
Michael Layzellb78f3b52017-06-04 19:03:03 -04001202 e = ExprField {
David Tolnay8c91b882017-12-28 23:04:32 -05001203 attrs: Vec::new(),
David Tolnay85b69a42017-12-27 20:43:10 -05001204 base: Box::new(e.into()),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001205 dot_token: token,
David Tolnay85b69a42017-12-27 20:43:10 -05001206 member: member,
Michael Layzellb78f3b52017-06-04 19:03:03 -04001207 }.into();
1208 })
1209 |
1210 tap!(i: and_index => {
1211 let (i, token) = i;
1212 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001213 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001214 expr: Box::new(e.into()),
1215 bracket_token: token,
1216 index: Box::new(i),
1217 }.into();
1218 })
1219 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001220 tap!(question: punct!(?) => {
Michael Layzellb78f3b52017-06-04 19:03:03 -04001221 e = ExprTry {
David Tolnay8c91b882017-12-28 23:04:32 -05001222 attrs: Vec::new(),
Michael Layzellb78f3b52017-06-04 19:03:03 -04001223 expr: Box::new(e.into()),
1224 question_token: question,
1225 }.into();
1226 })
1227 )) >>
1228 (e)
1229 ));
1230
Michael Layzell734adb42017-06-07 16:58:31 -04001231 // XXX: Duplication == ugly
1232 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001233 named!(trailer_expr(allow_struct: bool, allow_block: bool) -> Expr, do_parse!(
Michael Layzell734adb42017-06-07 16:58:31 -04001234 mut e: call!(atom_expr, allow_struct, allow_block) >>
1235 many0!(alt!(
1236 tap!(args: and_call => {
1237 let (args, paren) = args;
1238 e = ExprCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001239 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001240 func: Box::new(e.into()),
1241 args: args,
1242 paren_token: paren,
1243 }.into();
1244 })
1245 |
1246 tap!(i: and_index => {
1247 let (i, token) = i;
1248 e = ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -05001249 attrs: Vec::new(),
Michael Layzell734adb42017-06-07 16:58:31 -04001250 expr: Box::new(e.into()),
1251 bracket_token: token,
1252 index: Box::new(i),
1253 }.into();
1254 })
1255 )) >>
1256 (e)
1257 ));
1258
David Tolnaybcf26022017-12-25 22:10:52 -05001259 // Parse all atomic expressions which don't have to worry about precidence
1260 // interactions, as they are fully contained.
Michael Layzell734adb42017-06-07 16:58:31 -04001261 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001262 named!(atom_expr(allow_struct: bool, allow_block: bool) -> Expr, alt!(
1263 syn!(ExprGroup) => { Expr::Group } // must be placed first
Michael Layzell93c36282017-06-04 20:43:14 -04001264 |
David Tolnay8c91b882017-12-28 23:04:32 -05001265 syn!(ExprLit) => { Expr::Lit } // must be before expr_struct
Michael Layzellb78f3b52017-06-04 19:03:03 -04001266 |
1267 // must be before expr_path
David Tolnay8c91b882017-12-28 23:04:32 -05001268 cond_reduce!(allow_struct, map!(syn!(ExprStruct), Expr::Struct))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001269 |
David Tolnay8c91b882017-12-28 23:04:32 -05001270 syn!(ExprParen) => { Expr::Paren } // must be before expr_tup
Michael Layzellb78f3b52017-06-04 19:03:03 -04001271 |
David Tolnay8c91b882017-12-28 23:04:32 -05001272 syn!(ExprMacro) => { Expr::Macro } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001273 |
1274 call!(expr_break, allow_struct) // must be before expr_path
1275 |
David Tolnay8c91b882017-12-28 23:04:32 -05001276 syn!(ExprContinue) => { Expr::Continue } // must be before expr_path
Michael Layzellb78f3b52017-06-04 19:03:03 -04001277 |
1278 call!(expr_ret, allow_struct) // must be before expr_path
1279 |
David Tolnay8c91b882017-12-28 23:04:32 -05001280 syn!(ExprArray) => { Expr::Array }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001281 |
David Tolnay8c91b882017-12-28 23:04:32 -05001282 syn!(ExprTuple) => { Expr::Tuple }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001283 |
David Tolnay8c91b882017-12-28 23:04:32 -05001284 syn!(ExprIf) => { Expr::If }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001285 |
David Tolnay8c91b882017-12-28 23:04:32 -05001286 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001287 |
David Tolnay8c91b882017-12-28 23:04:32 -05001288 syn!(ExprWhile) => { Expr::While }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001289 |
David Tolnay8c91b882017-12-28 23:04:32 -05001290 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001291 |
David Tolnay8c91b882017-12-28 23:04:32 -05001292 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001293 |
David Tolnay8c91b882017-12-28 23:04:32 -05001294 syn!(ExprLoop) => { Expr::Loop }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001295 |
David Tolnay8c91b882017-12-28 23:04:32 -05001296 syn!(ExprMatch) => { Expr::Match }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001297 |
David Tolnay8c91b882017-12-28 23:04:32 -05001298 syn!(ExprCatch) => { Expr::Catch }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001299 |
David Tolnay8c91b882017-12-28 23:04:32 -05001300 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001301 |
David Tolnay8c91b882017-12-28 23:04:32 -05001302 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001303 |
Michael Layzellb78f3b52017-06-04 19:03:03 -04001304 call!(expr_closure, allow_struct)
1305 |
David Tolnay8c91b882017-12-28 23:04:32 -05001306 cond_reduce!(allow_block, map!(syn!(ExprBlock), Expr::Block))
Michael Layzellb78f3b52017-06-04 19:03:03 -04001307 |
1308 // NOTE: This is the prefix-form of range
1309 call!(expr_range, allow_struct)
1310 |
David Tolnay8c91b882017-12-28 23:04:32 -05001311 syn!(ExprPath) => { Expr::Path }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001312 |
David Tolnay8c91b882017-12-28 23:04:32 -05001313 syn!(ExprRepeat) => { Expr::Repeat }
Michael Layzellb78f3b52017-06-04 19:03:03 -04001314 ));
1315
Michael Layzell734adb42017-06-07 16:58:31 -04001316 #[cfg(not(feature = "full"))]
David Tolnay8c91b882017-12-28 23:04:32 -05001317 named!(atom_expr(_allow_struct: bool, _allow_block: bool) -> Expr, alt!(
David Tolnaye98775f2017-12-28 23:17:00 -05001318 syn!(ExprLit) => { Expr::Lit }
Michael Layzell734adb42017-06-07 16:58:31 -04001319 |
David Tolnay8c91b882017-12-28 23:04:32 -05001320 syn!(ExprPath) => { Expr::Path }
Michael Layzell734adb42017-06-07 16:58:31 -04001321 ));
1322
Michael Layzell734adb42017-06-07 16:58:31 -04001323 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04001324 named!(expr_nosemi -> Expr, map!(alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001325 syn!(ExprIf) => { Expr::If }
Michael Layzell35418782017-06-07 09:20:25 -04001326 |
David Tolnay8c91b882017-12-28 23:04:32 -05001327 syn!(ExprIfLet) => { Expr::IfLet }
Michael Layzell35418782017-06-07 09:20:25 -04001328 |
David Tolnay8c91b882017-12-28 23:04:32 -05001329 syn!(ExprWhile) => { Expr::While }
Michael Layzell35418782017-06-07 09:20:25 -04001330 |
David Tolnay8c91b882017-12-28 23:04:32 -05001331 syn!(ExprWhileLet) => { Expr::WhileLet }
Michael Layzell35418782017-06-07 09:20:25 -04001332 |
David Tolnay8c91b882017-12-28 23:04:32 -05001333 syn!(ExprForLoop) => { Expr::ForLoop }
Michael Layzell35418782017-06-07 09:20:25 -04001334 |
David Tolnay8c91b882017-12-28 23:04:32 -05001335 syn!(ExprLoop) => { Expr::Loop }
Michael Layzell35418782017-06-07 09:20:25 -04001336 |
David Tolnay8c91b882017-12-28 23:04:32 -05001337 syn!(ExprMatch) => { Expr::Match }
Michael Layzell35418782017-06-07 09:20:25 -04001338 |
David Tolnay8c91b882017-12-28 23:04:32 -05001339 syn!(ExprCatch) => { Expr::Catch }
Michael Layzell35418782017-06-07 09:20:25 -04001340 |
David Tolnay8c91b882017-12-28 23:04:32 -05001341 syn!(ExprYield) => { Expr::Yield }
Alex Crichtonfe110462017-06-01 12:49:27 -07001342 |
David Tolnay8c91b882017-12-28 23:04:32 -05001343 syn!(ExprUnsafe) => { Expr::Unsafe }
Nika Layzell640832a2017-12-04 13:37:09 -05001344 |
David Tolnay8c91b882017-12-28 23:04:32 -05001345 syn!(ExprBlock) => { Expr::Block }
Michael Layzell35418782017-06-07 09:20:25 -04001346 ), Expr::from));
1347
David Tolnay8c91b882017-12-28 23:04:32 -05001348 impl Synom for ExprLit {
1349 named!(parse -> Self, do_parse!(
1350 lit: syn!(Lit) >>
1351 (ExprLit {
1352 attrs: Vec::new(),
1353 lit: lit,
1354 })
1355 ));
1356 }
1357
1358 #[cfg(feature = "full")]
1359 impl Synom for ExprMacro {
1360 named!(parse -> Self, do_parse!(
1361 mac: syn!(Macro) >>
1362 (ExprMacro {
1363 attrs: Vec::new(),
1364 mac: mac,
1365 })
1366 ));
1367 }
1368
David Tolnaye98775f2017-12-28 23:17:00 -05001369 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04001370 impl Synom for ExprGroup {
1371 named!(parse -> Self, do_parse!(
1372 e: grouped!(syn!(Expr)) >>
1373 (ExprGroup {
David Tolnay8c91b882017-12-28 23:04:32 -05001374 attrs: Vec::new(),
Michael Layzell93c36282017-06-04 20:43:14 -04001375 expr: Box::new(e.0),
1376 group_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001377 })
Michael Layzell93c36282017-06-04 20:43:14 -04001378 ));
1379 }
1380
David Tolnaye98775f2017-12-28 23:17:00 -05001381 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001382 impl Synom for ExprParen {
Michael Layzell92639a52017-06-01 00:07:44 -04001383 named!(parse -> Self, do_parse!(
1384 e: parens!(syn!(Expr)) >>
1385 (ExprParen {
David Tolnay8c91b882017-12-28 23:04:32 -05001386 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001387 expr: Box::new(e.0),
1388 paren_token: e.1,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001389 })
Michael Layzell92639a52017-06-01 00:07:44 -04001390 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001391 }
David Tolnay89e05672016-10-02 14:39:42 -07001392
Michael Layzell734adb42017-06-07 16:58:31 -04001393 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001394 impl Synom for ExprArray {
Michael Layzell92639a52017-06-01 00:07:44 -04001395 named!(parse -> Self, do_parse!(
1396 elems: brackets!(call!(Delimited::parse_terminated)) >>
1397 (ExprArray {
David Tolnay8c91b882017-12-28 23:04:32 -05001398 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001399 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001400 bracket_token: elems.1,
1401 })
1402 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001403 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001404
David Tolnay32954ef2017-12-26 22:43:16 -05001405 named!(and_call -> (Delimited<Expr, Token![,]>, token::Paren),
Alex Crichton954046c2017-05-30 21:49:42 -07001406 parens!(call!(Delimited::parse_terminated)));
David Tolnayfa0edf22016-09-23 22:58:24 -07001407
Michael Layzell734adb42017-06-07 16:58:31 -04001408 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001409 named!(and_method_call -> ExprMethodCall, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001410 dot: punct!(.) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001411 method: syn!(Ident) >>
David Tolnayd60cfec2017-12-29 00:21:38 -05001412 turbofish: option!(tuple!(
1413 punct!(::),
1414 punct!(<),
1415 call!(Delimited::parse_terminated),
1416 punct!(>)
David Tolnayfa0edf22016-09-23 22:58:24 -07001417 )) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001418 args: parens!(call!(Delimited::parse_terminated)) >>
1419 ({
Alex Crichton954046c2017-05-30 21:49:42 -07001420 ExprMethodCall {
David Tolnay8c91b882017-12-28 23:04:32 -05001421 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001422 // this expr will get overwritten after being returned
David Tolnay76418512017-12-28 23:47:47 -05001423 receiver: Box::new(Expr::Lit(ExprLit {
David Tolnay8c91b882017-12-28 23:04:32 -05001424 attrs: Vec::new(),
1425 lit: Lit {
1426 span: Span::default(),
1427 value: LitKind::Bool(false),
1428 },
Alex Crichton954046c2017-05-30 21:49:42 -07001429 }).into()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001430
Alex Crichton954046c2017-05-30 21:49:42 -07001431 method: method,
David Tolnayd60cfec2017-12-29 00:21:38 -05001432 turbofish: turbofish.map(|fish| MethodTurbofish {
1433 colon2_token: fish.0,
1434 lt_token: fish.1,
1435 args: fish.2,
1436 gt_token: fish.3,
1437 }),
Alex Crichton954046c2017-05-30 21:49:42 -07001438 args: args.0,
1439 paren_token: args.1,
1440 dot_token: dot,
Alex Crichton954046c2017-05-30 21:49:42 -07001441 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001442 })
David Tolnayfa0edf22016-09-23 22:58:24 -07001443 ));
1444
Michael Layzell734adb42017-06-07 16:58:31 -04001445 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05001446 impl Synom for GenericMethodArgument {
1447 // TODO parse const generics as well
1448 named!(parse -> Self, map!(ty_no_eq_after, GenericMethodArgument::Type));
1449 }
1450
1451 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05001452 impl Synom for ExprTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04001453 named!(parse -> Self, do_parse!(
1454 elems: parens!(call!(Delimited::parse_terminated)) >>
David Tolnay05362582017-12-26 01:33:57 -05001455 (ExprTuple {
David Tolnay8c91b882017-12-28 23:04:32 -05001456 attrs: Vec::new(),
David Tolnay2a86fdd2017-12-28 23:34:28 -05001457 elems: elems.0,
Michael Layzell92639a52017-06-01 00:07:44 -04001458 paren_token: elems.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001459 })
1460 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001461 }
David Tolnayfa0edf22016-09-23 22:58:24 -07001462
Michael Layzell734adb42017-06-07 16:58:31 -04001463 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001464 impl Synom for ExprIfLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001465 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001466 if_: keyword!(if) >>
1467 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001468 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001469 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001470 cond: expr_no_struct >>
1471 then_block: braces!(call!(Block::parse_within)) >>
1472 else_block: option!(else_block) >>
1473 (ExprIfLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001474 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001475 pat: Box::new(pat),
1476 let_token: let_,
1477 eq_token: eq,
1478 expr: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001479 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001480 stmts: then_block.0,
1481 brace_token: then_block.1,
1482 },
1483 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001484 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001485 })
1486 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001487 }
1488
Michael Layzell734adb42017-06-07 16:58:31 -04001489 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001490 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001491 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001492 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001493 cond: expr_no_struct >>
1494 then_block: braces!(call!(Block::parse_within)) >>
1495 else_block: option!(else_block) >>
1496 (ExprIf {
David Tolnay8c91b882017-12-28 23:04:32 -05001497 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001498 cond: Box::new(cond),
David Tolnay2ccf32a2017-12-29 00:34:26 -05001499 then_branch: Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001500 stmts: then_block.0,
1501 brace_token: then_block.1,
1502 },
1503 if_token: if_,
David Tolnay2ccf32a2017-12-29 00:34:26 -05001504 else_branch: else_block,
Michael Layzell92639a52017-06-01 00:07:44 -04001505 })
1506 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001507 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001508
Michael Layzell734adb42017-06-07 16:58:31 -04001509 #[cfg(feature = "full")]
David Tolnay2ccf32a2017-12-29 00:34:26 -05001510 named!(else_block -> (Token![else], Box<Expr>), do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001511 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001512 expr: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001513 syn!(ExprIf) => { Expr::If }
Alex Crichton954046c2017-05-30 21:49:42 -07001514 |
David Tolnay8c91b882017-12-28 23:04:32 -05001515 syn!(ExprIfLet) => { Expr::IfLet }
Alex Crichton954046c2017-05-30 21:49:42 -07001516 |
1517 do_parse!(
1518 else_block: braces!(call!(Block::parse_within)) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001519 (Expr::Block(ExprBlock {
1520 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001521 block: Block {
1522 stmts: else_block.0,
1523 brace_token: else_block.1,
1524 },
1525 }))
David Tolnay939766a2016-09-23 23:48:12 -07001526 )
Alex Crichton954046c2017-05-30 21:49:42 -07001527 ) >>
David Tolnay2ccf32a2017-12-29 00:34:26 -05001528 (else_, Box::new(expr))
David Tolnay939766a2016-09-23 23:48:12 -07001529 ));
1530
Michael Layzell734adb42017-06-07 16:58:31 -04001531 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001532 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001533 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001534 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1535 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001536 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001537 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001538 expr: expr_no_struct >>
1539 loop_block: syn!(Block) >>
1540 (ExprForLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001541 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001542 for_token: for_,
1543 in_token: in_,
1544 pat: Box::new(pat),
1545 expr: Box::new(expr),
1546 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001547 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001548 label: lbl.map(|p| p.0),
1549 })
1550 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001551 }
Gregory Katze5f35682016-09-27 14:20:55 -04001552
Michael Layzell734adb42017-06-07 16:58:31 -04001553 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001554 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001555 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001556 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1557 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001558 loop_block: syn!(Block) >>
1559 (ExprLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001560 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001561 loop_token: loop_,
1562 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001563 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001564 label: lbl.map(|p| p.0),
1565 })
1566 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001567 }
1568
Michael Layzell734adb42017-06-07 16:58:31 -04001569 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001570 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001571 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001572 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001573 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001574 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001575 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001576 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001577 ExprMatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001578 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001579 expr: Box::new(obj),
1580 match_token: match_,
1581 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001582 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001583 }
1584 })
1585 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001586 }
David Tolnay1978c672016-10-27 22:05:52 -07001587
Michael Layzell734adb42017-06-07 16:58:31 -04001588 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001589 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001590 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001591 do_: keyword!(do) >>
1592 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001593 catch_block: syn!(Block) >>
1594 (ExprCatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001595 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001596 block: catch_block,
1597 do_token: do_,
1598 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001599 })
Michael Layzell92639a52017-06-01 00:07:44 -04001600 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001601 }
Arnavion02ef13f2017-04-25 00:54:31 -07001602
Michael Layzell734adb42017-06-07 16:58:31 -04001603 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001604 impl Synom for ExprYield {
1605 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001606 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001607 expr: option!(syn!(Expr)) >>
1608 (ExprYield {
David Tolnay8c91b882017-12-28 23:04:32 -05001609 attrs: Vec::new(),
Alex Crichtonfe110462017-06-01 12:49:27 -07001610 yield_token: yield_,
1611 expr: expr.map(Box::new),
1612 })
1613 ));
1614 }
1615
1616 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001617 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001618 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001619 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001620 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001621 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1622 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001623 body: do_parse!(
1624 expr: alt!(expr_nosemi | syn!(Expr)) >>
1625 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1626 map!(input_end!(), |_| None)
1627 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001628 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001629 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001630 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001631 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001632 ) >>
1633 (Arm {
1634 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001635 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001636 attrs: attrs,
1637 pats: pats,
1638 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001639 body: Box::new(body.0),
1640 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001641 })
1642 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001643 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001644
Michael Layzell734adb42017-06-07 16:58:31 -04001645 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001646 named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001647 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001648 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001649 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001650 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001651 ret_and_body: alt!(
1652 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001653 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001654 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001655 body: syn!(Block) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -05001656 (ReturnType::Type(arrow, Box::new(ty)),
David Tolnay8c91b882017-12-28 23:04:32 -05001657 Expr::Block(ExprBlock {
1658 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001659 block: body,
1660 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001661 )
1662 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001663 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001664 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001665 (ExprClosure {
David Tolnay8c91b882017-12-28 23:04:32 -05001666 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001667 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001668 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001669 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001670 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001671 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001672 body: Box::new(ret_and_body.1),
1673 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001674 ));
1675
Michael Layzell734adb42017-06-07 16:58:31 -04001676 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001677 named!(fn_arg -> FnArg, do_parse!(
1678 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001679 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001680 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001681 if let Some((colon, ty)) = ty {
1682 FnArg::Captured(ArgCaptured {
1683 pat: pat,
1684 colon_token: colon,
1685 ty: ty,
1686 })
1687 } else {
1688 FnArg::Inferred(pat)
1689 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001690 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001691 ));
1692
Michael Layzell734adb42017-06-07 16:58:31 -04001693 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001694 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001695 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001696 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1697 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001698 cond: expr_no_struct >>
1699 while_block: syn!(Block) >>
1700 (ExprWhile {
David Tolnay8c91b882017-12-28 23:04:32 -05001701 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001702 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001703 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001704 cond: Box::new(cond),
1705 body: while_block,
1706 label: lbl.map(|p| p.0),
1707 })
1708 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001709 }
1710
Michael Layzell734adb42017-06-07 16:58:31 -04001711 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001712 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001713 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001714 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1715 while_: keyword!(while) >>
1716 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001717 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001718 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001719 value: expr_no_struct >>
1720 while_block: syn!(Block) >>
1721 (ExprWhileLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001722 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001723 eq_token: eq,
1724 let_token: let_,
1725 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001726 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001727 pat: Box::new(pat),
1728 expr: Box::new(value),
1729 body: while_block,
1730 label: lbl.map(|p| p.0),
1731 })
1732 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001733 }
1734
Michael Layzell734adb42017-06-07 16:58:31 -04001735 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001736 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001737 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001738 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001739 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001740 (ExprContinue {
David Tolnay8c91b882017-12-28 23:04:32 -05001741 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001742 continue_token: cont,
1743 label: lbl,
1744 })
1745 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001746 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001747
Michael Layzell734adb42017-06-07 16:58:31 -04001748 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001749 named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001750 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001751 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001752 // We can't allow blocks after a `break` expression when we wouldn't
1753 // allow structs, as this expression is ambiguous.
1754 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001755 (ExprBreak {
David Tolnay8c91b882017-12-28 23:04:32 -05001756 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001757 label: lbl,
1758 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001759 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001760 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001761 ));
1762
Michael Layzell734adb42017-06-07 16:58:31 -04001763 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001764 named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001765 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001766 // NOTE: return is greedy and eats blocks after it even when in a
1767 // position where structs are not allowed, such as in if statement
1768 // conditions. For example:
1769 //
David Tolnaybcf26022017-12-25 22:10:52 -05001770 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001771 ret_value: option!(ambiguous_expr!(allow_struct)) >>
David Tolnayc246cd32017-12-28 23:14:32 -05001772 (ExprReturn {
David Tolnay8c91b882017-12-28 23:04:32 -05001773 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001774 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001775 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001776 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001777 ));
1778
Michael Layzell734adb42017-06-07 16:58:31 -04001779 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001780 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001781 named!(parse -> Self, do_parse!(
1782 path: syn!(Path) >>
1783 data: braces!(do_parse!(
1784 fields: call!(Delimited::parse_terminated) >>
1785 base: option!(
1786 cond!(fields.is_empty() || fields.trailing_delim(),
1787 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001788 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001789 base: syn!(Expr) >>
1790 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001791 )
Michael Layzell92639a52017-06-01 00:07:44 -04001792 )
1793 ) >>
1794 (fields, base)
1795 )) >>
1796 ({
1797 let ((fields, base), brace) = data;
1798 let (dots, rest) = match base.and_then(|b| b) {
1799 Some((dots, base)) => (Some(dots), Some(base)),
1800 None => (None, None),
1801 };
1802 ExprStruct {
David Tolnay8c91b882017-12-28 23:04:32 -05001803 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001804 brace_token: brace,
1805 path: path,
1806 fields: fields,
1807 dot2_token: dots,
1808 rest: rest.map(Box::new),
1809 }
1810 })
1811 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001812 }
1813
Michael Layzell734adb42017-06-07 16:58:31 -04001814 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001815 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001816 named!(parse -> Self, alt!(
1817 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001818 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001819 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001820 value: syn!(Expr) >>
1821 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001822 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001823 expr: value,
1824 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001825 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001826 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001827 })
Michael Layzell92639a52017-06-01 00:07:44 -04001828 )
1829 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001830 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001831 member: Member::Named(name),
David Tolnay8c91b882017-12-28 23:04:32 -05001832 expr: Expr::Path(ExprPath {
1833 attrs: Vec::new(),
1834 qself: None,
1835 path: name.into(),
1836 }).into(),
Michael Layzell92639a52017-06-01 00:07:44 -04001837 is_shorthand: true,
1838 attrs: Vec::new(),
1839 colon_token: None,
1840 })
1841 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001842 }
David Tolnay055a7042016-10-02 19:23:54 -07001843
Michael Layzell734adb42017-06-07 16:58:31 -04001844 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001845 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001846 named!(parse -> Self, do_parse!(
1847 data: brackets!(do_parse!(
1848 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001849 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001850 times: syn!(Expr) >>
1851 (value, semi, times)
1852 )) >>
1853 (ExprRepeat {
David Tolnay8c91b882017-12-28 23:04:32 -05001854 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001855 expr: Box::new((data.0).0),
1856 amt: Box::new((data.0).2),
1857 bracket_token: data.1,
1858 semi_token: (data.0).1,
1859 })
1860 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001861 }
David Tolnay055a7042016-10-02 19:23:54 -07001862
Michael Layzell734adb42017-06-07 16:58:31 -04001863 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001864 impl Synom for ExprUnsafe {
1865 named!(parse -> Self, do_parse!(
1866 unsafe_: keyword!(unsafe) >>
1867 b: syn!(Block) >>
1868 (ExprUnsafe {
David Tolnay8c91b882017-12-28 23:04:32 -05001869 attrs: Vec::new(),
Nika Layzell640832a2017-12-04 13:37:09 -05001870 unsafe_token: unsafe_,
1871 block: b,
1872 })
1873 ));
1874 }
1875
1876 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001877 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001878 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001879 b: syn!(Block) >>
1880 (ExprBlock {
David Tolnay8c91b882017-12-28 23:04:32 -05001881 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001882 block: b,
1883 })
1884 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001885 }
David Tolnay89e05672016-10-02 14:39:42 -07001886
Michael Layzell734adb42017-06-07 16:58:31 -04001887 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001888 named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001889 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001890 hi: opt_ambiguous_expr!(allow_struct) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001891 (ExprRange {
1892 attrs: Vec::new(),
1893 from: None,
1894 to: hi.map(Box::new),
1895 limits: limits,
1896 }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001897 ));
1898
Michael Layzell734adb42017-06-07 16:58:31 -04001899 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001900 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001901 named!(parse -> Self, alt!(
1902 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001903 punct!(..=) => { RangeLimits::Closed }
1904 |
1905 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001906 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001907 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001908 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001909 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001910 }
David Tolnay438c9052016-10-07 23:24:48 -07001911
Alex Crichton954046c2017-05-30 21:49:42 -07001912 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001913 named!(parse -> Self, do_parse!(
1914 pair: qpath >>
1915 (ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -05001916 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001917 qself: pair.0,
1918 path: pair.1,
1919 })
1920 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001921 }
David Tolnay42602292016-10-01 22:25:45 -07001922
Michael Layzell734adb42017-06-07 16:58:31 -04001923 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001924 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001925
David Tolnay32954ef2017-12-26 22:43:16 -05001926 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001927
Michael Layzell734adb42017-06-07 16:58:31 -04001928 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001929 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001930 named!(parse -> Self, do_parse!(
1931 stmts: braces!(call!(Block::parse_within)) >>
1932 (Block {
1933 stmts: stmts.0,
1934 brace_token: stmts.1,
1935 })
1936 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001937 }
David Tolnay939766a2016-09-23 23:48:12 -07001938
Michael Layzell734adb42017-06-07 16:58:31 -04001939 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001940 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001941 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001942 many0!(punct!(;)) >>
1943 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001944 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001945 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001946 mut e: syn!(Expr) >>
1947 ({
David Tolnay8c91b882017-12-28 23:04:32 -05001948 *e.attrs_mut() = attrs;
Alex Crichton70bbd592017-08-27 10:40:03 -07001949 Stmt::Expr(Box::new(e))
1950 })
1951 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001952 (match last {
1953 None => standalone,
1954 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001955 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001956 standalone
1957 }
1958 })
1959 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001960 }
1961
Michael Layzell734adb42017-06-07 16:58:31 -04001962 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001963 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001964 named!(parse -> Self, alt!(
1965 stmt_mac
1966 |
1967 stmt_local
1968 |
1969 stmt_item
1970 |
Michael Layzell35418782017-06-07 09:20:25 -04001971 stmt_blockexpr
1972 |
Michael Layzell92639a52017-06-01 00:07:44 -04001973 stmt_expr
1974 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001975 }
David Tolnay939766a2016-09-23 23:48:12 -07001976
Michael Layzell734adb42017-06-07 16:58:31 -04001977 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001978 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001979 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001980 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001981 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001982 // Only parse braces here; paren and bracket will get parsed as
1983 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001984 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001985 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05001986 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
1987 attrs: attrs,
1988 ident: None,
1989 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001990 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001991 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001992 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001993 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001994 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001995 },
David Tolnayeea28d62016-10-25 20:44:08 -07001996 },
David Tolnay57b52bc2017-12-28 18:06:38 -05001997 semi_token: semi,
1998 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07001999 ));
2000
Michael Layzell734adb42017-06-07 16:58:31 -04002001 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002002 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002003 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002004 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002005 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002006 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002007 init: option!(tuple!(punct!(=), syn!(Expr))) >>
2008 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07002009 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07002010 let_token: let_,
2011 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002012 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
2013 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07002014 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002015 ty: ty.map(|p| Box::new(p.1)),
2016 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07002017 attrs: attrs,
2018 })))
2019 ));
2020
Michael Layzell734adb42017-06-07 16:58:31 -04002021 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002022 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07002023
Michael Layzell734adb42017-06-07 16:58:31 -04002024 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04002025 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002026 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04002027 mut e: expr_nosemi >>
2028 // If the next token is a `.` or a `?` it is special-cased to parse as
2029 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08002030 not!(punct!(.)) >>
2031 not!(punct!(?)) >>
2032 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04002033 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002034 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002035 if let Some(semi) = semi {
2036 Stmt::Semi(Box::new(e), semi)
2037 } else {
2038 Stmt::Expr(Box::new(e))
2039 }
2040 })
2041 ));
David Tolnaycfe55022016-10-02 22:02:27 -07002042
Michael Layzell734adb42017-06-07 16:58:31 -04002043 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07002044 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002045 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002046 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002047 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07002048 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002049 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002050 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07002051 })
David Tolnay939766a2016-09-23 23:48:12 -07002052 ));
David Tolnay8b07f372016-09-30 10:28:40 -07002053
Michael Layzell734adb42017-06-07 16:58:31 -04002054 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002055 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04002056 named!(parse -> Self, alt!(
2057 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
2058 |
2059 syn!(PatBox) => { Pat::Box } // must be before pat_ident
2060 |
2061 syn!(PatRange) => { Pat::Range } // must be before pat_lit
2062 |
2063 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
2064 |
2065 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
2066 |
David Tolnaydecf28d2017-11-11 11:56:45 -08002067 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04002068 |
2069 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
2070 |
2071 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
2072 |
2073 syn!(PatPath) => { Pat::Path }
2074 |
2075 syn!(PatTuple) => { Pat::Tuple }
2076 |
2077 syn!(PatRef) => { Pat::Ref }
2078 |
2079 syn!(PatSlice) => { Pat::Slice }
2080 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002081 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002082
Michael Layzell734adb42017-06-07 16:58:31 -04002083 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002084 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04002085 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002086 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04002087 |u| PatWild { underscore_token: u }
2088 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002089 }
David Tolnay84aa0752016-10-02 23:01:13 -07002090
Michael Layzell734adb42017-06-07 16:58:31 -04002091 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002092 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04002093 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002094 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002095 pat: syn!(Pat) >>
2096 (PatBox {
2097 pat: Box::new(pat),
2098 box_token: boxed,
2099 })
2100 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002101 }
2102
Michael Layzell734adb42017-06-07 16:58:31 -04002103 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002104 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04002105 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002106 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002107 mutability: syn!(Mutability) >>
2108 name: alt!(
2109 syn!(Ident)
2110 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08002111 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04002112 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002113 not!(punct!(<)) >>
2114 not!(punct!(::)) >>
2115 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002116 (PatIdent {
2117 mode: match mode {
2118 Some(mode) => BindingMode::ByRef(mode, mutability),
2119 None => BindingMode::ByValue(mutability),
2120 },
2121 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002122 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002123 subpat: subpat.map(|p| Box::new(p.1)),
2124 })
2125 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002126 }
2127
Michael Layzell734adb42017-06-07 16:58:31 -04002128 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002129 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002130 named!(parse -> Self, do_parse!(
2131 path: syn!(Path) >>
2132 tuple: syn!(PatTuple) >>
2133 (PatTupleStruct {
2134 path: path,
2135 pat: tuple,
2136 })
2137 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002138 }
2139
Michael Layzell734adb42017-06-07 16:58:31 -04002140 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002141 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002142 named!(parse -> Self, do_parse!(
2143 path: syn!(Path) >>
2144 data: braces!(do_parse!(
2145 fields: call!(Delimited::parse_terminated) >>
2146 base: option!(
2147 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002148 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002149 ) >>
2150 (fields, base)
2151 )) >>
2152 (PatStruct {
2153 path: path,
2154 fields: (data.0).0,
2155 brace_token: data.1,
2156 dot2_token: (data.0).1.and_then(|m| m),
2157 })
2158 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002159 }
2160
Michael Layzell734adb42017-06-07 16:58:31 -04002161 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002162 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002163 named!(parse -> Self, alt!(
2164 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002165 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002166 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002167 pat: syn!(Pat) >>
2168 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002169 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002170 pat: Box::new(pat),
2171 is_shorthand: false,
2172 attrs: Vec::new(),
2173 colon_token: Some(colon),
2174 })
2175 )
2176 |
2177 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002178 boxed: option!(keyword!(box)) >>
2179 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002180 mutability: syn!(Mutability) >>
2181 ident: syn!(Ident) >>
2182 ({
2183 let mut pat: Pat = PatIdent {
2184 mode: if let Some(mode) = mode {
2185 BindingMode::ByRef(mode, mutability)
2186 } else {
2187 BindingMode::ByValue(mutability)
2188 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002189 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002190 subpat: None,
2191 at_token: None,
2192 }.into();
2193 if let Some(boxed) = boxed {
2194 pat = PatBox {
2195 pat: Box::new(pat),
2196 box_token: boxed,
2197 }.into();
2198 }
2199 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002200 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002201 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002202 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002203 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002204 colon_token: None,
2205 }
2206 })
2207 )
2208 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002209 }
2210
Michael Layzell734adb42017-06-07 16:58:31 -04002211 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002212 impl Synom for Member {
2213 named!(parse -> Self, alt!(
2214 syn!(Ident) => { Member::Named }
2215 |
2216 syn!(Index) => { Member::Unnamed }
2217 ));
2218 }
2219
2220 #[cfg(feature = "full")]
2221 impl Synom for Index {
2222 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002223 lit: syn!(Lit) >>
2224 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002225 if let Ok(i) = lit.value.to_string().parse() {
2226 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002227 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002228 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002229 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002230 })
David Tolnay85b69a42017-12-27 20:43:10 -05002231 ));
2232 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002233
Michael Layzell734adb42017-06-07 16:58:31 -04002234 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002235 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002236 named!(parse -> Self, map!(
2237 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002238 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002239 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002240 }
David Tolnay9636c052016-10-02 17:11:17 -07002241
Michael Layzell734adb42017-06-07 16:58:31 -04002242 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002243 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002244 named!(parse -> Self, do_parse!(
2245 data: parens!(do_parse!(
2246 elems: call!(Delimited::parse_terminated) >>
2247 dotdot: map!(cond!(
2248 elems.is_empty() || elems.trailing_delim(),
2249 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002250 dots: punct!(..) >>
2251 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002252 (dots, trailing)
2253 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002254 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002255 rest: cond!(match dotdot {
2256 Some((_, Some(_))) => true,
2257 _ => false,
2258 },
2259 call!(Delimited::parse_terminated)) >>
2260 (elems, dotdot, rest)
2261 )) >>
2262 ({
2263 let ((mut elems, dotdot, rest), parens) = data;
2264 let (dotdot, trailing) = match dotdot {
2265 Some((a, b)) => (Some(a), Some(b)),
2266 None => (None, None),
2267 };
2268 PatTuple {
2269 paren_token: parens,
2270 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2271 dot2_token: dotdot,
2272 comma_token: trailing.and_then(|b| b),
2273 pats: {
2274 if let Some(rest) = rest {
2275 for elem in rest {
2276 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002277 }
Michael Layzell92639a52017-06-01 00:07:44 -04002278 }
2279 elems
2280 },
2281 }
2282 })
2283 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002284 }
David Tolnayfbb73232016-10-03 01:00:06 -07002285
Michael Layzell734adb42017-06-07 16:58:31 -04002286 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002287 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002288 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002289 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002290 mutability: syn!(Mutability) >>
2291 pat: syn!(Pat) >>
2292 (PatRef {
2293 pat: Box::new(pat),
2294 mutbl: mutability,
2295 and_token: and,
2296 })
2297 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002298 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002299
Michael Layzell734adb42017-06-07 16:58:31 -04002300 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002301 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002302 named!(parse -> Self, do_parse!(
2303 lit: pat_lit_expr >>
David Tolnay8c91b882017-12-28 23:04:32 -05002304 (if let Expr::Path(_) = lit {
Michael Layzell92639a52017-06-01 00:07:44 -04002305 return parse_error(); // these need to be parsed by pat_path
2306 } else {
2307 PatLit {
2308 expr: Box::new(lit),
2309 }
2310 })
2311 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002312 }
David Tolnaye1310902016-10-29 23:40:00 -07002313
Michael Layzell734adb42017-06-07 16:58:31 -04002314 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002315 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002316 named!(parse -> Self, do_parse!(
2317 lo: pat_lit_expr >>
2318 limits: syn!(RangeLimits) >>
2319 hi: pat_lit_expr >>
2320 (PatRange {
2321 lo: Box::new(lo),
2322 hi: Box::new(hi),
2323 limits: limits,
2324 })
2325 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002326 }
David Tolnaye1310902016-10-29 23:40:00 -07002327
Michael Layzell734adb42017-06-07 16:58:31 -04002328 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002329 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002330 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002331 v: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05002332 syn!(ExprLit) => { Expr::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002333 |
David Tolnay8c91b882017-12-28 23:04:32 -05002334 syn!(ExprPath) => { Expr::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002335 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002336 (if let Some(neg) = neg {
David Tolnay8c91b882017-12-28 23:04:32 -05002337 Expr::Unary(ExprUnary {
2338 attrs: Vec::new(),
David Tolnayc29b9892017-12-27 22:58:14 -05002339 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002340 expr: Box::new(v.into())
2341 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002342 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002343 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002344 })
2345 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002346
Michael Layzell734adb42017-06-07 16:58:31 -04002347 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002348 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002349 named!(parse -> Self, map!(
2350 brackets!(do_parse!(
2351 before: call!(Delimited::parse_terminated) >>
2352 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002353 dots: punct!(..) >>
2354 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002355 (dots, trailing)
2356 )) >>
2357 after: cond!(
2358 match middle {
2359 Some((_, ref trailing)) => trailing.is_some(),
2360 _ => false,
2361 },
2362 call!(Delimited::parse_terminated)
2363 ) >>
2364 (before, middle, after)
2365 )),
2366 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002367 let mut before: Delimited<Pat, Token![,]> = before;
2368 let after: Option<Delimited<Pat, Token![,]>> = after;
2369 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002370 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002371 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002372 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002373 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002374 }),
2375 bracket_token: brackets,
2376 middle: middle.and_then(|_| {
2377 if !before.is_empty() && !before.trailing_delim() {
2378 Some(Box::new(before.pop().unwrap().into_item()))
2379 } else {
2380 None
2381 }
2382 }),
2383 front: before,
2384 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002385 }
Alex Crichton954046c2017-05-30 21:49:42 -07002386 }
Michael Layzell92639a52017-06-01 00:07:44 -04002387 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002388 }
David Tolnay435a9a82016-10-29 13:47:20 -07002389
Michael Layzell734adb42017-06-07 16:58:31 -04002390 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002391 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002392 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002393 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002394 |
2395 epsilon!() => { |_| CaptureBy::Ref }
2396 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002397 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002398}
2399
David Tolnayf4bbbd92016-09-23 14:41:55 -07002400#[cfg(feature = "printing")]
2401mod printing {
2402 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002403 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002404 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002405 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002406 #[cfg(feature = "full")]
2407 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002408
David Tolnaybcf26022017-12-25 22:10:52 -05002409 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2410 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002411 #[cfg(feature = "full")]
2412 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
David Tolnay8c91b882017-12-28 23:04:32 -05002413 if let Expr::Struct(_) = *e {
David Tolnay32954ef2017-12-26 22:43:16 -05002414 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002415 e.to_tokens(tokens);
2416 });
2417 } else {
2418 e.to_tokens(tokens);
2419 }
2420 }
2421
David Tolnay8c91b882017-12-28 23:04:32 -05002422 #[cfg(feature = "full")]
2423 fn attrs_to_tokens(attrs: &[Attribute], tokens: &mut Tokens) {
2424 tokens.append_all(attrs.outer());
2425 }
Michael Layzell734adb42017-06-07 16:58:31 -04002426
David Tolnay8c91b882017-12-28 23:04:32 -05002427 #[cfg(not(feature = "full"))]
2428 fn attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002429 }
2430
Michael Layzell734adb42017-06-07 16:58:31 -04002431 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002432 impl ToTokens for ExprBox {
2433 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002434 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002435 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002436 self.expr.to_tokens(tokens);
2437 }
2438 }
2439
Michael Layzell734adb42017-06-07 16:58:31 -04002440 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002441 impl ToTokens for ExprInPlace {
2442 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002443 tokens.append_all(self.attrs.outer());
David Tolnay8701a5c2017-12-28 23:31:10 -05002444 self.place.to_tokens(tokens);
2445 self.arrow_token.to_tokens(tokens);
2446 self.value.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002447 }
2448 }
2449
Michael Layzell734adb42017-06-07 16:58:31 -04002450 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002451 impl ToTokens for ExprArray {
2452 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002453 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002454 self.bracket_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002455 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002456 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002457 }
2458 }
2459
2460 impl ToTokens for ExprCall {
2461 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002462 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002463 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002464 self.paren_token.surround(tokens, |tokens| {
2465 self.args.to_tokens(tokens);
2466 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002467 }
2468 }
2469
Michael Layzell734adb42017-06-07 16:58:31 -04002470 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002471 impl ToTokens for ExprMethodCall {
2472 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002473 tokens.append_all(self.attrs.outer());
David Tolnay76418512017-12-28 23:47:47 -05002474 self.receiver.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002475 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002476 self.method.to_tokens(tokens);
David Tolnayd60cfec2017-12-29 00:21:38 -05002477 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002478 self.paren_token.surround(tokens, |tokens| {
2479 self.args.to_tokens(tokens);
2480 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002481 }
2482 }
2483
Michael Layzell734adb42017-06-07 16:58:31 -04002484 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05002485 impl ToTokens for MethodTurbofish {
2486 fn to_tokens(&self, tokens: &mut Tokens) {
2487 self.colon2_token.to_tokens(tokens);
2488 self.lt_token.to_tokens(tokens);
2489 self.args.to_tokens(tokens);
2490 self.gt_token.to_tokens(tokens);
2491 }
2492 }
2493
2494 #[cfg(feature = "full")]
2495 impl ToTokens for GenericMethodArgument {
2496 fn to_tokens(&self, tokens: &mut Tokens) {
2497 match *self {
2498 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
2499 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
2500 }
2501 }
2502 }
2503
2504 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002505 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002506 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002507 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002508 self.paren_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002509 self.elems.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002510 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002511 // distinguish ExprTuple from ExprParen.
David Tolnay2a86fdd2017-12-28 23:34:28 -05002512 if self.elems.len() == 1 && !self.elems.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002513 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002514 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002515 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002516 }
2517 }
2518
2519 impl ToTokens for ExprBinary {
2520 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002521 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002522 self.left.to_tokens(tokens);
2523 self.op.to_tokens(tokens);
2524 self.right.to_tokens(tokens);
2525 }
2526 }
2527
2528 impl ToTokens for ExprUnary {
2529 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002530 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002531 self.op.to_tokens(tokens);
2532 self.expr.to_tokens(tokens);
2533 }
2534 }
2535
David Tolnay8c91b882017-12-28 23:04:32 -05002536 impl ToTokens for ExprLit {
2537 fn to_tokens(&self, tokens: &mut Tokens) {
2538 attrs_to_tokens(&self.attrs, tokens);
2539 self.lit.to_tokens(tokens);
2540 }
2541 }
2542
Alex Crichton62a0a592017-05-22 13:58:53 -07002543 impl ToTokens for ExprCast {
2544 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002545 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002546 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002547 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002548 self.ty.to_tokens(tokens);
2549 }
2550 }
2551
David Tolnay0cf94f22017-12-28 23:46:26 -05002552 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002553 impl ToTokens for ExprType {
2554 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002555 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002556 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002557 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 self.ty.to_tokens(tokens);
2559 }
2560 }
2561
Michael Layzell734adb42017-06-07 16:58:31 -04002562 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002563 fn maybe_wrap_else(
2564 tokens: &mut Tokens,
David Tolnay2ccf32a2017-12-29 00:34:26 -05002565 else_: &Option<(Token![else], Box<Expr>)>,
David Tolnay51382052017-12-27 13:46:21 -05002566 ) {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002567 if let Some((ref else_token, ref else_)) = *else_ {
2568 else_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002569
2570 // If we are not one of the valid expressions to exist in an else
2571 // clause, wrap ourselves in a block.
David Tolnay2ccf32a2017-12-29 00:34:26 -05002572 match **else_ {
David Tolnay8c91b882017-12-28 23:04:32 -05002573 Expr::If(_) | Expr::IfLet(_) | Expr::Block(_) => {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002574 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002575 }
2576 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002577 token::Brace::default().surround(tokens, |tokens| {
David Tolnay2ccf32a2017-12-29 00:34:26 -05002578 else_.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002579 });
2580 }
2581 }
2582 }
2583 }
2584
2585 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002586 impl ToTokens for ExprIf {
2587 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002588 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002589 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002590 wrap_bare_struct(tokens, &self.cond);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002591 self.then_branch.to_tokens(tokens);
2592 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002593 }
2594 }
2595
Michael Layzell734adb42017-06-07 16:58:31 -04002596 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002597 impl ToTokens for ExprIfLet {
2598 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002599 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002600 self.if_token.to_tokens(tokens);
2601 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002602 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002603 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002604 wrap_bare_struct(tokens, &self.expr);
David Tolnay2ccf32a2017-12-29 00:34:26 -05002605 self.then_branch.to_tokens(tokens);
2606 maybe_wrap_else(tokens, &self.else_branch);
Alex Crichton62a0a592017-05-22 13:58:53 -07002607 }
2608 }
2609
Michael Layzell734adb42017-06-07 16:58:31 -04002610 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002611 impl ToTokens for ExprWhile {
2612 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002613 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002614 if self.label.is_some() {
2615 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002616 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002617 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002618 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002619 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002620 self.body.to_tokens(tokens);
2621 }
2622 }
2623
Michael Layzell734adb42017-06-07 16:58:31 -04002624 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002625 impl ToTokens for ExprWhileLet {
2626 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002627 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002628 if self.label.is_some() {
2629 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002630 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002631 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002632 self.while_token.to_tokens(tokens);
2633 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002634 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002635 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002636 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002637 self.body.to_tokens(tokens);
2638 }
2639 }
2640
Michael Layzell734adb42017-06-07 16:58:31 -04002641 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002642 impl ToTokens for ExprForLoop {
2643 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002644 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002645 if self.label.is_some() {
2646 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002647 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002648 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002649 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002650 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002651 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002652 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 self.body.to_tokens(tokens);
2654 }
2655 }
2656
Michael Layzell734adb42017-06-07 16:58:31 -04002657 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002658 impl ToTokens for ExprLoop {
2659 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002660 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002661 if self.label.is_some() {
2662 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002663 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002664 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002665 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002666 self.body.to_tokens(tokens);
2667 }
2668 }
2669
Michael Layzell734adb42017-06-07 16:58:31 -04002670 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002671 impl ToTokens for ExprMatch {
2672 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002673 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002674 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002675 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002676 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002677 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002678 arm.to_tokens(tokens);
2679 // Ensure that we have a comma after a non-block arm, except
2680 // for the last one.
2681 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002682 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002683 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002684 }
2685 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002686 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002687 }
2688 }
2689
Michael Layzell734adb42017-06-07 16:58:31 -04002690 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002691 impl ToTokens for ExprCatch {
2692 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002693 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002694 self.do_token.to_tokens(tokens);
2695 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002696 self.block.to_tokens(tokens);
2697 }
2698 }
2699
Michael Layzell734adb42017-06-07 16:58:31 -04002700 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002701 impl ToTokens for ExprYield {
2702 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002703 tokens.append_all(self.attrs.outer());
Alex Crichtonfe110462017-06-01 12:49:27 -07002704 self.yield_token.to_tokens(tokens);
2705 self.expr.to_tokens(tokens);
2706 }
2707 }
2708
2709 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002710 impl ToTokens for ExprClosure {
2711 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002712 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002713 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002714 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002715 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002716 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002717 FnArg::Captured(ArgCaptured {
2718 ref pat,
2719 ty: Type::Infer(_),
2720 ..
2721 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002722 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002723 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002724 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002725 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002726 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002727 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002728 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002729 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002730 self.body.to_tokens(tokens);
2731 }
2732 }
2733
Michael Layzell734adb42017-06-07 16:58:31 -04002734 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002735 impl ToTokens for ExprUnsafe {
2736 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002737 tokens.append_all(self.attrs.outer());
Nika Layzell640832a2017-12-04 13:37:09 -05002738 self.unsafe_token.to_tokens(tokens);
2739 self.block.to_tokens(tokens);
2740 }
2741 }
2742
2743 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002744 impl ToTokens for ExprBlock {
2745 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002746 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002747 self.block.to_tokens(tokens);
2748 }
2749 }
2750
Michael Layzell734adb42017-06-07 16:58:31 -04002751 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002752 impl ToTokens for ExprAssign {
2753 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002754 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002755 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002756 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002757 self.right.to_tokens(tokens);
2758 }
2759 }
2760
Michael Layzell734adb42017-06-07 16:58:31 -04002761 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002762 impl ToTokens for ExprAssignOp {
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.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002766 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002767 self.right.to_tokens(tokens);
2768 }
2769 }
2770
Michael Layzell734adb42017-06-07 16:58:31 -04002771 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002772 impl ToTokens for ExprField {
2773 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002774 tokens.append_all(self.attrs.outer());
David Tolnay85b69a42017-12-27 20:43:10 -05002775 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002776 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002777 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002778 }
2779 }
2780
Michael Layzell734adb42017-06-07 16:58:31 -04002781 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002782 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002783 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002784 match *self {
2785 Member::Named(ident) => ident.to_tokens(tokens),
2786 Member::Unnamed(ref index) => index.to_tokens(tokens),
2787 }
2788 }
2789 }
2790
2791 #[cfg(feature = "full")]
2792 impl ToTokens for Index {
2793 fn to_tokens(&self, tokens: &mut Tokens) {
2794 tokens.append(TokenTree {
2795 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002796 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002797 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002798 }
2799 }
2800
2801 impl ToTokens for ExprIndex {
2802 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002803 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002804 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002805 self.bracket_token.surround(tokens, |tokens| {
2806 self.index.to_tokens(tokens);
2807 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002808 }
2809 }
2810
Michael Layzell734adb42017-06-07 16:58:31 -04002811 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002812 impl ToTokens for ExprRange {
2813 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002814 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002815 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002816 match self.limits {
2817 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2818 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2819 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002820 self.to.to_tokens(tokens);
2821 }
2822 }
2823
2824 impl ToTokens for ExprPath {
2825 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002826 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002827 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002828 }
2829 }
2830
Michael Layzell734adb42017-06-07 16:58:31 -04002831 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002832 impl ToTokens for ExprAddrOf {
2833 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002834 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002835 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002836 self.mutbl.to_tokens(tokens);
2837 self.expr.to_tokens(tokens);
2838 }
2839 }
2840
Michael Layzell734adb42017-06-07 16:58:31 -04002841 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002842 impl ToTokens for ExprBreak {
2843 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002844 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002845 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002846 self.label.to_tokens(tokens);
2847 self.expr.to_tokens(tokens);
2848 }
2849 }
2850
Michael Layzell734adb42017-06-07 16:58:31 -04002851 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002852 impl ToTokens for ExprContinue {
2853 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002854 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002855 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002856 self.label.to_tokens(tokens);
2857 }
2858 }
2859
Michael Layzell734adb42017-06-07 16:58:31 -04002860 #[cfg(feature = "full")]
David Tolnayc246cd32017-12-28 23:14:32 -05002861 impl ToTokens for ExprReturn {
Alex Crichton62a0a592017-05-22 13:58:53 -07002862 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002863 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002864 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002865 self.expr.to_tokens(tokens);
2866 }
2867 }
2868
Michael Layzell734adb42017-06-07 16:58:31 -04002869 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05002870 impl ToTokens for ExprMacro {
2871 fn to_tokens(&self, tokens: &mut Tokens) {
2872 tokens.append_all(self.attrs.outer());
2873 self.mac.to_tokens(tokens);
2874 }
2875 }
2876
2877 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002878 impl ToTokens for ExprStruct {
2879 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002880 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002881 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002882 self.brace_token.surround(tokens, |tokens| {
2883 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002884 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002885 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002886 self.rest.to_tokens(tokens);
2887 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002888 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002889 }
2890 }
2891
Michael Layzell734adb42017-06-07 16:58:31 -04002892 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002893 impl ToTokens for ExprRepeat {
2894 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002895 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002896 self.bracket_token.surround(tokens, |tokens| {
2897 self.expr.to_tokens(tokens);
2898 self.semi_token.to_tokens(tokens);
2899 self.amt.to_tokens(tokens);
2900 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002901 }
2902 }
2903
David Tolnaye98775f2017-12-28 23:17:00 -05002904 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04002905 impl ToTokens for ExprGroup {
2906 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002907 attrs_to_tokens(&self.attrs, tokens);
Michael Layzell93c36282017-06-04 20:43:14 -04002908 self.group_token.surround(tokens, |tokens| {
2909 self.expr.to_tokens(tokens);
2910 });
2911 }
2912 }
2913
David Tolnaye98775f2017-12-28 23:17:00 -05002914 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002915 impl ToTokens for ExprParen {
2916 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002917 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002918 self.paren_token.surround(tokens, |tokens| {
2919 self.expr.to_tokens(tokens);
2920 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002921 }
2922 }
2923
Michael Layzell734adb42017-06-07 16:58:31 -04002924 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002925 impl ToTokens for ExprTry {
2926 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002927 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002928 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002929 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002930 }
2931 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002932
Michael Layzell734adb42017-06-07 16:58:31 -04002933 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002934 impl ToTokens for FieldValue {
2935 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002936 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002937 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2938 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002939 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002940 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002941 self.expr.to_tokens(tokens);
2942 }
David Tolnay055a7042016-10-02 19:23:54 -07002943 }
2944 }
2945
Michael Layzell734adb42017-06-07 16:58:31 -04002946 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002947 impl ToTokens for Arm {
2948 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002949 tokens.append_all(&self.attrs);
2950 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002951 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002952 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002953 self.guard.to_tokens(tokens);
2954 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002955 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002956 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002957 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002958 }
2959 }
2960
Michael Layzell734adb42017-06-07 16:58:31 -04002961 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002962 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002963 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002964 self.underscore_token.to_tokens(tokens);
2965 }
2966 }
2967
Michael Layzell734adb42017-06-07 16:58:31 -04002968 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002969 impl ToTokens for PatIdent {
2970 fn to_tokens(&self, tokens: &mut Tokens) {
2971 self.mode.to_tokens(tokens);
2972 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002973 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002974 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002975 self.subpat.to_tokens(tokens);
2976 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002977 }
2978 }
2979
Michael Layzell734adb42017-06-07 16:58:31 -04002980 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002981 impl ToTokens for PatStruct {
2982 fn to_tokens(&self, tokens: &mut Tokens) {
2983 self.path.to_tokens(tokens);
2984 self.brace_token.surround(tokens, |tokens| {
2985 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002986 // NOTE: We need a comma before the dot2 token if it is present.
2987 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002988 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002989 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002990 self.dot2_token.to_tokens(tokens);
2991 });
2992 }
2993 }
2994
Michael Layzell734adb42017-06-07 16:58:31 -04002995 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002996 impl ToTokens for PatTupleStruct {
2997 fn to_tokens(&self, tokens: &mut Tokens) {
2998 self.path.to_tokens(tokens);
2999 self.pat.to_tokens(tokens);
3000 }
3001 }
3002
Michael Layzell734adb42017-06-07 16:58:31 -04003003 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003004 impl ToTokens for PatPath {
3005 fn to_tokens(&self, tokens: &mut Tokens) {
3006 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
3007 }
3008 }
3009
Michael Layzell734adb42017-06-07 16:58:31 -04003010 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003011 impl ToTokens for PatTuple {
3012 fn to_tokens(&self, tokens: &mut Tokens) {
3013 self.paren_token.surround(tokens, |tokens| {
3014 for (i, token) in self.pats.iter().enumerate() {
3015 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07003016 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3017 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003018 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003019 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003020 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003021
3022 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003023 // Ensure there is a comma before the .. token.
3024 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003025 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003026 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003027 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003028 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003029 });
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 PatBox {
3035 fn to_tokens(&self, tokens: &mut Tokens) {
3036 self.box_token.to_tokens(tokens);
3037 self.pat.to_tokens(tokens);
3038 }
3039 }
3040
Michael Layzell734adb42017-06-07 16:58:31 -04003041 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003042 impl ToTokens for PatRef {
3043 fn to_tokens(&self, tokens: &mut Tokens) {
3044 self.and_token.to_tokens(tokens);
3045 self.mutbl.to_tokens(tokens);
3046 self.pat.to_tokens(tokens);
3047 }
3048 }
3049
Michael Layzell734adb42017-06-07 16:58:31 -04003050 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003051 impl ToTokens for PatLit {
3052 fn to_tokens(&self, tokens: &mut Tokens) {
3053 self.expr.to_tokens(tokens);
3054 }
3055 }
3056
Michael Layzell734adb42017-06-07 16:58:31 -04003057 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003058 impl ToTokens for PatRange {
3059 fn to_tokens(&self, tokens: &mut Tokens) {
3060 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08003061 match self.limits {
3062 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3063 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
3064 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003065 self.hi.to_tokens(tokens);
3066 }
3067 }
3068
Michael Layzell734adb42017-06-07 16:58:31 -04003069 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003070 impl ToTokens for PatSlice {
3071 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003072 // XXX: This is a mess, and it will be so easy to screw it up. How
3073 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003074 self.bracket_token.surround(tokens, |tokens| {
3075 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003076
3077 // If we need a comma before the middle or standalone .. token,
3078 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05003079 if !self.front.empty_or_trailing()
3080 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04003081 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003082 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003083 }
3084
3085 // If we have an identifier, we always need a .. token.
3086 if self.middle.is_some() {
3087 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003088 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003089 } else if self.dot2_token.is_some() {
3090 self.dot2_token.to_tokens(tokens);
3091 }
3092
3093 // Make sure we have a comma before the back half.
3094 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07003095 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003096 self.back.to_tokens(tokens);
3097 } else {
3098 self.comma_token.to_tokens(tokens);
3099 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003100 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07003101 }
3102 }
3103
Michael Layzell734adb42017-06-07 16:58:31 -04003104 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07003105 impl ToTokens for FieldPat {
3106 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003107 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07003108 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05003109 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003110 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003111 }
3112 self.pat.to_tokens(tokens);
3113 }
3114 }
3115
Michael Layzell734adb42017-06-07 16:58:31 -04003116 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07003117 impl ToTokens for BindingMode {
3118 fn to_tokens(&self, tokens: &mut Tokens) {
3119 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003120 BindingMode::ByRef(ref t, ref m) => {
3121 t.to_tokens(tokens);
3122 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003123 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003124 BindingMode::ByValue(ref m) => {
3125 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003126 }
3127 }
3128 }
3129 }
David Tolnay42602292016-10-01 22:25:45 -07003130
Michael Layzell734adb42017-06-07 16:58:31 -04003131 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07003132 impl ToTokens for CaptureBy {
3133 fn to_tokens(&self, tokens: &mut Tokens) {
3134 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003135 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003136 CaptureBy::Ref => {
3137 // nothing
3138 }
David Tolnay89e05672016-10-02 14:39:42 -07003139 }
3140 }
3141 }
3142
Michael Layzell734adb42017-06-07 16:58:31 -04003143 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003144 impl ToTokens for Block {
3145 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003146 self.brace_token.surround(tokens, |tokens| {
3147 tokens.append_all(&self.stmts);
3148 });
David Tolnay42602292016-10-01 22:25:45 -07003149 }
3150 }
3151
Michael Layzell734adb42017-06-07 16:58:31 -04003152 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003153 impl ToTokens for Stmt {
3154 fn to_tokens(&self, tokens: &mut Tokens) {
3155 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07003156 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07003157 Stmt::Item(ref item) => item.to_tokens(tokens),
3158 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003159 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003160 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003161 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003162 }
David Tolnay42602292016-10-01 22:25:45 -07003163 }
3164 }
3165 }
David Tolnay191e0582016-10-02 18:31:09 -07003166
Michael Layzell734adb42017-06-07 16:58:31 -04003167 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003168 impl ToTokens for Local {
3169 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003170 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003171 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003172 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003173 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003174 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003175 self.ty.to_tokens(tokens);
3176 }
3177 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003178 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003179 self.init.to_tokens(tokens);
3180 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003181 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003182 }
3183 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003184}