blob: 76c666f239805994af7e8eee48c8e60e46a0a5d5 [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>,
107 pub if_true: Block,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800108 pub else_token: Option<Token![else]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500109 pub if_false: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700110 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500111
Alex Crichton62a0a592017-05-22 13:58:53 -0700112 /// An `if let` expression with an optional else block
113 ///
114 /// E.g., `if let pat = expr { block } else { expr }`
115 ///
116 /// This is desugared to a `match` expression.
Michael Layzell734adb42017-06-07 16:58:31 -0400117 pub IfLet(ExprIfLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500118 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800119 pub if_token: Token![if],
120 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500121 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800122 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500123 pub expr: Box<Expr>,
124 pub if_true: Block,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800125 pub else_token: Option<Token![else]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500126 pub if_false: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700127 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500128
Alex Crichton62a0a592017-05-22 13:58:53 -0700129 /// A while loop, with an optional label
130 ///
131 /// E.g., `'label: while expr { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400132 pub While(ExprWhile #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500133 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700134 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800135 pub colon_token: Option<Token![:]>,
136 pub while_token: Token![while],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500137 pub cond: Box<Expr>,
138 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700139 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500140
Alex Crichton62a0a592017-05-22 13:58:53 -0700141 /// A while-let loop, with an optional label.
142 ///
143 /// E.g., `'label: while let pat = expr { block }`
144 ///
145 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400146 pub WhileLet(ExprWhileLet #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500147 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700148 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800149 pub colon_token: Option<Token![:]>,
150 pub while_token: Token![while],
151 pub let_token: Token![let],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500152 pub pat: Box<Pat>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800153 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500154 pub expr: Box<Expr>,
155 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700156 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500157
Alex Crichton62a0a592017-05-22 13:58:53 -0700158 /// A for loop, with an optional label.
159 ///
160 /// E.g., `'label: for pat in expr { block }`
161 ///
162 /// This is desugared to a combination of `loop` and `match` expressions.
Michael Layzell734adb42017-06-07 16:58:31 -0400163 pub ForLoop(ExprForLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500164 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500165 pub label: Option<Lifetime>,
166 pub colon_token: Option<Token![:]>,
167 pub for_token: Token![for],
Alex Crichton62a0a592017-05-22 13:58:53 -0700168 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500169 pub in_token: Token![in],
Alex Crichton62a0a592017-05-22 13:58:53 -0700170 pub expr: Box<Expr>,
171 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700172 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500173
Alex Crichton62a0a592017-05-22 13:58:53 -0700174 /// Conditionless loop with an optional label.
175 ///
176 /// E.g. `'label: loop { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400177 pub Loop(ExprLoop #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500178 pub attrs: Vec<Attribute>,
David Tolnay63e3dee2017-06-03 20:13:17 -0700179 pub label: Option<Lifetime>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800180 pub colon_token: Option<Token![:]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500181 pub loop_token: Token![loop],
182 pub body: Block,
Alex Crichton62a0a592017-05-22 13:58:53 -0700183 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500184
Alex Crichton62a0a592017-05-22 13:58:53 -0700185 /// A `match` block.
Michael Layzell734adb42017-06-07 16:58:31 -0400186 pub Match(ExprMatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500187 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800188 pub match_token: Token![match],
Alex Crichton62a0a592017-05-22 13:58:53 -0700189 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500190 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700191 pub arms: Vec<Arm>,
192 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500193
Alex Crichton62a0a592017-05-22 13:58:53 -0700194 /// A closure (for example, `move |a, b, c| a + b + c`)
Michael Layzell734adb42017-06-07 16:58:31 -0400195 pub Closure(ExprClosure #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500196 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700197 pub capture: CaptureBy,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800198 pub or1_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500199 pub inputs: Delimited<FnArg, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800200 pub or2_token: Token![|],
David Tolnay7f675742017-12-27 22:43:21 -0500201 pub output: ReturnType,
202 pub body: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700203 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500204
Nika Layzell640832a2017-12-04 13:37:09 -0500205 /// An unsafe block (`unsafe { ... }`)
206 pub Unsafe(ExprUnsafe #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500207 pub attrs: Vec<Attribute>,
Nika Layzell640832a2017-12-04 13:37:09 -0500208 pub unsafe_token: Token![unsafe],
209 pub block: Block,
210 }),
211
212 /// A block (`{ ... }`)
Michael Layzell734adb42017-06-07 16:58:31 -0400213 pub Block(ExprBlock #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500214 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700215 pub block: Block,
216 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700217
Alex Crichton62a0a592017-05-22 13:58:53 -0700218 /// An assignment (`a = foo()`)
Michael Layzell734adb42017-06-07 16:58:31 -0400219 pub Assign(ExprAssign #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500220 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700221 pub left: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800222 pub eq_token: Token![=],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500223 pub right: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700224 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500225
Alex Crichton62a0a592017-05-22 13:58:53 -0700226 /// An assignment with an operator
227 ///
228 /// For example, `a += 1`.
Michael Layzell734adb42017-06-07 16:58:31 -0400229 pub AssignOp(ExprAssignOp #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500230 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700231 pub left: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500232 pub op: BinOp,
Alex Crichton62a0a592017-05-22 13:58:53 -0700233 pub right: Box<Expr>,
234 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500235
David Tolnay85b69a42017-12-27 20:43:10 -0500236 /// Access of a named struct field (`obj.foo`) or unnamed tuple struct
237 /// field (`obj.0`).
Michael Layzell734adb42017-06-07 16:58:31 -0400238 pub Field(ExprField #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500239 pub attrs: Vec<Attribute>,
David Tolnay85b69a42017-12-27 20:43:10 -0500240 pub base: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800241 pub dot_token: Token![.],
David Tolnay85b69a42017-12-27 20:43:10 -0500242 pub member: Member,
Alex Crichton62a0a592017-05-22 13:58:53 -0700243 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500244
Alex Crichton62a0a592017-05-22 13:58:53 -0700245 /// An indexing operation (`foo[2]`)
246 pub Index(ExprIndex {
David Tolnay8c91b882017-12-28 23:04:32 -0500247 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700248 pub expr: Box<Expr>,
David Tolnay32954ef2017-12-26 22:43:16 -0500249 pub bracket_token: token::Bracket,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500250 pub index: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700251 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500252
David Tolnaybe55d7b2017-12-17 23:41:20 -0800253 /// A range (`1..2`, `1..`, `..2`, `1..=2`, `..=2`)
Michael Layzell734adb42017-06-07 16:58:31 -0400254 pub Range(ExprRange #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500255 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700256 pub from: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700257 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500258 pub to: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700259 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700260
Alex Crichton62a0a592017-05-22 13:58:53 -0700261 /// Variable reference, possibly containing `::` and/or type
262 /// parameters, e.g. foo::bar::<baz>.
263 ///
264 /// Optionally "qualified",
265 /// E.g. `<Vec<T> as SomeTrait>::SomeType`.
266 pub Path(ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -0500267 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700268 pub qself: Option<QSelf>,
269 pub path: Path,
270 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700271
Alex Crichton62a0a592017-05-22 13:58:53 -0700272 /// A referencing operation (`&a` or `&mut a`)
Michael Layzell734adb42017-06-07 16:58:31 -0400273 pub AddrOf(ExprAddrOf #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500274 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800275 pub and_token: Token![&],
Alex Crichton62a0a592017-05-22 13:58:53 -0700276 pub mutbl: Mutability,
277 pub expr: Box<Expr>,
278 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500279
Alex Crichton62a0a592017-05-22 13:58:53 -0700280 /// A `break`, with an optional label to break, and an optional expression
Michael Layzell734adb42017-06-07 16:58:31 -0400281 pub Break(ExprBreak #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500282 pub attrs: Vec<Attribute>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500283 pub break_token: Token![break],
David Tolnay63e3dee2017-06-03 20:13:17 -0700284 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700285 pub expr: Option<Box<Expr>>,
286 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500287
Alex Crichton62a0a592017-05-22 13:58:53 -0700288 /// A `continue`, with an optional label
Michael Layzell734adb42017-06-07 16:58:31 -0400289 pub Continue(ExprContinue #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500290 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800291 pub continue_token: Token![continue],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500292 pub label: Option<Lifetime>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700293 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500294
Alex Crichton62a0a592017-05-22 13:58:53 -0700295 /// A `return`, with an optional value to be returned
David Tolnayc246cd32017-12-28 23:14:32 -0500296 pub Return(ExprReturn #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500297 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800298 pub return_token: Token![return],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500299 pub expr: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700300 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700301
Alex Crichton62a0a592017-05-22 13:58:53 -0700302 /// A macro invocation; pre-expansion
David Tolnay8c91b882017-12-28 23:04:32 -0500303 pub Macro(ExprMacro #full {
304 pub attrs: Vec<Attribute>,
305 pub mac: Macro,
306 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700307
Alex Crichton62a0a592017-05-22 13:58:53 -0700308 /// A struct literal expression.
309 ///
310 /// For example, `Foo {x: 1, y: 2}`, or
311 /// `Foo {x: 1, .. base}`, where `base` is the `Option<Expr>`.
Michael Layzell734adb42017-06-07 16:58:31 -0400312 pub Struct(ExprStruct #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500313 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700314 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500315 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500316 pub fields: Delimited<FieldValue, Token![,]>,
317 pub dot2_token: Option<Token![..]>,
318 pub rest: Option<Box<Expr>>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700319 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700320
Alex Crichton62a0a592017-05-22 13:58:53 -0700321 /// An array literal constructed from one repeated element.
322 ///
323 /// For example, `[1; 5]`. The first expression is the element
324 /// to be repeated; the second is the number of times to repeat it.
Michael Layzell734adb42017-06-07 16:58:31 -0400325 pub Repeat(ExprRepeat #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500326 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500327 pub bracket_token: token::Bracket,
Alex Crichton62a0a592017-05-22 13:58:53 -0700328 pub expr: Box<Expr>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500329 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700330 pub amt: Box<Expr>,
331 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700332
Alex Crichton62a0a592017-05-22 13:58:53 -0700333 /// No-op: used solely so we can pretty-print faithfully
David Tolnaye98775f2017-12-28 23:17:00 -0500334 pub Paren(ExprParen #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500335 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500336 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500337 pub expr: Box<Expr>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700338 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700339
Michael Layzell93c36282017-06-04 20:43:14 -0400340 /// No-op: used solely so we can pretty-print faithfully
341 ///
342 /// A `group` represents a `None`-delimited span in the input
343 /// `TokenStream` which affects the precidence of the resulting
344 /// expression. They are used for macro hygiene.
David Tolnaye98775f2017-12-28 23:17:00 -0500345 pub Group(ExprGroup #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500346 pub attrs: Vec<Attribute>,
David Tolnay32954ef2017-12-26 22:43:16 -0500347 pub group_token: token::Group,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500348 pub expr: Box<Expr>,
Michael Layzell93c36282017-06-04 20:43:14 -0400349 }),
350
Alex Crichton62a0a592017-05-22 13:58:53 -0700351 /// `expr?`
Michael Layzell734adb42017-06-07 16:58:31 -0400352 pub Try(ExprTry #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500353 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700354 pub expr: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800355 pub question_token: Token![?],
Alex Crichton62a0a592017-05-22 13:58:53 -0700356 }),
Arnavion02ef13f2017-04-25 00:54:31 -0700357
Alex Crichton62a0a592017-05-22 13:58:53 -0700358 /// A catch expression.
359 ///
360 /// E.g. `do catch { block }`
Michael Layzell734adb42017-06-07 16:58:31 -0400361 pub Catch(ExprCatch #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500362 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800363 pub do_token: Token![do],
364 pub catch_token: Token![catch],
Alex Crichton62a0a592017-05-22 13:58:53 -0700365 pub block: Block,
366 }),
Alex Crichtonfe110462017-06-01 12:49:27 -0700367
368 /// A yield expression.
369 ///
370 /// E.g. `yield expr`
371 pub Yield(ExprYield #full {
David Tolnay8c91b882017-12-28 23:04:32 -0500372 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800373 pub yield_token: Token![yield],
Alex Crichtonfe110462017-06-01 12:49:27 -0700374 pub expr: Option<Box<Expr>>,
375 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700376 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700377}
378
David Tolnay8c91b882017-12-28 23:04:32 -0500379impl Expr {
380 // Not public API.
381 #[doc(hidden)]
David Tolnay096d4982017-12-28 23:18:18 -0500382 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -0500383 pub fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
384 match *self {
385 Expr::Box(ExprBox { ref mut attrs, .. }) |
386 Expr::InPlace(ExprInPlace { ref mut attrs, .. }) |
387 Expr::Array(ExprArray { ref mut attrs, .. }) |
388 Expr::Call(ExprCall { ref mut attrs, .. }) |
389 Expr::MethodCall(ExprMethodCall { ref mut attrs, .. }) |
390 Expr::Tuple(ExprTuple { ref mut attrs, .. }) |
391 Expr::Binary(ExprBinary { ref mut attrs, .. }) |
392 Expr::Unary(ExprUnary { ref mut attrs, .. }) |
393 Expr::Lit(ExprLit { ref mut attrs, .. }) |
394 Expr::Cast(ExprCast { ref mut attrs, .. }) |
395 Expr::Type(ExprType { ref mut attrs, .. }) |
396 Expr::If(ExprIf { ref mut attrs, .. }) |
397 Expr::IfLet(ExprIfLet { ref mut attrs, .. }) |
398 Expr::While(ExprWhile { ref mut attrs, .. }) |
399 Expr::WhileLet(ExprWhileLet { ref mut attrs, .. }) |
400 Expr::ForLoop(ExprForLoop { ref mut attrs, .. }) |
401 Expr::Loop(ExprLoop { ref mut attrs, .. }) |
402 Expr::Match(ExprMatch { ref mut attrs, .. }) |
403 Expr::Closure(ExprClosure { ref mut attrs, .. }) |
404 Expr::Unsafe(ExprUnsafe { ref mut attrs, .. }) |
405 Expr::Block(ExprBlock { ref mut attrs, .. }) |
406 Expr::Assign(ExprAssign { ref mut attrs, .. }) |
407 Expr::AssignOp(ExprAssignOp { ref mut attrs, .. }) |
408 Expr::Field(ExprField { ref mut attrs, .. }) |
409 Expr::Index(ExprIndex { ref mut attrs, .. }) |
410 Expr::Range(ExprRange { ref mut attrs, .. }) |
411 Expr::Path(ExprPath { ref mut attrs, .. }) |
412 Expr::AddrOf(ExprAddrOf { ref mut attrs, .. }) |
413 Expr::Break(ExprBreak { ref mut attrs, .. }) |
414 Expr::Continue(ExprContinue { ref mut attrs, .. }) |
David Tolnayc246cd32017-12-28 23:14:32 -0500415 Expr::Return(ExprReturn { ref mut attrs, .. }) |
David Tolnay8c91b882017-12-28 23:04:32 -0500416 Expr::Macro(ExprMacro { ref mut attrs, .. }) |
417 Expr::Struct(ExprStruct { ref mut attrs, .. }) |
418 Expr::Repeat(ExprRepeat { ref mut attrs, .. }) |
419 Expr::Paren(ExprParen { ref mut attrs, .. }) |
420 Expr::Group(ExprGroup { ref mut attrs, .. }) |
421 Expr::Try(ExprTry { ref mut attrs, .. }) |
422 Expr::Catch(ExprCatch { ref mut attrs, .. }) |
423 Expr::Yield(ExprYield { ref mut attrs, .. }) => attrs,
424 }
425 }
426}
427
Michael Layzell734adb42017-06-07 16:58:31 -0400428#[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -0500429ast_enum! {
430 /// A struct or tuple struct field accessed in a struct literal or field
431 /// expression.
432 pub enum Member {
433 /// A named field like `self.x`.
434 Named(Ident),
435 /// An unnamed field like `self.0`.
436 Unnamed(Index),
437 }
438}
439
440#[cfg(feature = "full")]
441ast_struct! {
442 /// The index of an unnamed tuple struct field.
443 pub struct Index #manual_extra_traits {
444 pub index: u32,
445 pub span: Span,
446 }
447}
448
449#[cfg(feature = "full")]
450impl Eq for Index {}
451
452#[cfg(feature = "full")]
453impl PartialEq for Index {
454 fn eq(&self, other: &Self) -> bool {
455 self.index == other.index
456 }
457}
458
459#[cfg(feature = "full")]
460impl Hash for Index {
461 fn hash<H: Hasher>(&self, state: &mut H) {
462 self.index.hash(state);
463 }
464}
465
466#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700467ast_struct! {
David Tolnayd60cfec2017-12-29 00:21:38 -0500468 pub struct MethodTurbofish {
469 pub colon2_token: Token![::],
470 pub lt_token: Token![<],
471 pub args: Delimited<GenericMethodArgument, Token![,]>,
472 pub gt_token: Token![>],
473 }
474}
475
476#[cfg(feature = "full")]
477ast_enum! {
478 /// A individual generic argument like `T`.
479 pub enum GenericMethodArgument {
480 /// The type parameters for this path segment, if present.
481 Type(Type),
482 /// Const expression. Must be inside of a block.
483 ///
484 /// NOTE: Identity expressions are represented as Type arguments, as
485 /// they are indistinguishable syntactically.
486 Const(Expr),
487 }
488}
489
490#[cfg(feature = "full")]
491ast_struct! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700492 /// A field-value pair in a struct literal.
493 pub struct FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -0500494 /// Attributes tagged on the field.
495 pub attrs: Vec<Attribute>,
496
497 /// Name or index of the field.
498 pub member: Member,
499
500 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -0500501
Alex Crichton62a0a592017-05-22 13:58:53 -0700502 /// Value of the field.
503 pub expr: Expr,
Clar Charrd22b5702017-03-10 15:24:56 -0500504
Alex Crichton62a0a592017-05-22 13:58:53 -0700505 /// Whether this is a shorthand field, e.g. `Struct { x }`
506 /// instead of `Struct { x: x }`.
507 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700508 }
David Tolnay055a7042016-10-02 19:23:54 -0700509}
510
Michael Layzell734adb42017-06-07 16:58:31 -0400511#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700512ast_struct! {
513 /// A Block (`{ .. }`).
514 ///
515 /// E.g. `{ .. }` as in `fn foo() { .. }`
516 pub struct Block {
David Tolnay32954ef2017-12-26 22:43:16 -0500517 pub brace_token: token::Brace,
Alex Crichton62a0a592017-05-22 13:58:53 -0700518 /// Statements in a block
519 pub stmts: Vec<Stmt>,
520 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700521}
522
Michael Layzell734adb42017-06-07 16:58:31 -0400523#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700524ast_enum! {
525 /// A statement, usually ending in a semicolon.
526 pub enum Stmt {
527 /// A local (let) binding.
528 Local(Box<Local>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700529
Alex Crichton62a0a592017-05-22 13:58:53 -0700530 /// An item definition.
531 Item(Box<Item>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700532
Alex Crichton62a0a592017-05-22 13:58:53 -0700533 /// Expr without trailing semicolon.
534 Expr(Box<Expr>),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700535
Alex Crichton62a0a592017-05-22 13:58:53 -0700536 /// Expression with trailing semicolon;
David Tolnayf8db7ba2017-11-11 22:52:16 -0800537 Semi(Box<Expr>, Token![;]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700538 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700539}
540
Michael Layzell734adb42017-06-07 16:58:31 -0400541#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700542ast_struct! {
543 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
544 pub struct Local {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500545 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800546 pub let_token: Token![let],
Alex Crichton62a0a592017-05-22 13:58:53 -0700547 pub pat: Box<Pat>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500548 pub colon_token: Option<Token![:]>,
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800549 pub ty: Option<Box<Type>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500550 pub eq_token: Option<Token![=]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700551 /// Initializer expression to set the value, if any
552 pub init: Option<Box<Expr>>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500553 pub semi_token: Token![;],
Alex Crichton62a0a592017-05-22 13:58:53 -0700554 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700555}
556
Michael Layzell734adb42017-06-07 16:58:31 -0400557#[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700558ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -0700559 // Clippy false positive
560 // https://github.com/Manishearth/rust-clippy/issues/1241
561 #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))]
562 pub enum Pat {
563 /// Represents a wildcard pattern (`_`)
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700564 pub Wild(PatWild {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800565 pub underscore_token: Token![_],
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700566 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700567
Alex Crichton62a0a592017-05-22 13:58:53 -0700568 /// A `Pat::Ident` may either be a new bound variable (`ref mut binding @ OPT_SUBPATTERN`),
569 /// or a unit struct/variant pattern, or a const pattern (in the last two cases the third
570 /// field must be `None`). Disambiguation cannot be done with parser alone, so it happens
571 /// during name resolution.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700572 pub Ident(PatIdent {
573 pub mode: BindingMode,
574 pub ident: Ident,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800575 pub at_token: Option<Token![@]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500576 pub subpat: Option<Box<Pat>>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700577 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700578
Alex Crichton62a0a592017-05-22 13:58:53 -0700579 /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`.
580 /// The `bool` is `true` in the presence of a `..`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700581 pub Struct(PatStruct {
582 pub path: Path,
David Tolnay32954ef2017-12-26 22:43:16 -0500583 pub brace_token: token::Brace,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500584 pub fields: Delimited<FieldPat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800585 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700586 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700587
Alex Crichton62a0a592017-05-22 13:58:53 -0700588 /// A tuple struct/variant pattern `Variant(x, y, .., z)`.
589 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
590 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700591 pub TupleStruct(PatTupleStruct {
592 pub path: Path,
593 pub pat: PatTuple,
594 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700595
Alex Crichton62a0a592017-05-22 13:58:53 -0700596 /// A possibly qualified path pattern.
597 /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
598 /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
599 /// only legally refer to associated constants.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700600 pub Path(PatPath {
601 pub qself: Option<QSelf>,
602 pub path: Path,
603 }),
David Tolnayf4bbbd92016-09-23 14:41:55 -0700604
Alex Crichton62a0a592017-05-22 13:58:53 -0700605 /// A tuple pattern `(a, b)`.
606 /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
607 /// 0 <= position <= subpats.len()
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700608 pub Tuple(PatTuple {
David Tolnay32954ef2017-12-26 22:43:16 -0500609 pub paren_token: token::Paren,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500610 pub pats: Delimited<Pat, Token![,]>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800611 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500612 pub dots_pos: Option<usize>,
613 pub dot2_token: Option<Token![..]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700614 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700615 /// A `box` pattern
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700616 pub Box(PatBox {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800617 pub box_token: Token![box],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500618 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700619 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700620 /// A reference pattern, e.g. `&mut (a, b)`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700621 pub Ref(PatRef {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800622 pub and_token: Token![&],
David Tolnay4a3f59a2017-12-28 21:21:12 -0500623 pub mutbl: Mutability,
624 pub pat: Box<Pat>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700625 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700626 /// A literal
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700627 pub Lit(PatLit {
628 pub expr: Box<Expr>,
629 }),
David Tolnaybe55d7b2017-12-17 23:41:20 -0800630 /// A range pattern, e.g. `1..=2`
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700631 pub Range(PatRange {
632 pub lo: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700633 pub limits: RangeLimits,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500634 pub hi: Box<Expr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700635 }),
Michael Layzell3936ceb2017-07-08 00:28:36 -0400636 /// `[a, b, i.., y, z]` is represented as:
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700637 pub Slice(PatSlice {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500638 pub bracket_token: token::Bracket,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800639 pub front: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700640 pub middle: Option<Box<Pat>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800641 pub comma_token: Option<Token![,]>,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500642 pub dot2_token: Option<Token![..]>,
643 pub back: Delimited<Pat, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700644 }),
Alex Crichton62a0a592017-05-22 13:58:53 -0700645 /// A macro pattern; pre-expansion
David Tolnaydecf28d2017-11-11 11:56:45 -0800646 pub Macro(Macro),
Alex Crichton62a0a592017-05-22 13:58:53 -0700647 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700648}
649
Michael Layzell734adb42017-06-07 16:58:31 -0400650#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700651ast_struct! {
652 /// An arm of a 'match'.
653 ///
David Tolnaybe55d7b2017-12-17 23:41:20 -0800654 /// E.g. `0..=10 => { println!("match!") }` as in
Alex Crichton62a0a592017-05-22 13:58:53 -0700655 ///
David Tolnaybcf26022017-12-25 22:10:52 -0500656 /// ```rust
657 /// # #![feature(dotdoteq_in_patterns)]
658 /// #
659 /// # fn main() {
660 /// # let n = 0;
Alex Crichton62a0a592017-05-22 13:58:53 -0700661 /// match n {
David Tolnaybcf26022017-12-25 22:10:52 -0500662 /// 0..=10 => { println!("match!") }
Alex Crichton62a0a592017-05-22 13:58:53 -0700663 /// // ..
David Tolnaybcf26022017-12-25 22:10:52 -0500664 /// # _ => {}
Alex Crichton62a0a592017-05-22 13:58:53 -0700665 /// }
David Tolnaybcf26022017-12-25 22:10:52 -0500666 /// # }
Alex Crichton62a0a592017-05-22 13:58:53 -0700667 /// ```
668 pub struct Arm {
669 pub attrs: Vec<Attribute>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800670 pub pats: Delimited<Pat, Token![|]>,
671 pub if_token: Option<Token![if]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700672 pub guard: Option<Box<Expr>>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800673 pub rocket_token: Token![=>],
Alex Crichton62a0a592017-05-22 13:58:53 -0700674 pub body: Box<Expr>,
David Tolnayf8db7ba2017-11-11 22:52:16 -0800675 pub comma: Option<Token![,]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700676 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700677}
678
Michael Layzell734adb42017-06-07 16:58:31 -0400679#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700680ast_enum! {
681 /// A capture clause
Alex Crichton2e0229c2017-05-23 09:34:50 -0700682 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700683 pub enum CaptureBy {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800684 Value(Token![move]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700685 Ref,
686 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700687}
688
Michael Layzell734adb42017-06-07 16:58:31 -0400689#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700690ast_enum! {
691 /// Limit types of a range (inclusive or exclusive)
Alex Crichton2e0229c2017-05-23 09:34:50 -0700692 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700693 pub enum RangeLimits {
694 /// Inclusive at the beginning, exclusive at the end
David Tolnayf8db7ba2017-11-11 22:52:16 -0800695 HalfOpen(Token![..]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700696 /// Inclusive at the beginning and end
David Tolnaybe55d7b2017-12-17 23:41:20 -0800697 Closed(Token![..=]),
Alex Crichton62a0a592017-05-22 13:58:53 -0700698 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700699}
700
Michael Layzell734adb42017-06-07 16:58:31 -0400701#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700702ast_struct! {
703 /// A single field in a struct pattern
704 ///
705 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
706 /// are treated the same as `x: x, y: ref y, z: ref mut z`,
707 /// except `is_shorthand` is true
708 pub struct FieldPat {
David Tolnay4a3f59a2017-12-28 21:21:12 -0500709 pub attrs: Vec<Attribute>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700710 /// The identifier for the field
David Tolnay85b69a42017-12-27 20:43:10 -0500711 pub member: Member,
David Tolnay4a3f59a2017-12-28 21:21:12 -0500712 pub colon_token: Option<Token![:]>,
Alex Crichton62a0a592017-05-22 13:58:53 -0700713 /// The pattern the field is destructured to
714 pub pat: Box<Pat>,
715 pub is_shorthand: bool,
Alex Crichton62a0a592017-05-22 13:58:53 -0700716 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700717}
718
Michael Layzell734adb42017-06-07 16:58:31 -0400719#[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -0700720ast_enum! {
Alex Crichton2e0229c2017-05-23 09:34:50 -0700721 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -0700722 pub enum BindingMode {
David Tolnayf8db7ba2017-11-11 22:52:16 -0800723 ByRef(Token![ref], Mutability),
Alex Crichton62a0a592017-05-22 13:58:53 -0700724 ByValue(Mutability),
725 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700726}
727
Michael Layzell3936ceb2017-07-08 00:28:36 -0400728#[cfg(any(feature = "parsing", feature = "printing"))]
729#[cfg(feature = "full")]
Alex Crichton03b30272017-08-28 09:35:24 -0700730fn arm_expr_requires_comma(expr: &Expr) -> bool {
731 // see https://github.com/rust-lang/rust/blob/eb8f2586e
732 // /src/libsyntax/parse/classify.rs#L17-L37
David Tolnay8c91b882017-12-28 23:04:32 -0500733 match *expr {
734 Expr::Unsafe(..)
735 | Expr::Block(..)
736 | Expr::If(..)
737 | Expr::IfLet(..)
738 | Expr::Match(..)
739 | Expr::While(..)
740 | Expr::WhileLet(..)
741 | Expr::Loop(..)
742 | Expr::ForLoop(..)
743 | Expr::Catch(..) => false,
Alex Crichton03b30272017-08-28 09:35:24 -0700744 _ => true,
Michael Layzell3936ceb2017-07-08 00:28:36 -0400745 }
746}
747
David Tolnayb9c8e322016-09-23 20:48:37 -0700748#[cfg(feature = "parsing")]
749pub mod parsing {
750 use super::*;
David Tolnayd60cfec2017-12-29 00:21:38 -0500751 use ty::parsing::{qpath, 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),
1479 if_true: Block {
1480 stmts: then_block.0,
1481 brace_token: then_block.1,
1482 },
1483 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001484 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001485 if_false: else_block.map(|p| Box::new(p.1.into())),
1486 })
1487 ));
David Tolnay29f9ce12016-10-02 20:58:40 -07001488 }
1489
Michael Layzell734adb42017-06-07 16:58:31 -04001490 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001491 impl Synom for ExprIf {
Michael Layzell92639a52017-06-01 00:07:44 -04001492 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001493 if_: keyword!(if) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001494 cond: expr_no_struct >>
1495 then_block: braces!(call!(Block::parse_within)) >>
1496 else_block: option!(else_block) >>
1497 (ExprIf {
David Tolnay8c91b882017-12-28 23:04:32 -05001498 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001499 cond: Box::new(cond),
1500 if_true: Block {
1501 stmts: then_block.0,
1502 brace_token: then_block.1,
1503 },
1504 if_token: if_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001505 else_token: else_block.as_ref().map(|p| Token![else]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001506 if_false: else_block.map(|p| Box::new(p.1.into())),
1507 })
1508 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001509 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001510
Michael Layzell734adb42017-06-07 16:58:31 -04001511 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001512 named!(else_block -> (Token![else], Expr), do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001513 else_: keyword!(else) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001514 expr: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05001515 syn!(ExprIf) => { Expr::If }
Alex Crichton954046c2017-05-30 21:49:42 -07001516 |
David Tolnay8c91b882017-12-28 23:04:32 -05001517 syn!(ExprIfLet) => { Expr::IfLet }
Alex Crichton954046c2017-05-30 21:49:42 -07001518 |
1519 do_parse!(
1520 else_block: braces!(call!(Block::parse_within)) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001521 (Expr::Block(ExprBlock {
1522 attrs: Vec::new(),
Alex Crichton954046c2017-05-30 21:49:42 -07001523 block: Block {
1524 stmts: else_block.0,
1525 brace_token: else_block.1,
1526 },
1527 }))
David Tolnay939766a2016-09-23 23:48:12 -07001528 )
Alex Crichton954046c2017-05-30 21:49:42 -07001529 ) >>
1530 (else_, expr)
David Tolnay939766a2016-09-23 23:48:12 -07001531 ));
1532
Michael Layzell734adb42017-06-07 16:58:31 -04001533 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001534 impl Synom for ExprForLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001535 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001536 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1537 for_: keyword!(for) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001538 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001539 in_: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001540 expr: expr_no_struct >>
1541 loop_block: syn!(Block) >>
1542 (ExprForLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001543 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001544 for_token: for_,
1545 in_token: in_,
1546 pat: Box::new(pat),
1547 expr: Box::new(expr),
1548 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001549 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001550 label: lbl.map(|p| p.0),
1551 })
1552 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001553 }
Gregory Katze5f35682016-09-27 14:20:55 -04001554
Michael Layzell734adb42017-06-07 16:58:31 -04001555 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001556 impl Synom for ExprLoop {
Michael Layzell92639a52017-06-01 00:07:44 -04001557 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001558 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1559 loop_: keyword!(loop) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001560 loop_block: syn!(Block) >>
1561 (ExprLoop {
David Tolnay8c91b882017-12-28 23:04:32 -05001562 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001563 loop_token: loop_,
1564 body: loop_block,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001565 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001566 label: lbl.map(|p| p.0),
1567 })
1568 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001569 }
1570
Michael Layzell734adb42017-06-07 16:58:31 -04001571 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001572 impl Synom for ExprMatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001573 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001574 match_: keyword!(match) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001575 obj: expr_no_struct >>
David Tolnay2c136452017-12-27 14:13:32 -05001576 res: braces!(many0!(Arm::parse)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001577 ({
Alex Crichton03b30272017-08-28 09:35:24 -07001578 let (arms, brace) = res;
Michael Layzell92639a52017-06-01 00:07:44 -04001579 ExprMatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001580 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001581 expr: Box::new(obj),
1582 match_token: match_,
1583 brace_token: brace,
Alex Crichton03b30272017-08-28 09:35:24 -07001584 arms: arms,
Michael Layzell92639a52017-06-01 00:07:44 -04001585 }
1586 })
1587 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001588 }
David Tolnay1978c672016-10-27 22:05:52 -07001589
Michael Layzell734adb42017-06-07 16:58:31 -04001590 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001591 impl Synom for ExprCatch {
Michael Layzell92639a52017-06-01 00:07:44 -04001592 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001593 do_: keyword!(do) >>
1594 catch_: keyword!(catch) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001595 catch_block: syn!(Block) >>
1596 (ExprCatch {
David Tolnay8c91b882017-12-28 23:04:32 -05001597 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001598 block: catch_block,
1599 do_token: do_,
1600 catch_token: catch_,
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001601 })
Michael Layzell92639a52017-06-01 00:07:44 -04001602 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001603 }
Arnavion02ef13f2017-04-25 00:54:31 -07001604
Michael Layzell734adb42017-06-07 16:58:31 -04001605 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07001606 impl Synom for ExprYield {
1607 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001608 yield_: keyword!(yield) >>
Alex Crichtonfe110462017-06-01 12:49:27 -07001609 expr: option!(syn!(Expr)) >>
1610 (ExprYield {
David Tolnay8c91b882017-12-28 23:04:32 -05001611 attrs: Vec::new(),
Alex Crichtonfe110462017-06-01 12:49:27 -07001612 yield_token: yield_,
1613 expr: expr.map(Box::new),
1614 })
1615 ));
1616 }
1617
1618 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001619 impl Synom for Arm {
Michael Layzell92639a52017-06-01 00:07:44 -04001620 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001621 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001622 pats: call!(Delimited::parse_separated_nonempty) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001623 guard: option!(tuple!(keyword!(if), syn!(Expr))) >>
1624 rocket: punct!(=>) >>
Alex Crichton03b30272017-08-28 09:35:24 -07001625 body: do_parse!(
1626 expr: alt!(expr_nosemi | syn!(Expr)) >>
1627 comma1: cond!(arm_expr_requires_comma(&expr), alt!(
1628 map!(input_end!(), |_| None)
1629 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001630 map!(punct!(,), Some)
Alex Crichton03b30272017-08-28 09:35:24 -07001631 )) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001632 comma2: cond!(!arm_expr_requires_comma(&expr), option!(punct!(,))) >>
David Tolnaybb4ca9f2017-12-26 12:28:58 -05001633 (expr, comma1.and_then(|x| x).or_else(|| comma2.and_then(|x| x)))
Michael Layzell92639a52017-06-01 00:07:44 -04001634 ) >>
1635 (Arm {
1636 rocket_token: rocket,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001637 if_token: guard.as_ref().map(|p| Token![if]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001638 attrs: attrs,
1639 pats: pats,
1640 guard: guard.map(|p| Box::new(p.1)),
Alex Crichton03b30272017-08-28 09:35:24 -07001641 body: Box::new(body.0),
1642 comma: body.1,
Michael Layzell92639a52017-06-01 00:07:44 -04001643 })
1644 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001645 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07001646
Michael Layzell734adb42017-06-07 16:58:31 -04001647 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001648 named!(expr_closure(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001649 capture: syn!(CaptureBy) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001650 or1: punct!(|) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001651 inputs: call!(Delimited::parse_terminated_with, fn_arg) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001652 or2: punct!(|) >>
David Tolnay89e05672016-10-02 14:39:42 -07001653 ret_and_body: alt!(
1654 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001655 arrow: punct!(->) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001656 ty: syn!(Type) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001657 body: syn!(Block) >>
David Tolnay4a3f59a2017-12-28 21:21:12 -05001658 (ReturnType::Type(arrow, Box::new(ty)),
David Tolnay8c91b882017-12-28 23:04:32 -05001659 Expr::Block(ExprBlock {
1660 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001661 block: body,
1662 }).into())
David Tolnay89e05672016-10-02 14:39:42 -07001663 )
1664 |
David Tolnayf93b90d2017-11-11 19:21:26 -08001665 map!(ambiguous_expr!(allow_struct), |e| (ReturnType::Default, e))
David Tolnay89e05672016-10-02 14:39:42 -07001666 ) >>
Alex Crichton62a0a592017-05-22 13:58:53 -07001667 (ExprClosure {
David Tolnay8c91b882017-12-28 23:04:32 -05001668 attrs: Vec::new(),
Alex Crichton62a0a592017-05-22 13:58:53 -07001669 capture: capture,
Alex Crichton954046c2017-05-30 21:49:42 -07001670 or1_token: or1,
David Tolnay7f675742017-12-27 22:43:21 -05001671 inputs: inputs,
Alex Crichton954046c2017-05-30 21:49:42 -07001672 or2_token: or2,
David Tolnay7f675742017-12-27 22:43:21 -05001673 output: ret_and_body.0,
Alex Crichton62a0a592017-05-22 13:58:53 -07001674 body: Box::new(ret_and_body.1),
1675 }.into())
David Tolnay89e05672016-10-02 14:39:42 -07001676 ));
1677
Michael Layzell734adb42017-06-07 16:58:31 -04001678 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001679 named!(fn_arg -> FnArg, do_parse!(
1680 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08001681 ty: option!(tuple!(punct!(:), syn!(Type))) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001682 ({
David Tolnay80ed55f2017-12-27 22:54:40 -05001683 if let Some((colon, ty)) = ty {
1684 FnArg::Captured(ArgCaptured {
1685 pat: pat,
1686 colon_token: colon,
1687 ty: ty,
1688 })
1689 } else {
1690 FnArg::Inferred(pat)
1691 }
David Tolnaybb6feae2016-10-02 21:25:20 -07001692 })
Gregory Katz3e562cc2016-09-28 18:33:02 -04001693 ));
1694
Michael Layzell734adb42017-06-07 16:58:31 -04001695 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001696 impl Synom for ExprWhile {
Michael Layzell92639a52017-06-01 00:07:44 -04001697 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001698 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1699 while_: keyword!(while) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001700 cond: expr_no_struct >>
1701 while_block: syn!(Block) >>
1702 (ExprWhile {
David Tolnay8c91b882017-12-28 23:04:32 -05001703 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001704 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001705 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001706 cond: Box::new(cond),
1707 body: while_block,
1708 label: lbl.map(|p| p.0),
1709 })
1710 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001711 }
1712
Michael Layzell734adb42017-06-07 16:58:31 -04001713 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001714 impl Synom for ExprWhileLet {
Michael Layzell92639a52017-06-01 00:07:44 -04001715 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001716 lbl: option!(tuple!(syn!(Lifetime), punct!(:))) >>
1717 while_: keyword!(while) >>
1718 let_: keyword!(let) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001719 pat: syn!(Pat) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001720 eq: punct!(=) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001721 value: expr_no_struct >>
1722 while_block: syn!(Block) >>
1723 (ExprWhileLet {
David Tolnay8c91b882017-12-28 23:04:32 -05001724 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001725 eq_token: eq,
1726 let_token: let_,
1727 while_token: while_,
David Tolnayf8db7ba2017-11-11 22:52:16 -08001728 colon_token: lbl.as_ref().map(|p| Token![:]((p.1).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04001729 pat: Box::new(pat),
1730 expr: Box::new(value),
1731 body: while_block,
1732 label: lbl.map(|p| p.0),
1733 })
1734 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001735 }
1736
Michael Layzell734adb42017-06-07 16:58:31 -04001737 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001738 impl Synom for ExprContinue {
Michael Layzell92639a52017-06-01 00:07:44 -04001739 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001740 cont: keyword!(continue) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001741 lbl: option!(syn!(Lifetime)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001742 (ExprContinue {
David Tolnay8c91b882017-12-28 23:04:32 -05001743 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001744 continue_token: cont,
1745 label: lbl,
1746 })
1747 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001748 }
Gregory Katzfd6935d2016-09-30 22:51:25 -04001749
Michael Layzell734adb42017-06-07 16:58:31 -04001750 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001751 named!(expr_break(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001752 break_: keyword!(break) >>
David Tolnay63e3dee2017-06-03 20:13:17 -07001753 lbl: option!(syn!(Lifetime)) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001754 // We can't allow blocks after a `break` expression when we wouldn't
1755 // allow structs, as this expression is ambiguous.
1756 val: opt_ambiguous_expr!(allow_struct) >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001757 (ExprBreak {
David Tolnay8c91b882017-12-28 23:04:32 -05001758 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001759 label: lbl,
1760 expr: val.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001761 break_token: break_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001762 }.into())
Gregory Katzfd6935d2016-09-30 22:51:25 -04001763 ));
1764
Michael Layzell734adb42017-06-07 16:58:31 -04001765 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001766 named!(expr_ret(allow_struct: bool) -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001767 return_: keyword!(return) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001768 // NOTE: return is greedy and eats blocks after it even when in a
1769 // position where structs are not allowed, such as in if statement
1770 // conditions. For example:
1771 //
David Tolnaybcf26022017-12-25 22:10:52 -05001772 // if return { println!("A") } {} // Prints "A"
David Tolnayaf2557e2016-10-24 11:52:21 -07001773 ret_value: option!(ambiguous_expr!(allow_struct)) >>
David Tolnayc246cd32017-12-28 23:14:32 -05001774 (ExprReturn {
David Tolnay8c91b882017-12-28 23:04:32 -05001775 attrs: Vec::new(),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001776 expr: ret_value.map(Box::new),
Alex Crichton954046c2017-05-30 21:49:42 -07001777 return_token: return_,
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001778 }.into())
David Tolnay055a7042016-10-02 19:23:54 -07001779 ));
1780
Michael Layzell734adb42017-06-07 16:58:31 -04001781 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001782 impl Synom for ExprStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04001783 named!(parse -> Self, do_parse!(
1784 path: syn!(Path) >>
1785 data: braces!(do_parse!(
1786 fields: call!(Delimited::parse_terminated) >>
1787 base: option!(
1788 cond!(fields.is_empty() || fields.trailing_delim(),
1789 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08001790 dots: punct!(..) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001791 base: syn!(Expr) >>
1792 (dots, base)
Alex Crichton954046c2017-05-30 21:49:42 -07001793 )
Michael Layzell92639a52017-06-01 00:07:44 -04001794 )
1795 ) >>
1796 (fields, base)
1797 )) >>
1798 ({
1799 let ((fields, base), brace) = data;
1800 let (dots, rest) = match base.and_then(|b| b) {
1801 Some((dots, base)) => (Some(dots), Some(base)),
1802 None => (None, None),
1803 };
1804 ExprStruct {
David Tolnay8c91b882017-12-28 23:04:32 -05001805 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001806 brace_token: brace,
1807 path: path,
1808 fields: fields,
1809 dot2_token: dots,
1810 rest: rest.map(Box::new),
1811 }
1812 })
1813 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001814 }
1815
Michael Layzell734adb42017-06-07 16:58:31 -04001816 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001817 impl Synom for FieldValue {
Michael Layzell92639a52017-06-01 00:07:44 -04001818 named!(parse -> Self, alt!(
1819 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05001820 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001821 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001822 value: syn!(Expr) >>
1823 (FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001824 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04001825 expr: value,
1826 is_shorthand: false,
Alex Crichton954046c2017-05-30 21:49:42 -07001827 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001828 colon_token: Some(colon),
Alex Crichton954046c2017-05-30 21:49:42 -07001829 })
Michael Layzell92639a52017-06-01 00:07:44 -04001830 )
1831 |
David Tolnaybc7d7d92017-06-03 20:54:05 -07001832 map!(syn!(Ident), |name| FieldValue {
David Tolnay85b69a42017-12-27 20:43:10 -05001833 member: Member::Named(name),
David Tolnay8c91b882017-12-28 23:04:32 -05001834 expr: Expr::Path(ExprPath {
1835 attrs: Vec::new(),
1836 qself: None,
1837 path: name.into(),
1838 }).into(),
Michael Layzell92639a52017-06-01 00:07:44 -04001839 is_shorthand: true,
1840 attrs: Vec::new(),
1841 colon_token: None,
1842 })
1843 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001844 }
David Tolnay055a7042016-10-02 19:23:54 -07001845
Michael Layzell734adb42017-06-07 16:58:31 -04001846 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001847 impl Synom for ExprRepeat {
Michael Layzell92639a52017-06-01 00:07:44 -04001848 named!(parse -> Self, do_parse!(
1849 data: brackets!(do_parse!(
1850 value: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001851 semi: punct!(;) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001852 times: syn!(Expr) >>
1853 (value, semi, times)
1854 )) >>
1855 (ExprRepeat {
David Tolnay8c91b882017-12-28 23:04:32 -05001856 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001857 expr: Box::new((data.0).0),
1858 amt: Box::new((data.0).2),
1859 bracket_token: data.1,
1860 semi_token: (data.0).1,
1861 })
1862 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001863 }
David Tolnay055a7042016-10-02 19:23:54 -07001864
Michael Layzell734adb42017-06-07 16:58:31 -04001865 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05001866 impl Synom for ExprUnsafe {
1867 named!(parse -> Self, do_parse!(
1868 unsafe_: keyword!(unsafe) >>
1869 b: syn!(Block) >>
1870 (ExprUnsafe {
David Tolnay8c91b882017-12-28 23:04:32 -05001871 attrs: Vec::new(),
Nika Layzell640832a2017-12-04 13:37:09 -05001872 unsafe_token: unsafe_,
1873 block: b,
1874 })
1875 ));
1876 }
1877
1878 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001879 impl Synom for ExprBlock {
Michael Layzell92639a52017-06-01 00:07:44 -04001880 named!(parse -> Self, do_parse!(
Michael Layzell92639a52017-06-01 00:07:44 -04001881 b: syn!(Block) >>
1882 (ExprBlock {
David Tolnay8c91b882017-12-28 23:04:32 -05001883 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001884 block: b,
1885 })
1886 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001887 }
David Tolnay89e05672016-10-02 14:39:42 -07001888
Michael Layzell734adb42017-06-07 16:58:31 -04001889 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05001890 named!(expr_range(allow_struct: bool) -> Expr, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07001891 limits: syn!(RangeLimits) >>
Michael Layzellb78f3b52017-06-04 19:03:03 -04001892 hi: opt_ambiguous_expr!(allow_struct) >>
David Tolnay8c91b882017-12-28 23:04:32 -05001893 (ExprRange {
1894 attrs: Vec::new(),
1895 from: None,
1896 to: hi.map(Box::new),
1897 limits: limits,
1898 }.into())
David Tolnay438c9052016-10-07 23:24:48 -07001899 ));
1900
Michael Layzell734adb42017-06-07 16:58:31 -04001901 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001902 impl Synom for RangeLimits {
Michael Layzell92639a52017-06-01 00:07:44 -04001903 named!(parse -> Self, alt!(
1904 // Must come before Dot2
David Tolnaybe55d7b2017-12-17 23:41:20 -08001905 punct!(..=) => { RangeLimits::Closed }
1906 |
1907 // Must come before Dot2
David Tolnay995bff22017-12-17 23:44:43 -08001908 punct!(...) => { |dot3| RangeLimits::Closed(Token![..=](dot3.0)) }
Michael Layzell92639a52017-06-01 00:07:44 -04001909 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08001910 punct!(..) => { RangeLimits::HalfOpen }
Michael Layzell92639a52017-06-01 00:07:44 -04001911 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001912 }
David Tolnay438c9052016-10-07 23:24:48 -07001913
Alex Crichton954046c2017-05-30 21:49:42 -07001914 impl Synom for ExprPath {
Michael Layzell92639a52017-06-01 00:07:44 -04001915 named!(parse -> Self, do_parse!(
1916 pair: qpath >>
1917 (ExprPath {
David Tolnay8c91b882017-12-28 23:04:32 -05001918 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04001919 qself: pair.0,
1920 path: pair.1,
1921 })
1922 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001923 }
David Tolnay42602292016-10-01 22:25:45 -07001924
Michael Layzell734adb42017-06-07 16:58:31 -04001925 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05001926 named!(and_field -> (Token![.], Member), tuple!(punct!(.), syn!(Member)));
David Tolnay438c9052016-10-07 23:24:48 -07001927
David Tolnay32954ef2017-12-26 22:43:16 -05001928 named!(and_index -> (Expr, token::Bracket), brackets!(syn!(Expr)));
David Tolnay438c9052016-10-07 23:24:48 -07001929
Michael Layzell734adb42017-06-07 16:58:31 -04001930 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001931 impl Synom for Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001932 named!(parse -> Self, do_parse!(
1933 stmts: braces!(call!(Block::parse_within)) >>
1934 (Block {
1935 stmts: stmts.0,
1936 brace_token: stmts.1,
1937 })
1938 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001939 }
David Tolnay939766a2016-09-23 23:48:12 -07001940
Michael Layzell734adb42017-06-07 16:58:31 -04001941 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001942 impl Block {
Michael Layzell92639a52017-06-01 00:07:44 -04001943 named!(pub parse_within -> Vec<Stmt>, do_parse!(
David Tolnay4699a312017-12-27 14:39:22 -05001944 many0!(punct!(;)) >>
1945 mut standalone: many0!(terminated!(syn!(Stmt), many0!(punct!(;)))) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001946 last: option!(do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001947 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton70bbd592017-08-27 10:40:03 -07001948 mut e: syn!(Expr) >>
1949 ({
David Tolnay8c91b882017-12-28 23:04:32 -05001950 *e.attrs_mut() = attrs;
Alex Crichton70bbd592017-08-27 10:40:03 -07001951 Stmt::Expr(Box::new(e))
1952 })
1953 )) >>
Michael Layzell92639a52017-06-01 00:07:44 -04001954 (match last {
1955 None => standalone,
1956 Some(last) => {
Alex Crichton70bbd592017-08-27 10:40:03 -07001957 standalone.push(last);
Michael Layzell92639a52017-06-01 00:07:44 -04001958 standalone
1959 }
1960 })
1961 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001962 }
1963
Michael Layzell734adb42017-06-07 16:58:31 -04001964 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07001965 impl Synom for Stmt {
Michael Layzell92639a52017-06-01 00:07:44 -04001966 named!(parse -> Self, alt!(
1967 stmt_mac
1968 |
1969 stmt_local
1970 |
1971 stmt_item
1972 |
Michael Layzell35418782017-06-07 09:20:25 -04001973 stmt_blockexpr
1974 |
Michael Layzell92639a52017-06-01 00:07:44 -04001975 stmt_expr
1976 ));
Alex Crichton954046c2017-05-30 21:49:42 -07001977 }
David Tolnay939766a2016-09-23 23:48:12 -07001978
Michael Layzell734adb42017-06-07 16:58:31 -04001979 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07001980 named!(stmt_mac -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05001981 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07001982 what: syn!(Path) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001983 bang: punct!(!) >>
David Tolnayeea28d62016-10-25 20:44:08 -07001984 // Only parse braces here; paren and bracket will get parsed as
1985 // expression statements
Alex Crichton954046c2017-05-30 21:49:42 -07001986 data: braces!(syn!(TokenStream)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08001987 semi: option!(punct!(;)) >>
David Tolnay57b52bc2017-12-28 18:06:38 -05001988 (Stmt::Item(Box::new(Item::Macro(ItemMacro {
1989 attrs: attrs,
1990 ident: None,
1991 mac: Macro {
David Tolnay5d55ef72016-12-21 20:20:04 -05001992 path: what,
Alex Crichton954046c2017-05-30 21:49:42 -07001993 bang_token: bang,
David Tolnay369f0c52017-12-27 01:50:45 -05001994 tokens: proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -05001995 span: (data.1).0,
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -07001996 kind: TokenNode::Group(Delimiter::Brace, data.0),
David Tolnay369f0c52017-12-27 01:50:45 -05001997 },
David Tolnayeea28d62016-10-25 20:44:08 -07001998 },
David Tolnay57b52bc2017-12-28 18:06:38 -05001999 semi_token: semi,
2000 }))))
David Tolnay13b3d352016-10-03 00:31:15 -07002001 ));
2002
Michael Layzell734adb42017-06-07 16:58:31 -04002003 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07002004 named!(stmt_local -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002005 attrs: many0!(Attribute::parse_outer) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002006 let_: keyword!(let) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002007 pat: syn!(Pat) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -08002008 ty: option!(tuple!(punct!(:), syn!(Type))) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002009 init: option!(tuple!(punct!(=), syn!(Expr))) >>
2010 semi: punct!(;) >>
David Tolnay191e0582016-10-02 18:31:09 -07002011 (Stmt::Local(Box::new(Local {
Alex Crichton954046c2017-05-30 21:49:42 -07002012 let_token: let_,
2013 semi_token: semi,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002014 colon_token: ty.as_ref().map(|p| Token![:]((p.0).0)),
2015 eq_token: init.as_ref().map(|p| Token![=]((p.0).0)),
David Tolnay191e0582016-10-02 18:31:09 -07002016 pat: Box::new(pat),
Alex Crichton954046c2017-05-30 21:49:42 -07002017 ty: ty.map(|p| Box::new(p.1)),
2018 init: init.map(|p| Box::new(p.1)),
David Tolnay191e0582016-10-02 18:31:09 -07002019 attrs: attrs,
2020 })))
2021 ));
2022
Michael Layzell734adb42017-06-07 16:58:31 -04002023 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002024 named!(stmt_item -> Stmt, map!(syn!(Item), |i| Stmt::Item(Box::new(i))));
David Tolnay191e0582016-10-02 18:31:09 -07002025
Michael Layzell734adb42017-06-07 16:58:31 -04002026 #[cfg(feature = "full")]
Michael Layzell35418782017-06-07 09:20:25 -04002027 named!(stmt_blockexpr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002028 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell35418782017-06-07 09:20:25 -04002029 mut e: expr_nosemi >>
2030 // If the next token is a `.` or a `?` it is special-cased to parse as
2031 // an expression instead of a blockexpression.
David Tolnayf8db7ba2017-11-11 22:52:16 -08002032 not!(punct!(.)) >>
2033 not!(punct!(?)) >>
2034 semi: option!(punct!(;)) >>
Michael Layzell35418782017-06-07 09:20:25 -04002035 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002036 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002037 if let Some(semi) = semi {
2038 Stmt::Semi(Box::new(e), semi)
2039 } else {
2040 Stmt::Expr(Box::new(e))
2041 }
2042 })
2043 ));
David Tolnaycfe55022016-10-02 22:02:27 -07002044
Michael Layzell734adb42017-06-07 16:58:31 -04002045 #[cfg(feature = "full")]
David Tolnaycfe55022016-10-02 22:02:27 -07002046 named!(stmt_expr -> Stmt, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -05002047 attrs: many0!(Attribute::parse_outer) >>
Alex Crichton954046c2017-05-30 21:49:42 -07002048 mut e: syn!(Expr) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002049 semi: punct!(;) >>
David Tolnay7184b132016-10-30 10:06:37 -07002050 ({
David Tolnay8c91b882017-12-28 23:04:32 -05002051 *e.attrs_mut() = attrs;
Michael Layzell35418782017-06-07 09:20:25 -04002052 Stmt::Semi(Box::new(e), semi)
David Tolnaycfe55022016-10-02 22:02:27 -07002053 })
David Tolnay939766a2016-09-23 23:48:12 -07002054 ));
David Tolnay8b07f372016-09-30 10:28:40 -07002055
Michael Layzell734adb42017-06-07 16:58:31 -04002056 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002057 impl Synom for Pat {
Michael Layzell92639a52017-06-01 00:07:44 -04002058 named!(parse -> Self, alt!(
2059 syn!(PatWild) => { Pat::Wild } // must be before pat_ident
2060 |
2061 syn!(PatBox) => { Pat::Box } // must be before pat_ident
2062 |
2063 syn!(PatRange) => { Pat::Range } // must be before pat_lit
2064 |
2065 syn!(PatTupleStruct) => { Pat::TupleStruct } // must be before pat_ident
2066 |
2067 syn!(PatStruct) => { Pat::Struct } // must be before pat_ident
2068 |
David Tolnaydecf28d2017-11-11 11:56:45 -08002069 syn!(Macro) => { Pat::Macro } // must be before pat_ident
Michael Layzell92639a52017-06-01 00:07:44 -04002070 |
2071 syn!(PatLit) => { Pat::Lit } // must be before pat_ident
2072 |
2073 syn!(PatIdent) => { Pat::Ident } // must be before pat_path
2074 |
2075 syn!(PatPath) => { Pat::Path }
2076 |
2077 syn!(PatTuple) => { Pat::Tuple }
2078 |
2079 syn!(PatRef) => { Pat::Ref }
2080 |
2081 syn!(PatSlice) => { Pat::Slice }
2082 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002083 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002084
Michael Layzell734adb42017-06-07 16:58:31 -04002085 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002086 impl Synom for PatWild {
Michael Layzell92639a52017-06-01 00:07:44 -04002087 named!(parse -> Self, map!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002088 punct!(_),
Michael Layzell92639a52017-06-01 00:07:44 -04002089 |u| PatWild { underscore_token: u }
2090 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002091 }
David Tolnay84aa0752016-10-02 23:01:13 -07002092
Michael Layzell734adb42017-06-07 16:58:31 -04002093 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002094 impl Synom for PatBox {
Michael Layzell92639a52017-06-01 00:07:44 -04002095 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002096 boxed: keyword!(box) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002097 pat: syn!(Pat) >>
2098 (PatBox {
2099 pat: Box::new(pat),
2100 box_token: boxed,
2101 })
2102 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002103 }
2104
Michael Layzell734adb42017-06-07 16:58:31 -04002105 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002106 impl Synom for PatIdent {
Michael Layzell92639a52017-06-01 00:07:44 -04002107 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002108 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002109 mutability: syn!(Mutability) >>
2110 name: alt!(
2111 syn!(Ident)
2112 |
David Tolnayf8db7ba2017-11-11 22:52:16 -08002113 keyword!(self) => { Into::into }
Michael Layzell92639a52017-06-01 00:07:44 -04002114 ) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002115 not!(punct!(<)) >>
2116 not!(punct!(::)) >>
2117 subpat: option!(tuple!(punct!(@), syn!(Pat))) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002118 (PatIdent {
2119 mode: match mode {
2120 Some(mode) => BindingMode::ByRef(mode, mutability),
2121 None => BindingMode::ByValue(mutability),
2122 },
2123 ident: name,
David Tolnayf8db7ba2017-11-11 22:52:16 -08002124 at_token: subpat.as_ref().map(|p| Token![@]((p.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002125 subpat: subpat.map(|p| Box::new(p.1)),
2126 })
2127 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002128 }
2129
Michael Layzell734adb42017-06-07 16:58:31 -04002130 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002131 impl Synom for PatTupleStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002132 named!(parse -> Self, do_parse!(
2133 path: syn!(Path) >>
2134 tuple: syn!(PatTuple) >>
2135 (PatTupleStruct {
2136 path: path,
2137 pat: tuple,
2138 })
2139 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002140 }
2141
Michael Layzell734adb42017-06-07 16:58:31 -04002142 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002143 impl Synom for PatStruct {
Michael Layzell92639a52017-06-01 00:07:44 -04002144 named!(parse -> Self, do_parse!(
2145 path: syn!(Path) >>
2146 data: braces!(do_parse!(
2147 fields: call!(Delimited::parse_terminated) >>
2148 base: option!(
2149 cond!(fields.is_empty() || fields.trailing_delim(),
David Tolnayf8db7ba2017-11-11 22:52:16 -08002150 punct!(..))
Michael Layzell92639a52017-06-01 00:07:44 -04002151 ) >>
2152 (fields, base)
2153 )) >>
2154 (PatStruct {
2155 path: path,
2156 fields: (data.0).0,
2157 brace_token: data.1,
2158 dot2_token: (data.0).1.and_then(|m| m),
2159 })
2160 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002161 }
2162
Michael Layzell734adb42017-06-07 16:58:31 -04002163 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002164 impl Synom for FieldPat {
Michael Layzell92639a52017-06-01 00:07:44 -04002165 named!(parse -> Self, alt!(
2166 do_parse!(
David Tolnay85b69a42017-12-27 20:43:10 -05002167 member: syn!(Member) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -08002168 colon: punct!(:) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002169 pat: syn!(Pat) >>
2170 (FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002171 member: member,
Michael Layzell92639a52017-06-01 00:07:44 -04002172 pat: Box::new(pat),
2173 is_shorthand: false,
2174 attrs: Vec::new(),
2175 colon_token: Some(colon),
2176 })
2177 )
2178 |
2179 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002180 boxed: option!(keyword!(box)) >>
2181 mode: option!(keyword!(ref)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002182 mutability: syn!(Mutability) >>
2183 ident: syn!(Ident) >>
2184 ({
2185 let mut pat: Pat = PatIdent {
2186 mode: if let Some(mode) = mode {
2187 BindingMode::ByRef(mode, mutability)
2188 } else {
2189 BindingMode::ByValue(mutability)
2190 },
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002191 ident: ident,
Michael Layzell92639a52017-06-01 00:07:44 -04002192 subpat: None,
2193 at_token: None,
2194 }.into();
2195 if let Some(boxed) = boxed {
2196 pat = PatBox {
2197 pat: Box::new(pat),
2198 box_token: boxed,
2199 }.into();
2200 }
2201 FieldPat {
David Tolnay85b69a42017-12-27 20:43:10 -05002202 member: Member::Named(ident),
Alex Crichton954046c2017-05-30 21:49:42 -07002203 pat: Box::new(pat),
Michael Layzell92639a52017-06-01 00:07:44 -04002204 is_shorthand: true,
Alex Crichton954046c2017-05-30 21:49:42 -07002205 attrs: Vec::new(),
Michael Layzell92639a52017-06-01 00:07:44 -04002206 colon_token: None,
2207 }
2208 })
2209 )
2210 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002211 }
2212
Michael Layzell734adb42017-06-07 16:58:31 -04002213 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002214 impl Synom for Member {
2215 named!(parse -> Self, alt!(
2216 syn!(Ident) => { Member::Named }
2217 |
2218 syn!(Index) => { Member::Unnamed }
2219 ));
2220 }
2221
2222 #[cfg(feature = "full")]
2223 impl Synom for Index {
2224 named!(parse -> Self, do_parse!(
Alex Crichton954046c2017-05-30 21:49:42 -07002225 lit: syn!(Lit) >>
2226 ({
David Tolnay85b69a42017-12-27 20:43:10 -05002227 if let Ok(i) = lit.value.to_string().parse() {
2228 Index { index: i, span: lit.span }
Alex Crichton954046c2017-05-30 21:49:42 -07002229 } else {
Michael Layzell92639a52017-06-01 00:07:44 -04002230 return parse_error();
David Tolnayda167382016-10-30 13:34:09 -07002231 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002232 })
David Tolnay85b69a42017-12-27 20:43:10 -05002233 ));
2234 }
David Tolnay8d9e81a2016-10-03 22:36:32 -07002235
Michael Layzell734adb42017-06-07 16:58:31 -04002236 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002237 impl Synom for PatPath {
Michael Layzell92639a52017-06-01 00:07:44 -04002238 named!(parse -> Self, map!(
2239 syn!(ExprPath),
David Tolnaybc7d7d92017-06-03 20:54:05 -07002240 |p| PatPath { qself: p.qself, path: p.path }
Michael Layzell92639a52017-06-01 00:07:44 -04002241 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002242 }
David Tolnay9636c052016-10-02 17:11:17 -07002243
Michael Layzell734adb42017-06-07 16:58:31 -04002244 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002245 impl Synom for PatTuple {
Michael Layzell92639a52017-06-01 00:07:44 -04002246 named!(parse -> Self, do_parse!(
2247 data: parens!(do_parse!(
2248 elems: call!(Delimited::parse_terminated) >>
2249 dotdot: map!(cond!(
2250 elems.is_empty() || elems.trailing_delim(),
2251 option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002252 dots: punct!(..) >>
2253 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002254 (dots, trailing)
2255 ))
David Tolnaybc7d7d92017-06-03 20:54:05 -07002256 ), |x| x.and_then(|x| x)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002257 rest: cond!(match dotdot {
2258 Some((_, Some(_))) => true,
2259 _ => false,
2260 },
2261 call!(Delimited::parse_terminated)) >>
2262 (elems, dotdot, rest)
2263 )) >>
2264 ({
2265 let ((mut elems, dotdot, rest), parens) = data;
2266 let (dotdot, trailing) = match dotdot {
2267 Some((a, b)) => (Some(a), Some(b)),
2268 None => (None, None),
2269 };
2270 PatTuple {
2271 paren_token: parens,
2272 dots_pos: dotdot.as_ref().map(|_| elems.len()),
2273 dot2_token: dotdot,
2274 comma_token: trailing.and_then(|b| b),
2275 pats: {
2276 if let Some(rest) = rest {
2277 for elem in rest {
2278 elems.push(elem);
Alex Crichton954046c2017-05-30 21:49:42 -07002279 }
Michael Layzell92639a52017-06-01 00:07:44 -04002280 }
2281 elems
2282 },
2283 }
2284 })
2285 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002286 }
David Tolnayfbb73232016-10-03 01:00:06 -07002287
Michael Layzell734adb42017-06-07 16:58:31 -04002288 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002289 impl Synom for PatRef {
Michael Layzell92639a52017-06-01 00:07:44 -04002290 named!(parse -> Self, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002291 and: punct!(&) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002292 mutability: syn!(Mutability) >>
2293 pat: syn!(Pat) >>
2294 (PatRef {
2295 pat: Box::new(pat),
2296 mutbl: mutability,
2297 and_token: and,
2298 })
2299 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002300 }
David Tolnayffdb97f2016-10-03 01:28:33 -07002301
Michael Layzell734adb42017-06-07 16:58:31 -04002302 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002303 impl Synom for PatLit {
Michael Layzell92639a52017-06-01 00:07:44 -04002304 named!(parse -> Self, do_parse!(
2305 lit: pat_lit_expr >>
David Tolnay8c91b882017-12-28 23:04:32 -05002306 (if let Expr::Path(_) = lit {
Michael Layzell92639a52017-06-01 00:07:44 -04002307 return parse_error(); // these need to be parsed by pat_path
2308 } else {
2309 PatLit {
2310 expr: Box::new(lit),
2311 }
2312 })
2313 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002314 }
David Tolnaye1310902016-10-29 23:40:00 -07002315
Michael Layzell734adb42017-06-07 16:58:31 -04002316 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002317 impl Synom for PatRange {
Michael Layzell92639a52017-06-01 00:07:44 -04002318 named!(parse -> Self, do_parse!(
2319 lo: pat_lit_expr >>
2320 limits: syn!(RangeLimits) >>
2321 hi: pat_lit_expr >>
2322 (PatRange {
2323 lo: Box::new(lo),
2324 hi: Box::new(hi),
2325 limits: limits,
2326 })
2327 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002328 }
David Tolnaye1310902016-10-29 23:40:00 -07002329
Michael Layzell734adb42017-06-07 16:58:31 -04002330 #[cfg(feature = "full")]
David Tolnay2cfddc62016-10-30 01:03:27 -07002331 named!(pat_lit_expr -> Expr, do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002332 neg: option!(punct!(-)) >>
David Tolnay2cfddc62016-10-30 01:03:27 -07002333 v: alt!(
David Tolnay8c91b882017-12-28 23:04:32 -05002334 syn!(ExprLit) => { Expr::Lit }
David Tolnay2cfddc62016-10-30 01:03:27 -07002335 |
David Tolnay8c91b882017-12-28 23:04:32 -05002336 syn!(ExprPath) => { Expr::Path }
David Tolnay2cfddc62016-10-30 01:03:27 -07002337 ) >>
David Tolnayc29b9892017-12-27 22:58:14 -05002338 (if let Some(neg) = neg {
David Tolnay8c91b882017-12-28 23:04:32 -05002339 Expr::Unary(ExprUnary {
2340 attrs: Vec::new(),
David Tolnayc29b9892017-12-27 22:58:14 -05002341 op: UnOp::Neg(neg),
Alex Crichton62a0a592017-05-22 13:58:53 -07002342 expr: Box::new(v.into())
2343 }).into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002344 } else {
David Tolnay7184b132016-10-30 10:06:37 -07002345 v.into()
David Tolnay0ad9e9f2016-10-29 22:20:02 -07002346 })
2347 ));
David Tolnay8b308c22016-10-03 01:24:10 -07002348
Michael Layzell734adb42017-06-07 16:58:31 -04002349 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002350 impl Synom for PatSlice {
Michael Layzell92639a52017-06-01 00:07:44 -04002351 named!(parse -> Self, map!(
2352 brackets!(do_parse!(
2353 before: call!(Delimited::parse_terminated) >>
2354 middle: option!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002355 dots: punct!(..) >>
2356 trailing: option!(punct!(,)) >>
Michael Layzell92639a52017-06-01 00:07:44 -04002357 (dots, trailing)
2358 )) >>
2359 after: cond!(
2360 match middle {
2361 Some((_, ref trailing)) => trailing.is_some(),
2362 _ => false,
2363 },
2364 call!(Delimited::parse_terminated)
2365 ) >>
2366 (before, middle, after)
2367 )),
2368 |((before, middle, after), brackets)| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002369 let mut before: Delimited<Pat, Token![,]> = before;
2370 let after: Option<Delimited<Pat, Token![,]>> = after;
2371 let middle: Option<(Token![..], Option<Token![,]>)> = middle;
Michael Layzell92639a52017-06-01 00:07:44 -04002372 PatSlice {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002373 dot2_token: middle.as_ref().map(|m| Token![..]((m.0).0)),
Michael Layzell92639a52017-06-01 00:07:44 -04002374 comma_token: middle.as_ref().and_then(|m| {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002375 m.1.as_ref().map(|m| Token![,](m.0))
Michael Layzell92639a52017-06-01 00:07:44 -04002376 }),
2377 bracket_token: brackets,
2378 middle: middle.and_then(|_| {
2379 if !before.is_empty() && !before.trailing_delim() {
2380 Some(Box::new(before.pop().unwrap().into_item()))
2381 } else {
2382 None
2383 }
2384 }),
2385 front: before,
2386 back: after.unwrap_or_default(),
David Tolnaye1f13c32016-10-29 23:34:40 -07002387 }
Alex Crichton954046c2017-05-30 21:49:42 -07002388 }
Michael Layzell92639a52017-06-01 00:07:44 -04002389 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002390 }
David Tolnay435a9a82016-10-29 13:47:20 -07002391
Michael Layzell734adb42017-06-07 16:58:31 -04002392 #[cfg(feature = "full")]
Alex Crichton954046c2017-05-30 21:49:42 -07002393 impl Synom for CaptureBy {
Michael Layzell92639a52017-06-01 00:07:44 -04002394 named!(parse -> Self, alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -08002395 keyword!(move) => { CaptureBy::Value }
Michael Layzell92639a52017-06-01 00:07:44 -04002396 |
2397 epsilon!() => { |_| CaptureBy::Ref }
2398 ));
Alex Crichton954046c2017-05-30 21:49:42 -07002399 }
David Tolnayb9c8e322016-09-23 20:48:37 -07002400}
2401
David Tolnayf4bbbd92016-09-23 14:41:55 -07002402#[cfg(feature = "printing")]
2403mod printing {
2404 use super::*;
Michael Layzell734adb42017-06-07 16:58:31 -04002405 #[cfg(feature = "full")]
David Tolnay13b3d352016-10-03 00:31:15 -07002406 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -05002407 use quote::{ToTokens, Tokens};
David Tolnay85b69a42017-12-27 20:43:10 -05002408 #[cfg(feature = "full")]
2409 use proc_macro2::{TokenTree, TokenNode, Literal};
David Tolnayf4bbbd92016-09-23 14:41:55 -07002410
David Tolnaybcf26022017-12-25 22:10:52 -05002411 // If the given expression is a bare `ExprStruct`, wraps it in parenthesis
2412 // before appending it to `Tokens`.
Michael Layzell3936ceb2017-07-08 00:28:36 -04002413 #[cfg(feature = "full")]
2414 fn wrap_bare_struct(tokens: &mut Tokens, e: &Expr) {
David Tolnay8c91b882017-12-28 23:04:32 -05002415 if let Expr::Struct(_) = *e {
David Tolnay32954ef2017-12-26 22:43:16 -05002416 token::Paren::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002417 e.to_tokens(tokens);
2418 });
2419 } else {
2420 e.to_tokens(tokens);
2421 }
2422 }
2423
David Tolnay8c91b882017-12-28 23:04:32 -05002424 #[cfg(feature = "full")]
2425 fn attrs_to_tokens(attrs: &[Attribute], tokens: &mut Tokens) {
2426 tokens.append_all(attrs.outer());
2427 }
Michael Layzell734adb42017-06-07 16:58:31 -04002428
David Tolnay8c91b882017-12-28 23:04:32 -05002429 #[cfg(not(feature = "full"))]
2430 fn attrs_to_tokens(_attrs: &[Attribute], _tokens: &mut Tokens) {
Alex Crichton62a0a592017-05-22 13:58:53 -07002431 }
2432
Michael Layzell734adb42017-06-07 16:58:31 -04002433 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002434 impl ToTokens for ExprBox {
2435 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002436 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002437 self.box_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002438 self.expr.to_tokens(tokens);
2439 }
2440 }
2441
Michael Layzell734adb42017-06-07 16:58:31 -04002442 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002443 impl ToTokens for ExprInPlace {
2444 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002445 tokens.append_all(self.attrs.outer());
David Tolnay8701a5c2017-12-28 23:31:10 -05002446 self.place.to_tokens(tokens);
2447 self.arrow_token.to_tokens(tokens);
2448 self.value.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002449 }
2450 }
2451
Michael Layzell734adb42017-06-07 16:58:31 -04002452 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002453 impl ToTokens for ExprArray {
2454 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002455 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002456 self.bracket_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002457 self.elems.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002458 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002459 }
2460 }
2461
2462 impl ToTokens for ExprCall {
2463 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002464 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002465 self.func.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002466 self.paren_token.surround(tokens, |tokens| {
2467 self.args.to_tokens(tokens);
2468 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002469 }
2470 }
2471
Michael Layzell734adb42017-06-07 16:58:31 -04002472 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002473 impl ToTokens for ExprMethodCall {
2474 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002475 tokens.append_all(self.attrs.outer());
David Tolnay76418512017-12-28 23:47:47 -05002476 self.receiver.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002477 self.dot_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002478 self.method.to_tokens(tokens);
David Tolnayd60cfec2017-12-29 00:21:38 -05002479 self.turbofish.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002480 self.paren_token.surround(tokens, |tokens| {
2481 self.args.to_tokens(tokens);
2482 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002483 }
2484 }
2485
Michael Layzell734adb42017-06-07 16:58:31 -04002486 #[cfg(feature = "full")]
David Tolnayd60cfec2017-12-29 00:21:38 -05002487 impl ToTokens for MethodTurbofish {
2488 fn to_tokens(&self, tokens: &mut Tokens) {
2489 self.colon2_token.to_tokens(tokens);
2490 self.lt_token.to_tokens(tokens);
2491 self.args.to_tokens(tokens);
2492 self.gt_token.to_tokens(tokens);
2493 }
2494 }
2495
2496 #[cfg(feature = "full")]
2497 impl ToTokens for GenericMethodArgument {
2498 fn to_tokens(&self, tokens: &mut Tokens) {
2499 match *self {
2500 GenericMethodArgument::Type(ref t) => t.to_tokens(tokens),
2501 GenericMethodArgument::Const(ref c) => c.to_tokens(tokens),
2502 }
2503 }
2504 }
2505
2506 #[cfg(feature = "full")]
David Tolnay05362582017-12-26 01:33:57 -05002507 impl ToTokens for ExprTuple {
Alex Crichton62a0a592017-05-22 13:58:53 -07002508 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002509 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002510 self.paren_token.surround(tokens, |tokens| {
David Tolnay2a86fdd2017-12-28 23:34:28 -05002511 self.elems.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002512 // If we only have one argument, we need a trailing comma to
David Tolnay05362582017-12-26 01:33:57 -05002513 // distinguish ExprTuple from ExprParen.
David Tolnay2a86fdd2017-12-28 23:34:28 -05002514 if self.elems.len() == 1 && !self.elems.trailing_delim() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002515 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002516 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002517 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002518 }
2519 }
2520
2521 impl ToTokens for ExprBinary {
2522 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002523 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002524 self.left.to_tokens(tokens);
2525 self.op.to_tokens(tokens);
2526 self.right.to_tokens(tokens);
2527 }
2528 }
2529
2530 impl ToTokens for ExprUnary {
2531 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002532 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002533 self.op.to_tokens(tokens);
2534 self.expr.to_tokens(tokens);
2535 }
2536 }
2537
David Tolnay8c91b882017-12-28 23:04:32 -05002538 impl ToTokens for ExprLit {
2539 fn to_tokens(&self, tokens: &mut Tokens) {
2540 attrs_to_tokens(&self.attrs, tokens);
2541 self.lit.to_tokens(tokens);
2542 }
2543 }
2544
Alex Crichton62a0a592017-05-22 13:58:53 -07002545 impl ToTokens for ExprCast {
2546 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002547 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002548 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002549 self.as_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002550 self.ty.to_tokens(tokens);
2551 }
2552 }
2553
David Tolnay0cf94f22017-12-28 23:46:26 -05002554 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002555 impl ToTokens for ExprType {
2556 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002557 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002558 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002559 self.colon_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002560 self.ty.to_tokens(tokens);
2561 }
2562 }
2563
Michael Layzell734adb42017-06-07 16:58:31 -04002564 #[cfg(feature = "full")]
David Tolnay51382052017-12-27 13:46:21 -05002565 fn maybe_wrap_else(
2566 tokens: &mut Tokens,
2567 else_token: &Option<Token![else]>,
2568 if_false: &Option<Box<Expr>>,
2569 ) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002570 if let Some(ref if_false) = *if_false {
David Tolnaybb4ca9f2017-12-26 12:28:58 -05002571 TokensOrDefault(else_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002572
2573 // If we are not one of the valid expressions to exist in an else
2574 // clause, wrap ourselves in a block.
David Tolnay8c91b882017-12-28 23:04:32 -05002575 match **if_false {
2576 Expr::If(_) | Expr::IfLet(_) | Expr::Block(_) => {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002577 if_false.to_tokens(tokens);
2578 }
2579 _ => {
David Tolnay32954ef2017-12-26 22:43:16 -05002580 token::Brace::default().surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002581 if_false.to_tokens(tokens);
2582 });
2583 }
2584 }
2585 }
2586 }
2587
2588 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002589 impl ToTokens for ExprIf {
2590 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002591 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002592 self.if_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002593 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002594 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002595 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002596 }
2597 }
2598
Michael Layzell734adb42017-06-07 16:58:31 -04002599 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002600 impl ToTokens for ExprIfLet {
2601 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002602 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002603 self.if_token.to_tokens(tokens);
2604 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002605 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002606 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002607 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002608 self.if_true.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002609 maybe_wrap_else(tokens, &self.else_token, &self.if_false);
Alex Crichton62a0a592017-05-22 13:58:53 -07002610 }
2611 }
2612
Michael Layzell734adb42017-06-07 16:58:31 -04002613 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002614 impl ToTokens for ExprWhile {
2615 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002616 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002617 if self.label.is_some() {
2618 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002619 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002620 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002621 self.while_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002622 wrap_bare_struct(tokens, &self.cond);
Alex Crichton62a0a592017-05-22 13:58:53 -07002623 self.body.to_tokens(tokens);
2624 }
2625 }
2626
Michael Layzell734adb42017-06-07 16:58:31 -04002627 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002628 impl ToTokens for ExprWhileLet {
2629 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002630 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002631 if self.label.is_some() {
2632 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002633 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002634 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002635 self.while_token.to_tokens(tokens);
2636 self.let_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002637 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002638 self.eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002639 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002640 self.body.to_tokens(tokens);
2641 }
2642 }
2643
Michael Layzell734adb42017-06-07 16:58:31 -04002644 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002645 impl ToTokens for ExprForLoop {
2646 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002647 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002648 if self.label.is_some() {
2649 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002650 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002651 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002652 self.for_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002653 self.pat.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002654 self.in_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002655 wrap_bare_struct(tokens, &self.expr);
Alex Crichton62a0a592017-05-22 13:58:53 -07002656 self.body.to_tokens(tokens);
2657 }
2658 }
2659
Michael Layzell734adb42017-06-07 16:58:31 -04002660 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002661 impl ToTokens for ExprLoop {
2662 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002663 tokens.append_all(self.attrs.outer());
Michael Layzell3936ceb2017-07-08 00:28:36 -04002664 if self.label.is_some() {
2665 self.label.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07002666 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002667 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002668 self.loop_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002669 self.body.to_tokens(tokens);
2670 }
2671 }
2672
Michael Layzell734adb42017-06-07 16:58:31 -04002673 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002674 impl ToTokens for ExprMatch {
2675 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002676 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002677 self.match_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002678 wrap_bare_struct(tokens, &self.expr);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002679 self.brace_token.surround(tokens, |tokens| {
David Tolnay51382052017-12-27 13:46:21 -05002680 for (i, arm) in self.arms.iter().enumerate() {
Michael Layzell3936ceb2017-07-08 00:28:36 -04002681 arm.to_tokens(tokens);
2682 // Ensure that we have a comma after a non-block arm, except
2683 // for the last one.
2684 let is_last = i == self.arms.len() - 1;
Alex Crichton03b30272017-08-28 09:35:24 -07002685 if !is_last && arm_expr_requires_comma(&arm.body) && arm.comma.is_none() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002686 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002687 }
2688 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002689 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002690 }
2691 }
2692
Michael Layzell734adb42017-06-07 16:58:31 -04002693 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002694 impl ToTokens for ExprCatch {
2695 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002696 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002697 self.do_token.to_tokens(tokens);
2698 self.catch_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002699 self.block.to_tokens(tokens);
2700 }
2701 }
2702
Michael Layzell734adb42017-06-07 16:58:31 -04002703 #[cfg(feature = "full")]
Alex Crichtonfe110462017-06-01 12:49:27 -07002704 impl ToTokens for ExprYield {
2705 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002706 tokens.append_all(self.attrs.outer());
Alex Crichtonfe110462017-06-01 12:49:27 -07002707 self.yield_token.to_tokens(tokens);
2708 self.expr.to_tokens(tokens);
2709 }
2710 }
2711
2712 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002713 impl ToTokens for ExprClosure {
2714 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002715 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002716 self.capture.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002717 self.or1_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002718 for item in self.inputs.iter() {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002719 match **item.item() {
David Tolnay51382052017-12-27 13:46:21 -05002720 FnArg::Captured(ArgCaptured {
2721 ref pat,
2722 ty: Type::Infer(_),
2723 ..
2724 }) => {
Alex Crichton62a0a592017-05-22 13:58:53 -07002725 pat.to_tokens(tokens);
David Tolnay9636c052016-10-02 17:11:17 -07002726 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002727 _ => item.item().to_tokens(tokens),
David Tolnay3c2467c2016-10-02 17:55:08 -07002728 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002729 item.delimiter().to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002730 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002731 self.or2_token.to_tokens(tokens);
David Tolnay7f675742017-12-27 22:43:21 -05002732 self.output.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002733 self.body.to_tokens(tokens);
2734 }
2735 }
2736
Michael Layzell734adb42017-06-07 16:58:31 -04002737 #[cfg(feature = "full")]
Nika Layzell640832a2017-12-04 13:37:09 -05002738 impl ToTokens for ExprUnsafe {
2739 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002740 tokens.append_all(self.attrs.outer());
Nika Layzell640832a2017-12-04 13:37:09 -05002741 self.unsafe_token.to_tokens(tokens);
2742 self.block.to_tokens(tokens);
2743 }
2744 }
2745
2746 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002747 impl ToTokens for ExprBlock {
2748 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002749 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002750 self.block.to_tokens(tokens);
2751 }
2752 }
2753
Michael Layzell734adb42017-06-07 16:58:31 -04002754 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002755 impl ToTokens for ExprAssign {
2756 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002757 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002758 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002759 self.eq_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002760 self.right.to_tokens(tokens);
2761 }
2762 }
2763
Michael Layzell734adb42017-06-07 16:58:31 -04002764 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002765 impl ToTokens for ExprAssignOp {
2766 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002767 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002768 self.left.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002769 self.op.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002770 self.right.to_tokens(tokens);
2771 }
2772 }
2773
Michael Layzell734adb42017-06-07 16:58:31 -04002774 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002775 impl ToTokens for ExprField {
2776 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002777 tokens.append_all(self.attrs.outer());
David Tolnay85b69a42017-12-27 20:43:10 -05002778 self.base.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002779 self.dot_token.to_tokens(tokens);
David Tolnay85b69a42017-12-27 20:43:10 -05002780 self.member.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002781 }
2782 }
2783
Michael Layzell734adb42017-06-07 16:58:31 -04002784 #[cfg(feature = "full")]
David Tolnay85b69a42017-12-27 20:43:10 -05002785 impl ToTokens for Member {
Alex Crichton62a0a592017-05-22 13:58:53 -07002786 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002787 match *self {
2788 Member::Named(ident) => ident.to_tokens(tokens),
2789 Member::Unnamed(ref index) => index.to_tokens(tokens),
2790 }
2791 }
2792 }
2793
2794 #[cfg(feature = "full")]
2795 impl ToTokens for Index {
2796 fn to_tokens(&self, tokens: &mut Tokens) {
2797 tokens.append(TokenTree {
2798 span: self.span,
David Tolnay9bce0572017-12-27 22:24:09 -05002799 kind: TokenNode::Literal(Literal::integer(i64::from(self.index))),
David Tolnay85b69a42017-12-27 20:43:10 -05002800 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002801 }
2802 }
2803
2804 impl ToTokens for ExprIndex {
2805 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002806 attrs_to_tokens(&self.attrs, tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002807 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002808 self.bracket_token.surround(tokens, |tokens| {
2809 self.index.to_tokens(tokens);
2810 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002811 }
2812 }
2813
Michael Layzell734adb42017-06-07 16:58:31 -04002814 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002815 impl ToTokens for ExprRange {
2816 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002817 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002818 self.from.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08002819 match self.limits {
2820 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
2821 RangeLimits::Closed(ref t) => t.to_tokens(tokens),
2822 }
Alex Crichton62a0a592017-05-22 13:58:53 -07002823 self.to.to_tokens(tokens);
2824 }
2825 }
2826
2827 impl ToTokens for ExprPath {
2828 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002829 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002830 ::PathTokens(&self.qself, &self.path).to_tokens(tokens)
Alex Crichton62a0a592017-05-22 13:58:53 -07002831 }
2832 }
2833
Michael Layzell734adb42017-06-07 16:58:31 -04002834 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002835 impl ToTokens for ExprAddrOf {
2836 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002837 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002838 self.and_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002839 self.mutbl.to_tokens(tokens);
2840 self.expr.to_tokens(tokens);
2841 }
2842 }
2843
Michael Layzell734adb42017-06-07 16:58:31 -04002844 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002845 impl ToTokens for ExprBreak {
2846 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002847 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002848 self.break_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002849 self.label.to_tokens(tokens);
2850 self.expr.to_tokens(tokens);
2851 }
2852 }
2853
Michael Layzell734adb42017-06-07 16:58:31 -04002854 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002855 impl ToTokens for ExprContinue {
2856 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002857 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002858 self.continue_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002859 self.label.to_tokens(tokens);
2860 }
2861 }
2862
Michael Layzell734adb42017-06-07 16:58:31 -04002863 #[cfg(feature = "full")]
David Tolnayc246cd32017-12-28 23:14:32 -05002864 impl ToTokens for ExprReturn {
Alex Crichton62a0a592017-05-22 13:58:53 -07002865 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002866 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002867 self.return_token.to_tokens(tokens);
Alex Crichton62a0a592017-05-22 13:58:53 -07002868 self.expr.to_tokens(tokens);
2869 }
2870 }
2871
Michael Layzell734adb42017-06-07 16:58:31 -04002872 #[cfg(feature = "full")]
David Tolnay8c91b882017-12-28 23:04:32 -05002873 impl ToTokens for ExprMacro {
2874 fn to_tokens(&self, tokens: &mut Tokens) {
2875 tokens.append_all(self.attrs.outer());
2876 self.mac.to_tokens(tokens);
2877 }
2878 }
2879
2880 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002881 impl ToTokens for ExprStruct {
2882 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002883 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002884 self.path.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002885 self.brace_token.surround(tokens, |tokens| {
2886 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002887 if self.rest.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002888 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002889 self.rest.to_tokens(tokens);
2890 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002891 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002892 }
2893 }
2894
Michael Layzell734adb42017-06-07 16:58:31 -04002895 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002896 impl ToTokens for ExprRepeat {
2897 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002898 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002899 self.bracket_token.surround(tokens, |tokens| {
2900 self.expr.to_tokens(tokens);
2901 self.semi_token.to_tokens(tokens);
2902 self.amt.to_tokens(tokens);
2903 })
Alex Crichton62a0a592017-05-22 13:58:53 -07002904 }
2905 }
2906
David Tolnaye98775f2017-12-28 23:17:00 -05002907 #[cfg(feature = "full")]
Michael Layzell93c36282017-06-04 20:43:14 -04002908 impl ToTokens for ExprGroup {
2909 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002910 attrs_to_tokens(&self.attrs, tokens);
Michael Layzell93c36282017-06-04 20:43:14 -04002911 self.group_token.surround(tokens, |tokens| {
2912 self.expr.to_tokens(tokens);
2913 });
2914 }
2915 }
2916
David Tolnaye98775f2017-12-28 23:17:00 -05002917 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002918 impl ToTokens for ExprParen {
2919 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002920 attrs_to_tokens(&self.attrs, tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002921 self.paren_token.surround(tokens, |tokens| {
2922 self.expr.to_tokens(tokens);
2923 });
Alex Crichton62a0a592017-05-22 13:58:53 -07002924 }
2925 }
2926
Michael Layzell734adb42017-06-07 16:58:31 -04002927 #[cfg(feature = "full")]
Alex Crichton62a0a592017-05-22 13:58:53 -07002928 impl ToTokens for ExprTry {
2929 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay8c91b882017-12-28 23:04:32 -05002930 tokens.append_all(self.attrs.outer());
Alex Crichton62a0a592017-05-22 13:58:53 -07002931 self.expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002932 self.question_token.to_tokens(tokens);
David Tolnayf4bbbd92016-09-23 14:41:55 -07002933 }
2934 }
David Tolnayb4ad3b52016-10-01 21:58:13 -07002935
Michael Layzell734adb42017-06-07 16:58:31 -04002936 #[cfg(feature = "full")]
David Tolnay055a7042016-10-02 19:23:54 -07002937 impl ToTokens for FieldValue {
2938 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay85b69a42017-12-27 20:43:10 -05002939 self.member.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002940 // XXX: Override self.is_shorthand if expr is not an IdentExpr with
2941 // the ident self.ident?
David Tolnay276690f2016-10-30 12:06:59 -07002942 if !self.is_shorthand {
Alex Crichton259ee532017-07-14 06:51:02 -07002943 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay276690f2016-10-30 12:06:59 -07002944 self.expr.to_tokens(tokens);
2945 }
David Tolnay055a7042016-10-02 19:23:54 -07002946 }
2947 }
2948
Michael Layzell734adb42017-06-07 16:58:31 -04002949 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07002950 impl ToTokens for Arm {
2951 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002952 tokens.append_all(&self.attrs);
2953 self.pats.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002954 if self.guard.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002955 TokensOrDefault(&self.if_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002956 self.guard.to_tokens(tokens);
2957 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002958 self.rocket_token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002959 self.body.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002960 self.comma.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07002961 }
2962 }
2963
Michael Layzell734adb42017-06-07 16:58:31 -04002964 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002965 impl ToTokens for PatWild {
David Tolnayb4ad3b52016-10-01 21:58:13 -07002966 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002967 self.underscore_token.to_tokens(tokens);
2968 }
2969 }
2970
Michael Layzell734adb42017-06-07 16:58:31 -04002971 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002972 impl ToTokens for PatIdent {
2973 fn to_tokens(&self, tokens: &mut Tokens) {
2974 self.mode.to_tokens(tokens);
2975 self.ident.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002976 if self.subpat.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07002977 TokensOrDefault(&self.at_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002978 self.subpat.to_tokens(tokens);
2979 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002980 }
2981 }
2982
Michael Layzell734adb42017-06-07 16:58:31 -04002983 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002984 impl ToTokens for PatStruct {
2985 fn to_tokens(&self, tokens: &mut Tokens) {
2986 self.path.to_tokens(tokens);
2987 self.brace_token.surround(tokens, |tokens| {
2988 self.fields.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002989 // NOTE: We need a comma before the dot2 token if it is present.
2990 if !self.fields.empty_or_trailing() && self.dot2_token.is_some() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08002991 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04002992 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002993 self.dot2_token.to_tokens(tokens);
2994 });
2995 }
2996 }
2997
Michael Layzell734adb42017-06-07 16:58:31 -04002998 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002999 impl ToTokens for PatTupleStruct {
3000 fn to_tokens(&self, tokens: &mut Tokens) {
3001 self.path.to_tokens(tokens);
3002 self.pat.to_tokens(tokens);
3003 }
3004 }
3005
Michael Layzell734adb42017-06-07 16:58:31 -04003006 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003007 impl ToTokens for PatPath {
3008 fn to_tokens(&self, tokens: &mut Tokens) {
3009 ::PathTokens(&self.qself, &self.path).to_tokens(tokens);
3010 }
3011 }
3012
Michael Layzell734adb42017-06-07 16:58:31 -04003013 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003014 impl ToTokens for PatTuple {
3015 fn to_tokens(&self, tokens: &mut Tokens) {
3016 self.paren_token.surround(tokens, |tokens| {
3017 for (i, token) in self.pats.iter().enumerate() {
3018 if Some(i) == self.dots_pos {
Alex Crichton259ee532017-07-14 06:51:02 -07003019 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
3020 TokensOrDefault(&self.comma_token).to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003021 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003022 token.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003023 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003024
3025 if Some(self.pats.len()) == self.dots_pos {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003026 // Ensure there is a comma before the .. token.
3027 if !self.pats.empty_or_trailing() {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003028 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003029 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003030 self.dot2_token.to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003031 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003032 });
3033 }
3034 }
3035
Michael Layzell734adb42017-06-07 16:58:31 -04003036 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003037 impl ToTokens for PatBox {
3038 fn to_tokens(&self, tokens: &mut Tokens) {
3039 self.box_token.to_tokens(tokens);
3040 self.pat.to_tokens(tokens);
3041 }
3042 }
3043
Michael Layzell734adb42017-06-07 16:58:31 -04003044 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003045 impl ToTokens for PatRef {
3046 fn to_tokens(&self, tokens: &mut Tokens) {
3047 self.and_token.to_tokens(tokens);
3048 self.mutbl.to_tokens(tokens);
3049 self.pat.to_tokens(tokens);
3050 }
3051 }
3052
Michael Layzell734adb42017-06-07 16:58:31 -04003053 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003054 impl ToTokens for PatLit {
3055 fn to_tokens(&self, tokens: &mut Tokens) {
3056 self.expr.to_tokens(tokens);
3057 }
3058 }
3059
Michael Layzell734adb42017-06-07 16:58:31 -04003060 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003061 impl ToTokens for PatRange {
3062 fn to_tokens(&self, tokens: &mut Tokens) {
3063 self.lo.to_tokens(tokens);
David Tolnay475288a2017-12-19 22:59:44 -08003064 match self.limits {
3065 RangeLimits::HalfOpen(ref t) => t.to_tokens(tokens),
3066 RangeLimits::Closed(ref t) => Token![...](t.0).to_tokens(tokens),
3067 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003068 self.hi.to_tokens(tokens);
3069 }
3070 }
3071
Michael Layzell734adb42017-06-07 16:58:31 -04003072 #[cfg(feature = "full")]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003073 impl ToTokens for PatSlice {
3074 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003075 // XXX: This is a mess, and it will be so easy to screw it up. How
3076 // do we make this correct itself better?
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003077 self.bracket_token.surround(tokens, |tokens| {
3078 self.front.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003079
3080 // If we need a comma before the middle or standalone .. token,
3081 // then make sure it's present.
David Tolnay51382052017-12-27 13:46:21 -05003082 if !self.front.empty_or_trailing()
3083 && (self.middle.is_some() || self.dot2_token.is_some())
Michael Layzell3936ceb2017-07-08 00:28:36 -04003084 {
David Tolnayf8db7ba2017-11-11 22:52:16 -08003085 <Token![,]>::default().to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003086 }
3087
3088 // If we have an identifier, we always need a .. token.
3089 if self.middle.is_some() {
3090 self.middle.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003091 TokensOrDefault(&self.dot2_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003092 } else if self.dot2_token.is_some() {
3093 self.dot2_token.to_tokens(tokens);
3094 }
3095
3096 // Make sure we have a comma before the back half.
3097 if !self.back.is_empty() {
Alex Crichton259ee532017-07-14 06:51:02 -07003098 TokensOrDefault(&self.comma_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003099 self.back.to_tokens(tokens);
3100 } else {
3101 self.comma_token.to_tokens(tokens);
3102 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003103 })
David Tolnayb4ad3b52016-10-01 21:58:13 -07003104 }
3105 }
3106
Michael Layzell734adb42017-06-07 16:58:31 -04003107 #[cfg(feature = "full")]
David Tolnay8d9e81a2016-10-03 22:36:32 -07003108 impl ToTokens for FieldPat {
3109 fn to_tokens(&self, tokens: &mut Tokens) {
Michael Layzell3936ceb2017-07-08 00:28:36 -04003110 // XXX: Override is_shorthand if it was wrong?
David Tolnay8d9e81a2016-10-03 22:36:32 -07003111 if !self.is_shorthand {
David Tolnay85b69a42017-12-27 20:43:10 -05003112 self.member.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -07003113 TokensOrDefault(&self.colon_token).to_tokens(tokens);
David Tolnay8d9e81a2016-10-03 22:36:32 -07003114 }
3115 self.pat.to_tokens(tokens);
3116 }
3117 }
3118
Michael Layzell734adb42017-06-07 16:58:31 -04003119 #[cfg(feature = "full")]
David Tolnayb4ad3b52016-10-01 21:58:13 -07003120 impl ToTokens for BindingMode {
3121 fn to_tokens(&self, tokens: &mut Tokens) {
3122 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003123 BindingMode::ByRef(ref t, ref m) => {
3124 t.to_tokens(tokens);
3125 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003126 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003127 BindingMode::ByValue(ref m) => {
3128 m.to_tokens(tokens);
David Tolnayb4ad3b52016-10-01 21:58:13 -07003129 }
3130 }
3131 }
3132 }
David Tolnay42602292016-10-01 22:25:45 -07003133
Michael Layzell734adb42017-06-07 16:58:31 -04003134 #[cfg(feature = "full")]
David Tolnay89e05672016-10-02 14:39:42 -07003135 impl ToTokens for CaptureBy {
3136 fn to_tokens(&self, tokens: &mut Tokens) {
3137 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003138 CaptureBy::Value(ref t) => t.to_tokens(tokens),
David Tolnaydaaf7742016-10-03 11:11:43 -07003139 CaptureBy::Ref => {
3140 // nothing
3141 }
David Tolnay89e05672016-10-02 14:39:42 -07003142 }
3143 }
3144 }
3145
Michael Layzell734adb42017-06-07 16:58:31 -04003146 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003147 impl ToTokens for Block {
3148 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003149 self.brace_token.surround(tokens, |tokens| {
3150 tokens.append_all(&self.stmts);
3151 });
David Tolnay42602292016-10-01 22:25:45 -07003152 }
3153 }
3154
Michael Layzell734adb42017-06-07 16:58:31 -04003155 #[cfg(feature = "full")]
David Tolnay42602292016-10-01 22:25:45 -07003156 impl ToTokens for Stmt {
3157 fn to_tokens(&self, tokens: &mut Tokens) {
3158 match *self {
David Tolnay191e0582016-10-02 18:31:09 -07003159 Stmt::Local(ref local) => local.to_tokens(tokens),
David Tolnay42602292016-10-01 22:25:45 -07003160 Stmt::Item(ref item) => item.to_tokens(tokens),
3161 Stmt::Expr(ref expr) => expr.to_tokens(tokens),
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003162 Stmt::Semi(ref expr, ref semi) => {
David Tolnay42602292016-10-01 22:25:45 -07003163 expr.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003164 semi.to_tokens(tokens);
David Tolnay42602292016-10-01 22:25:45 -07003165 }
David Tolnay42602292016-10-01 22:25:45 -07003166 }
3167 }
3168 }
David Tolnay191e0582016-10-02 18:31:09 -07003169
Michael Layzell734adb42017-06-07 16:58:31 -04003170 #[cfg(feature = "full")]
David Tolnay191e0582016-10-02 18:31:09 -07003171 impl ToTokens for Local {
3172 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4e3158d2016-10-30 00:30:01 -07003173 tokens.append_all(self.attrs.outer());
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003174 self.let_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003175 self.pat.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003176 if self.ty.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003177 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003178 self.ty.to_tokens(tokens);
3179 }
3180 if self.init.is_some() {
Alex Crichton259ee532017-07-14 06:51:02 -07003181 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -04003182 self.init.to_tokens(tokens);
3183 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -07003184 self.semi_token.to_tokens(tokens);
David Tolnay191e0582016-10-02 18:31:09 -07003185 }
3186 }
David Tolnayf4bbbd92016-09-23 14:41:55 -07003187}